Skip to content

Commit c82d47e

Browse files
authored
Merge pull request #214 from ruby-go-gem/feature/rake_task
Add rake task helper for go
2 parents e2abf04 + 3739d1e commit c82d47e

File tree

8 files changed

+351
-49
lines changed

8 files changed

+351
-49
lines changed

Rakefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require_relative "_gem/lib/go_gem/rake_task"
4+
35
# @return [String]
46
def repo_root
57
__dir__

_gem/README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,68 @@ require "go_gem/mkmf" # Append this
3333
create_go_makefile("example/example")
3434
```
3535

36+
### `GoGem::RakeTask`
37+
Provides rake tasks for `go test` with CRuby
38+
39+
#### Example (Without config)
40+
```ruby
41+
# Rakefile
42+
require "go_gem/rake_task"
43+
44+
GoGem::RakeTask.new("gem_name")
45+
```
46+
47+
Following tasks are generated
48+
49+
* `rake go:test`
50+
* `rake go:testrace`
51+
* `rake go:fmt`
52+
53+
#### Example (With config)
54+
```ruby
55+
# Rakefile
56+
require "go_gem/rake_task"
57+
58+
GoGem::RakeTask.new("gem_name") do |t|
59+
t.task_namespace = "go5"
60+
t.go_bin_path = "/path/to/go"
61+
t.go_test_args = "-mod=readonly"
62+
t.target_dir = "/dir/to/go-mod/"
63+
end
64+
```
65+
66+
Following tasks are generated
67+
68+
* `rake go5:test`
69+
* `rake go5:testrace`
70+
* `rake go5:fmt`
71+
72+
#### Example (Add additional tasks)
73+
```ruby
74+
# Rakefile
75+
require "go_gem/rake_task"
76+
77+
go_task = GoGem::RakeTask.new("gem_name")
78+
79+
namespace :go do
80+
desc "Run golangci-lint"
81+
task :lint do
82+
go_task.within_target_dir do
83+
sh "which golangci-lint" do |ok, _|
84+
raise "golangci-lint isn't installed. See. https://golangci-lint.run/welcome/install/" unless ok
85+
end
86+
sh GoGem::RakeTask.build_env_vars, "golangci-lint run"
87+
end
88+
end
89+
end
90+
```
91+
92+
#### Available configurations
93+
* `task_namespace` : task namespace (default: `:go`)
94+
* `go_bin_path` : path to go binary (default: `"go"`)
95+
* `go_test_args` : argument passed to `go test` (default: `"-mod=readonly -count=1"`)
96+
* `target_dir` : directory when executing go commands. (default: `"ext/#{gem_name}"`)
97+
3698
## Development
3799

38100
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.

_gem/lib/go_gem/rake_task.rb

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# frozen_string_literal: true
2+
3+
require "rake"
4+
require "rake/tasklib"
5+
6+
module GoGem
7+
# Provides rake tasks for `go test` with CRuby
8+
#
9+
# @example Without config
10+
# # Rakefile
11+
# require "go_gem/rake_task"
12+
#
13+
# GoGem::RakeTask.new("gem_name")
14+
#
15+
# @example With config
16+
# # Rakefile
17+
# require "go_gem/rake_task"
18+
#
19+
# GoGem::RakeTask.new("gem_name") do |t|
20+
# t.task_namespace = "go5"
21+
# t.go_bin_path = "/path/to/go"
22+
# t.go_test_args = "-mod=readonly"
23+
# t.target_dir = "/dir/to/go-mod/"
24+
# end
25+
#
26+
# @example additional tasks
27+
# # Rakefile
28+
# require "go_gem/rake_task"
29+
#
30+
# t = GoGem::RakeTask.new("gem_name")
31+
#
32+
# namespace :go do
33+
# desc "Run golangci-lint"
34+
# task :lint do
35+
# t.within_target_dir do
36+
# sh "which golangci-lint" do |ok, _|
37+
# raise "golangci-lint isn't installed. See. https://golangci-lint.run/welcome/install/" unless ok
38+
# end
39+
# sh GoGem::RakeTask.build_env_vars, "golangci-lint run"
40+
# end
41+
# end
42+
# end
43+
class RakeTask < ::Rake::TaskLib
44+
DEFAULT_TASK_NAMESPACE = :go
45+
46+
DEFAULT_GO_BIN_PATH = "go"
47+
48+
DEFAULT_GO_TEST_ARGS = "-mod=readonly -count=1"
49+
50+
# @!attribute [r] gem_name
51+
# @return [String]
52+
attr_reader :gem_name
53+
54+
# @!attribute task_namespace
55+
# @return [Symbol,String] task namespace (default: `:go`)
56+
attr_accessor :task_namespace
57+
58+
# @!attribute go_bin_path
59+
# @return [String] path to go binary (default: `"go"`)
60+
attr_accessor :go_bin_path
61+
62+
# @!attribute go_test_args
63+
# @return [String] argument passed to `go test` (default: `"-mod=readonly -count=1"`)
64+
attr_accessor :go_test_args
65+
66+
# @!attribute cwd
67+
# @return [String] directory when executing go commands. (default: `"ext/#{gem_name}"`)
68+
attr_accessor :target_dir
69+
70+
# @param gem_name [String]
71+
# @yield configuration of {RakeTask}
72+
# @yieldparam t [RakeTask]
73+
def initialize(gem_name)
74+
super()
75+
76+
@gem_name = gem_name
77+
78+
@task_namespace = DEFAULT_TASK_NAMESPACE
79+
@go_bin_path = DEFAULT_GO_BIN_PATH
80+
@go_test_args = DEFAULT_GO_TEST_ARGS
81+
@target_dir = ext_dir
82+
83+
yield(self) if block_given?
84+
85+
namespace(task_namespace) do
86+
define_go_test_task
87+
define_go_testrace_task
88+
define_go_fmt_task
89+
end
90+
end
91+
92+
# Generate environment variables to build go programs in the Go gem
93+
#
94+
# @return [Hash<String, String>]
95+
def self.build_env_vars
96+
ldflags = "-L#{RbConfig::CONFIG["libdir"]} -l#{RbConfig::CONFIG["RUBY_SO_NAME"]}"
97+
98+
case `#{RbConfig::CONFIG["CC"]} --version` # rubocop:disable Lint/LiteralAsCondition
99+
when /Free Software Foundation/
100+
ldflags << " -Wl,--unresolved-symbols=ignore-all"
101+
when /clang/
102+
ldflags << " -undefined dynamic_lookup"
103+
end
104+
105+
cflags = [
106+
RbConfig::CONFIG["CFLAGS"],
107+
"-I#{RbConfig::CONFIG["rubyarchhdrdir"]}",
108+
"-I#{RbConfig::CONFIG["rubyhdrdir"]}",
109+
].join(" ")
110+
111+
# FIXME: Workaround for Ubuntu (GitHub Actions)
112+
if RUBY_PLATFORM =~ /linux/i
113+
cflags.gsub!("-Wno-self-assign", "")
114+
cflags.gsub!("-Wno-parentheses-equality", "")
115+
cflags.gsub!("-Wno-constant-logical-operand", "")
116+
cflags.gsub!("-Wsuggest-attribute=format", "")
117+
cflags.gsub!("-Wold-style-definition", "")
118+
cflags.gsub!("-Wsuggest-attribute=noreturn", "")
119+
ldflags.gsub!("-Wl,--unresolved-symbols=ignore-all", "")
120+
end
121+
122+
ld_library_path = RbConfig::CONFIG["libdir"]
123+
124+
{
125+
"CGO_CFLAGS" => cflags,
126+
"CGO_LDFLAGS" => ldflags,
127+
"LD_LIBRARY_PATH" => ld_library_path,
128+
}
129+
end
130+
131+
# @yield
132+
def within_target_dir
133+
Dir.chdir(target_dir) do # rubocop:disable Style/ExplicitBlockArgument
134+
yield
135+
end
136+
end
137+
138+
# @return [String]
139+
def ext_dir
140+
File.join("ext", gem_name)
141+
end
142+
143+
private
144+
145+
def define_go_test_task
146+
desc "Run #{go_bin_path} test"
147+
task(:test) do
148+
within_target_dir do
149+
sh RakeTask.build_env_vars, "#{go_bin_path} test #{go_test_args} ./..."
150+
end
151+
end
152+
end
153+
154+
def define_go_testrace_task
155+
desc "Run #{go_bin_path} test -race"
156+
task(:testrace) do
157+
within_target_dir do
158+
sh RakeTask.build_env_vars, "#{go_bin_path} test #{go_test_args} -race ./..."
159+
end
160+
end
161+
end
162+
163+
def define_go_fmt_task
164+
desc "Run #{go_bin_path} fmt"
165+
task(:fmt) do
166+
within_target_dir do
167+
sh "#{go_bin_path} fmt ./..."
168+
end
169+
end
170+
end
171+
end
172+
end

