Skip to content
Open
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
4 changes: 4 additions & 0 deletions .github/workflows/bundler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ jobs:
distribution: temurin
java-version: 19.0.2
if: matrix.os.name == 'Windows' && matrix.ruby.name == 'jruby'
- name: Setup go
uses: actions/setup-go@v5
with:
go-version: stable
- name: Install graphviz (Ubuntu)
run: sudo apt-get install graphviz -y
if: matrix.bundler.value == '' && matrix.os.name == 'Ubuntu'
Expand Down
4 changes: 4 additions & 0 deletions Manifest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,12 @@ bundler/lib/bundler/templates/newgem/circleci/config.yml.tt
bundler/lib/bundler/templates/newgem/exe/newgem.tt
bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt
bundler/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt
bundler/lib/bundler/templates/newgem/ext/newgem/extconf-go.rb.tt
bundler/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt
bundler/lib/bundler/templates/newgem/ext/newgem/go.mod.tt
bundler/lib/bundler/templates/newgem/ext/newgem/newgem-go.c.tt
bundler/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt
bundler/lib/bundler/templates/newgem/ext/newgem/newgem.go.tt
bundler/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt
bundler/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt
bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt
Expand Down
2 changes: 1 addition & 1 deletion bundler/lib/bundler/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class CLI < Thor

AUTO_INSTALL_CMDS = %w[show binstubs outdated exec open console licenses clean].freeze
PARSEABLE_COMMANDS = %w[check config help exec platform show version].freeze
EXTENSIONS = ["c", "rust"].freeze
EXTENSIONS = ["c", "rust", "go"].freeze

COMMAND_ALIASES = {
"check" => "c",
Expand Down
48 changes: 47 additions & 1 deletion bundler/lib/bundler/cli/gem.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require "pathname"
require "open3"

module Bundler
class CLI
Expand All @@ -15,6 +16,8 @@ class CLI::Gem
"test-unit" => "3.0",
}.freeze

DEFAULT_GITHUB_USERNAME = "[USERNAME]"

attr_reader :options, :gem_name, :thor, :name, :target, :extension

def initialize(options, gem_name, thor)
Expand Down Expand Up @@ -71,7 +74,7 @@ def run
exe: options[:exe],
bundler_version: bundler_dependency_version,
git: use_git,
github_username: github_username.empty? ? "[USERNAME]" : github_username,
github_username: github_username.empty? ? DEFAULT_GITHUB_USERNAME : github_username,
required_ruby_version: required_ruby_version,
rust_builder_required_rubygems_version: rust_builder_required_rubygems_version,
minitest_constant_name: minitest_constant_name,
Expand Down Expand Up @@ -213,6 +216,19 @@ def run
)
end

if extension == "go"
templates.merge!(
"ext/newgem/go.mod.tt" => "ext/#{name}/go.mod",
"ext/newgem/extconf-go.rb.tt" => "ext/#{name}/extconf.rb",
"ext/newgem/newgem.h.tt" => "ext/#{name}/#{underscored_name}.h",
"ext/newgem/newgem.go.tt" => "ext/#{name}/#{underscored_name}.go",
"ext/newgem/newgem-go.c.tt" => "ext/#{name}/#{underscored_name}.c",
)

config[:go_version] = go_version
config[:go_module_username] = config[:github_username] == DEFAULT_GITHUB_USERNAME ? "username" : config[:github_username]
end

if target.exist? && !target.directory?
Bundler.ui.error "Couldn't create a new gem named `#{gem_name}` because there's an existing file named `#{gem_name}`."
exit Bundler::BundlerError.all_errors[Bundler::GenericSystemCallError]
Expand All @@ -237,6 +253,10 @@ def run
path.chmod(executable)
end

if extension == "go"
run_go_mod_tidy(target.join("ext/#{name}"))
end

if use_git
IO.popen(%w[git add .], { chdir: target }, &:read)
end
Expand Down Expand Up @@ -463,5 +483,31 @@ def validate_rust_builder_rubygems_version
exit 1
end
end

