Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require_relative "_gem/lib/go_gem/rake_task"

# @return [String]
def repo_root
__dir__
Expand Down
62 changes: 62 additions & 0 deletions _gem/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,68 @@ require "go_gem/mkmf" # Append this
create_go_makefile("example/example")
```

### `GoGem::RakeTask`
Provides rake tasks for `go test` with CRuby

#### Example (Without config)
```ruby
# Rakefile
require "go_gem/rake_task"

GoGem::RakeTask.new("gem_name")
```

Following tasks are generated

* `rake go:test`
* `rake go:testrace`
* `rake go:fmt`

#### Example (With config)
```ruby
# Rakefile
require "go_gem/rake_task"

GoGem::RakeTask.new("gem_name") do |t|
t.task_namespace = "go5"
t.go_bin_path = "/path/to/go"
t.go_test_args = "-mod=readonly"
t.target_dir = "/dir/to/go-mod/"
end
```

Following tasks are generated

* `rake go5:test`
* `rake go5:testrace`
* `rake go5:fmt`

#### Example (Add additional tasks)
```ruby
# Rakefile
require "go_gem/rake_task"

go_task = GoGem::RakeTask.new("gem_name")

namespace :go do
desc "Run golangci-lint"
task :lint do
go_task.within_target_dir do
sh "which golangci-lint" do |ok, _|
raise "golangci-lint isn't installed. See. https://golangci-lint.run/welcome/install/" unless ok
end
sh GoGem::RakeTask.build_env_vars, "golangci-lint run"
end
end
end
```

#### Available configurations
* `task_namespace` : task namespace (default: `:go`)
* `go_bin_path` : path to go binary (default: `"go"`)
* `go_test_args` : argument passed to `go test` (default: `"-mod=readonly -count=1"`)
* `target_dir` : directory when executing go commands. (default: `"ext/#{gem_name}"`)

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
Expand Down
172 changes: 172 additions & 0 deletions _gem/lib/go_gem/rake_task.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# frozen_string_literal: true

require "rake"
require "rake/tasklib"

module GoGem
# Provides rake tasks for `go test` with CRuby
#
# @example Without config
# # Rakefile
# require "go_gem/rake_task"
#
# GoGem::RakeTask.new("gem_name")
#
# @example With config
# # Rakefile
# require "go_gem/rake_task"
#
# GoGem::RakeTask.new("gem_name") do |t|
# t.task_namespace = "go5"
# t.go_bin_path = "/path/to/go"
# t.go_test_args = "-mod=readonly"
# t.target_dir = "/dir/to/go-mod/"
# end
#
# @example additional tasks
# # Rakefile
# require "go_gem/rake_task"
#
# t = GoGem::RakeTask.new("gem_name")
#
# namespace :go do
# desc "Run golangci-lint"
# task :lint do
# t.within_target_dir do
# sh "which golangci-lint" do |ok, _|
# raise "golangci-lint isn't installed. See. https://golangci-lint.run/welcome/install/" unless ok
# end
# sh GoGem::RakeTask.build_env_vars, "golangci-lint run"
# end
# end
# end
class RakeTask < ::Rake::TaskLib
DEFAULT_TASK_NAMESPACE = :go

DEFAULT_GO_BIN_PATH = "go"

DEFAULT_GO_TEST_ARGS = "-mod=readonly -count=1"

# @!attribute [r] gem_name
# @return [String]
attr_reader :gem_name

# @!attribute task_namespace
# @return [Symbol,String] task namespace (default: `:go`)
attr_accessor :task_namespace

# @!attribute go_bin_path
# @return [String] path to go binary (default: `"go"`)
attr_accessor :go_bin_path

# @!attribute go_test_args
# @return [String] argument passed to `go test` (default: `"-mod=readonly -count=1"`)
attr_accessor :go_test_args

# @!attribute cwd
# @return [String] directory when executing go commands. (default: `"ext/#{gem_name}"`)
attr_accessor :target_dir

# @param gem_name [String]
# @yield configuration of {RakeTask}
# @yieldparam t [RakeTask]
def initialize(gem_name)
super()

@gem_name = gem_name

@task_namespace = DEFAULT_TASK_NAMESPACE
@go_bin_path = DEFAULT_GO_BIN_PATH
@go_test_args = DEFAULT_GO_TEST_ARGS
@target_dir = ext_dir

yield(self) if block_given?

namespace(task_namespace) do
define_go_test_task
define_go_testrace_task
define_go_fmt_task
end
end

# Generate environment variables to build go programs in the Go gem
#
# @return [Hash<String, String>]
def self.build_env_vars
ldflags = "-L#{RbConfig::CONFIG["libdir"]} -l#{RbConfig::CONFIG["RUBY_SO_NAME"]}"

case `#{RbConfig::CONFIG["CC"]} --version` # rubocop:disable Lint/LiteralAsCondition
when /Free Software Foundation/
ldflags << " -Wl,--unresolved-symbols=ignore-all"
when /clang/
ldflags << " -undefined dynamic_lookup"
end