_gem/sig/go_gem/rake_task.rbs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
module GoGem
2+
class RakeTask < ::Rake::TaskLib
3+
@gem_name: String
4+
5+
@task_namespace: Symbol | String
6+
7+
@go_bin_path: String
8+
9+
@go_test_args: String
10+
11+
@target_dir: String
12+
13+
DEFAULT_TASK_NAMESPACE: Symbol
14+
15+
DEFAULT_GO_BIN_PATH: String
16+
17+
DEFAULT_GO_TEST_ARGS: String
18+
19+
attr_reader gem_name: String
20+
21+
attr_accessor task_namespace: Symbol | String
22+
23+
attr_accessor go_bin_path: String
24+
25+
attr_accessor go_test_args: String
26+
27+
attr_accessor target_dir: String
28+
29+
def initialize: (String gem_name) ?{ (RakeTask) -> void } -> void
30+
31+
def self.build_env_vars: () -> { "CGO_CFLAGS" => String, "CGO_LDFLAGS" => String, "LD_LIBRARY_PATH" => String }
32+
33+
private
34+
35+
def define_go_test_task: () -> void
36+
37+
def define_go_testrace_task: () -> void
38+
39+
def define_go_fmt_task: () -> void
40+
41+
def within_target_dir: () { () -> void } -> void
42+
43+
def ext_dir: () -> String
44+
end
45+
end