def go_version
stdout, _, status = Open3.capture3("go version")

# Suppress error if Go isn't installed
return nil unless status.success?

/go version go([.\d]+)/.match(stdout)[1]
end

# Run `go mod tidy` within ext/newgem/
def run_go_mod_tidy(ext_dir)
Dir.chdir(ext_dir) do
_, stderr, status = Open3.capture3("go mod tidy")

if status.success?
Bundler.ui.info "#{ext_dir}/go.sum has been created with `go mod tidy`"
else
Bundler.ui.warn <<~MSG
An error occurred when executing `go mod tidy`.
stderr: #{stderr}
Please run `go mod tidy` later in #{ext_dir} to create `go.sum`.
MSG
end
end
end
end
end
2 changes: 1 addition & 1 deletion bundler/lib/bundler/man/bundle-gem.1
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ The generated project skeleton can be customized with OPTIONS, as explained belo
.IP "\(bu" 4
\fB\-\-no\-changelog\fR: Do not create a \fBCHANGELOG\.md\fR (overrides \fB\-\-changelog\fR specified in the global config)\.
.IP "\(bu" 4
\fB\-\-ext=c\fR, \fB\-\-ext=rust\fR: Add boilerplate for C or Rust (currently magnus \fIhttps://docs\.rs/magnus\fR based) extension code to the generated project\. This behavior is disabled by default\.
\fB\-\-ext=c\fR, \fB\-\-ext=go\fR, \fB\-\-ext=rust\fR: Add boilerplate for C, Go (currently go\-gem\-wrapper \fIhttps://github\.com/ruby\-go\-gem/go\-gem\-wrapper\fR based) or Rust (currently magnus \fIhttps://docs\.rs/magnus\fR based) extension code to the generated project\. This behavior is disabled by default\.
.IP "\(bu" 4
\fB\-\-no\-ext\fR: Do not add extension code (overrides \fB\-\-ext\fR specified in the global config)\.
.IP "\(bu" 4
Expand Down
4 changes: 2 additions & 2 deletions bundler/lib/bundler/man/bundle-gem.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ configuration file using the following names:
Do not create a `CHANGELOG.md` (overrides `--changelog` specified in the
global config).

* `--ext=c`, `--ext=rust`:
Add boilerplate for C or Rust (currently [magnus](https://docs.rs/magnus) based) extension code to the generated project. This behavior
* `--ext=c`, `--ext=go`, `--ext=rust`:
Add boilerplate for C, Go (currently [go-gem-wrapper](https://github.com/ruby-go-gem/go-gem-wrapper) based) or Rust (currently [magnus](https://docs.rs/magnus) based) extension code to the generated project. This behavior
is disabled by default.

* `--no-ext`:
Expand Down
12 changes: 12 additions & 0 deletions bundler/lib/bundler/templates/newgem/circleci/config.yml.tt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ jobs:
<%- if config[:ext] == 'rust' -%>
environment:
RB_SYS_FORCE_INSTALL_RUST_TOOLCHAIN: 'true'
<%- end -%>
<%- if config[:ext] == 'go' -%>
environment:
GO_VERSION: '1.23.0'
<%- end -%>
steps:
- checkout
Expand All @@ -16,6 +20,14 @@ jobs:
- run:
name: Install a RubyGems version that can compile rust extensions
command: gem update --system '<%= ::Gem.rubygems_version %>'
<%- end -%>
<%- if config[:ext] == 'go' -%>
- run:
name: Install Go
command: |
wget https://go.dev/dl/go$GO_VERSION.linux-amd64.tar.gz -O /tmp/go.tar.gz
tar -C /usr/local -xzf /tmp/go.tar.gz
echo 'export PATH=/usr/local/go/bin:"$PATH"' >> "$BASH_ENV"
<%- end -%>
- run:
name: Run the default task
Expand Down
11 changes: 11 additions & 0 deletions bundler/lib/bundler/templates/newgem/ext/newgem/extconf-go.rb.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

require "mkmf"
require "go_gem/mkmf"

# Makes all symbols private by default to avoid unintended conflict
# with other gems. To explicitly export symbols you can use RUBY_FUNC_EXPORTED
# selectively, or entirely remove this flag.
append_cflags("-fvisibility=hidden")

create_go_makefile(<%= config[:makefile_path].inspect %>)
5 changes: 5 additions & 0 deletions bundler/lib/bundler/templates/newgem/ext/newgem/go.mod.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/<%= config[:go_module_username] %>/<%= config[:underscored_name] %>

go <%= config[:go_version] %>

require github.com/ruby-go-gem/go-gem-wrapper latest
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include "<%= config[:underscored_name] %>.h"
#include "_cgo_export.h"
31 changes: 31 additions & 0 deletions bundler/lib/bundler/templates/newgem/ext/newgem/newgem.go.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package main

/*
#include "<%= config[:underscored_name] %>.h"

VALUE rb_<%= config[:underscored_name] %>_sum(VALUE self, VALUE a, VALUE b);
*/
import "C"

import (
"github.com/ruby-go-gem/go-gem-wrapper/ruby"
)

//export rb_<%= config[:underscored_name] %>_sum
func rb_<%= config[:underscored_name] %>_sum(_ C.VALUE, a C.VALUE, b C.VALUE) C.VALUE {
longA := ruby.NUM2LONG(ruby.VALUE(a))
longB := ruby.NUM2LONG(ruby.VALUE(b))

sum := longA + longB

return C.VALUE(ruby.LONG2NUM(sum))
}

//export Init_<%= config[:underscored_name] %>
func Init_<%= config[:underscored_name] %>() {
rb_m<%= config[:constant_array].join %> := ruby.RbDefineModule(<%= config[:constant_name].inspect %>)
ruby.RbDefineSingletonMethod(rb_m<%= config[:constant_array].join %>, "sum", C.rb_<%= config[:underscored_name] %>_sum, 2)
}

func main() {
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ jobs:
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
<%- end -%>
<%- if config[:ext] == 'go' -%>
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: ext/<%= config[:underscored_name] %>/go.mod
<%- end -%>
- name: Run the default task
run: bundle exec rake
9 changes: 9 additions & 0 deletions bundler/lib/bundler/templates/newgem/gitlab-ci.yml.tt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ default:
<%- if config[:ext] == 'rust' -%>
- apt-get update && apt-get install -y clang
- gem update --system '<%= ::Gem.rubygems_version %>'
<%- end -%>
<%- if config[:ext] == 'go' -%>
- wget https://go.dev/dl/go$GO_VERSION.linux-amd64.tar.gz -O /tmp/go.tar.gz
- tar -C /usr/local -xzf /tmp/go.tar.gz
- export PATH=/usr/local/go/bin:$PATH
<%- end -%>
- gem install bundler -v <%= Bundler::VERSION %>
- bundle install
Expand All @@ -13,6 +18,10 @@ example_job:
<%- if config[:ext] == 'rust' -%>
variables:
RB_SYS_FORCE_INSTALL_RUST_TOOLCHAIN: 'true'
<%- end -%>
<%- if config[:ext] == 'go' -%>
variables:
GO_VERSION: '1.23.0'
<%- end -%>
script:
- bundle exec rake
5 changes: 4 additions & 1 deletion bundler/lib/bundler/templates/newgem/newgem.gemspec.tt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
<%- if config[:ext] == 'c' || config[:ext] == 'rust' -%>
<%- if %w(c rust go).include?(config[:ext]) -%>
spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
<%- end -%>

Expand All @@ -46,6 +46,9 @@ Gem::Specification.new do |spec|
<%- if config[:ext] == 'rust' -%>
spec.add_dependency "rb_sys", "~> 0.9.91"
<%- end -%>
<%- if config[:ext] == 'go' -%>
spec.add_dependency "go_gem", "~> 0.2"
<%- end -%>

# For more information and examples about making a new gem, check out our
# guide at: https://bundler.io/guides/creating_gem.html
Expand Down
Loading
Loading