cflags = [
RbConfig::CONFIG["CFLAGS"],
"-I#{RbConfig::CONFIG["rubyarchhdrdir"]}",
"-I#{RbConfig::CONFIG["rubyhdrdir"]}",
].join(" ")

# FIXME: Workaround for Ubuntu (GitHub Actions)
if RUBY_PLATFORM =~ /linux/i
cflags.gsub!("-Wno-self-assign", "")
cflags.gsub!("-Wno-parentheses-equality", "")
cflags.gsub!("-Wno-constant-logical-operand", "")
cflags.gsub!("-Wsuggest-attribute=format", "")
cflags.gsub!("-Wold-style-definition", "")
cflags.gsub!("-Wsuggest-attribute=noreturn", "")
ldflags.gsub!("-Wl,--unresolved-symbols=ignore-all", "")
end

ld_library_path = RbConfig::CONFIG["libdir"]

{
"CGO_CFLAGS" => cflags,
"CGO_LDFLAGS" => ldflags,
"LD_LIBRARY_PATH" => ld_library_path,
}
end

# @yield
def within_target_dir
Dir.chdir(target_dir) do # rubocop:disable Style/ExplicitBlockArgument
yield
end
end

# @return [String]
def ext_dir
File.join("ext", gem_name)
end

private

def define_go_test_task
desc "Run #{go_bin_path} test"
task(:test) do
within_target_dir do
sh RakeTask.build_env_vars, "#{go_bin_path} test #{go_test_args} ./..."
end
end
end

def define_go_testrace_task
desc "Run #{go_bin_path} test -race"
task(:testrace) do
within_target_dir do
sh RakeTask.build_env_vars, "#{go_bin_path} test #{go_test_args} -race ./..."
end
end
end

def define_go_fmt_task
desc "Run #{go_bin_path} fmt"
task(:fmt) do
within_target_dir do
sh "#{go_bin_path} fmt ./..."
end
end
end
end
end
45 changes: 45 additions & 0 deletions _gem/sig/go_gem/rake_task.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
module GoGem
class RakeTask < ::Rake::TaskLib
@gem_name: String

@task_namespace: Symbol | String

@go_bin_path: String

@go_test_args: String

@target_dir: String

DEFAULT_TASK_NAMESPACE: Symbol

DEFAULT_GO_BIN_PATH: String

DEFAULT_GO_TEST_ARGS: String

attr_reader gem_name: String

attr_accessor task_namespace: Symbol | String

attr_accessor go_bin_path: String

attr_accessor go_test_args: String

attr_accessor target_dir: String

def initialize: (String gem_name) ?{ (RakeTask) -> void } -> void

def self.build_env_vars: () -> { "CGO_CFLAGS" => String, "CGO_LDFLAGS" => String, "LD_LIBRARY_PATH" => String }

private

def define_go_test_task: () -> void

def define_go_testrace_task: () -> void

def define_go_fmt_task: () -> void

def within_target_dir: () { () -> void } -> void

def ext_dir: () -> String
end
end
4 changes: 4 additions & 0 deletions _gem/sig/non-gemify/rake.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module FileUtils
def sh: (Hash[String, String] env, *String cmd, **untyped options) ?{ (bool, Process::Status) -> void } -> void
| ...
end
57 changes: 57 additions & 0 deletions _gem/spec/go_gem/rake_task_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

RSpec.describe GoGem::RakeTask do
before { Rake::Task.clear }

after { Rake::Task.clear }

describe "defining tasks" do
context "with default params" do
let(:gem_name) { "my_gem" }

subject do
GoGem::RakeTask.new(gem_name)
Rake::Task
end

it { should be_task_defined("go:test") }
it { should be_task_defined("go:testrace") }
it { should be_task_defined("go:fmt") }

describe "Add additional tasks" do
include Rake::DSL

subject do
t = GoGem::RakeTask.new(gem_name)

namespace :go do
task :test2 do
t.within_target_dir do
sh "go test"
end
end
end

Rake::Task
end

it { should be_task_defined("go:test2") }
end
end

context "with params" do
let(:gem_name) { "my_gem" }

subject do
GoGem::RakeTask.new(gem_name) do |config|
config.task_namespace = :go5
end
Rake::Task
end

it { should be_task_defined("go5:test") }
it { should be_task_defined("go5:testrace") }
it { should be_task_defined("go5:fmt") }
end
end
end
1 change: 1 addition & 0 deletions _gem/spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require "go_gem"
require "go_gem/mkmf"
require "go_gem/rake_task"

require "tmpdir"
require "serverspec"
Expand Down
Loading
Loading