_gem/sig/non-gemify/rake.rbs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module FileUtils
2+
def sh: (Hash[String, String] env, *String cmd, **untyped options) ?{ (bool, Process::Status) -> void } -> void
3+
| ...
4+
end

_gem/spec/go_gem/rake_task_spec.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe GoGem::RakeTask do
4+
before { Rake::Task.clear }
5+
6+
after { Rake::Task.clear }
7+
8+
describe "defining tasks" do
9+
context "with default params" do
10+
let(:gem_name) { "my_gem" }
11+
12+
subject do
13+
GoGem::RakeTask.new(gem_name)
14+
Rake::Task
15+
end
16+
17+
it { should be_task_defined("go:test") }
18+
it { should be_task_defined("go:testrace") }
19+
it { should be_task_defined("go:fmt") }
20+
21+
describe "Add additional tasks" do
22+
include Rake::DSL
23+
24+
subject do
25+
t = GoGem::RakeTask.new(gem_name)
26+
27+
namespace :go do
28+
task :test2 do
29+
t.within_target_dir do
30+
sh "go test"
31+
end
32+
end
33+
end
34+
35+
Rake::Task
36+
end
37+
38+
it { should be_task_defined("go:test2") }
39+
end
40+
end
41+
42+
context "with params" do
43+
let(:gem_name) { "my_gem" }
44+
45+
subject do
46+
GoGem::RakeTask.new(gem_name) do |config|
47+
config.task_namespace = :go5
48+
end
49+
Rake::Task
50+
end
51+
52+
it { should be_task_defined("go5:test") }
53+
it { should be_task_defined("go5:testrace") }
54+
it { should be_task_defined("go5:fmt") }
55+
end
56+
end
57+
end

_gem/spec/spec_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
require "go_gem"
44
require "go_gem/mkmf"
5+
require "go_gem/rake_task"
56

67
require "tmpdir"
78
require "serverspec"

0 commit comments

Comments
 (0)