go-bundler 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/README.md +57 -0
- data/Rakefile +8 -0
- data/example/Gofile +5 -0
- data/example/app.rb +19 -0
- data/example/manual_fetch.rb +15 -0
- data/go.mod +3 -0
- data/lib/go/bundler/version.rb +7 -0
- data/lib/go/bundler.rb +104 -0
- data/sig/go/bundler.rbs +6 -0
- metadata +54 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 5d96473cb71dd04ce70c9fa99f229ad2eb964648357fc5aba88ab78d09c9788a
|
|
4
|
+
data.tar.gz: b892c5a023963a814a017bd74b0a5649f930be12625208efdfdcccb89d430326
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: e36cefecc73d2c3b8628bdd28a9890e8d32e11fb450c769d145629fed5ce8534ce1e3831dd2e34a5eb9d5f6afd69e48407feba41749d8fcc00dca0561a25c013
|
|
7
|
+
data.tar.gz: c095f603d7e27d087c7562ca4df4ef3818642436de295bdb5ebbd5439052d44bede906332e0a59776c6c4efe67c9b4911dd9de23b9b7d69c88aaf7454f1630d6
|
data/CHANGELOG.md
ADDED
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
"go-bundler" follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
|
|
4
|
+
|
|
5
|
+
* Participants will be tolerant of opposing views.
|
|
6
|
+
* Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
|
|
7
|
+
* When interpreting the words and actions of others, participants should always assume good intentions.
|
|
8
|
+
* Behaviour which can be reasonably considered harassment will not be tolerated.
|
|
9
|
+
|
|
10
|
+
If you have any concerns about behaviour within this project, please contact us at ["andrewnez@gmail.com"](mailto:"andrewnez@gmail.com").
|
data/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# go-bundler
|
|
2
|
+
|
|
3
|
+
**Do not use this.** It's a joke that happens to work.
|
|
4
|
+
|
|
5
|
+
Go-style imports for Ruby:
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
require "github.com/rack/rack"
|
|
9
|
+
require "github.com/rails/rails"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Uses Go's module proxy to fetch Ruby gems. See [the blog post](https://nesbitt.io/2025/12/25/go-get-for-rubygems.html) for the full explanation.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
Create a `Gofile` listing dependencies:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
github.com/rack/rack v3.1.8
|
|
20
|
+
github.com/sinatra/sinatra v4.1.1
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Then in your Ruby code:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
require "go/bundler"
|
|
27
|
+
|
|
28
|
+
Go::Bundler.install("Gofile")
|
|
29
|
+
|
|
30
|
+
require "github.com/rack/rack"
|
|
31
|
+
require "github.com/sinatra/sinatra"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or fetch manually:
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
require "go/bundler"
|
|
38
|
+
|
|
39
|
+
Go::Bundler.fetch("github.com/rack/rack", "v3.1.8")
|
|
40
|
+
|
|
41
|
+
require "github.com/rack/rack"
|
|
42
|
+
require "github.com/rack/rack/request"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Requirements
|
|
46
|
+
|
|
47
|
+
- Go installed and in PATH
|
|
48
|
+
- Ruby gems must have a `go.mod` file at repo root
|
|
49
|
+
- Versions come from git tags
|
|
50
|
+
|
|
51
|
+
## How it works
|
|
52
|
+
|
|
53
|
+
Go's module proxy caches any repo with a `go.mod` file and logs its hash in a transparency log. It doesn't check that the repo contains Go code. This gem hooks Ruby's `require` to resolve `github.com/org/repo` paths to modules fetched via `go get`.
|
|
54
|
+
|
|
55
|
+
Modules land in `~/.go-bundler/pkg/mod/github.com/org/repo@version/`. The require hook finds the right `lib/` directory and loads from there.
|
|
56
|
+
|
|
57
|
+
Seriously, don't use this.
|
data/Rakefile
ADDED
data/example/Gofile
ADDED
data/example/app.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "go/bundler"
|
|
5
|
+
|
|
6
|
+
# Install dependencies from Gofile
|
|
7
|
+
Go::Bundler.install("Gofile")
|
|
8
|
+
|
|
9
|
+
# Now require using Go-style paths
|
|
10
|
+
require "github.com/rack/rack"
|
|
11
|
+
require "github.com/sinatra/sinatra"
|
|
12
|
+
|
|
13
|
+
class App < Sinatra::Base
|
|
14
|
+
get "/" do
|
|
15
|
+
"Hello from go-bundler!"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
run App
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "go/bundler"
|
|
5
|
+
|
|
6
|
+
# Fetch a single module
|
|
7
|
+
Go::Bundler.fetch("github.com/rack/rack", "v3.1.8")
|
|
8
|
+
|
|
9
|
+
# Require using Go-style path
|
|
10
|
+
require "github.com/rack/rack"
|
|
11
|
+
|
|
12
|
+
puts "Rack version: #{Rack::VERSION}"
|
|
13
|
+
|
|
14
|
+
# You can also require submodules
|
|
15
|
+
require "github.com/rack/rack/request"
|
data/go.mod
ADDED
data/lib/go/bundler.rb
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "bundler/version"
|
|
4
|
+
|
|
5
|
+
module Go
|
|
6
|
+
module Bundler
|
|
7
|
+
class Error < StandardError; end
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
def gopath
|
|
11
|
+
@gopath ||= File.join(Dir.home, ".go-bundler")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def gopath=(path)
|
|
15
|
+
@gopath = path
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def mod_path
|
|
19
|
+
File.join(gopath, "pkg", "mod")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def fetch(module_path, version = nil)
|
|
23
|
+
spec = version ? "#{module_path}@#{version}" : module_path
|
|
24
|
+
env = { "GOPATH" => gopath }
|
|
25
|
+
system(env, "go", "get", spec, exception: true)
|
|
26
|
+
module_root(module_path, version)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def module_root(module_path, version = nil)
|
|
30
|
+
escaped = escape_path(module_path)
|
|
31
|
+
pattern = File.join(mod_path, escaped + (version ? "@#{version}" : "@*"))
|
|
32
|
+
dirs = Dir.glob(pattern).sort
|
|
33
|
+
dirs.last
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def install(gofile_path = "Gofile")
|
|
37
|
+
deps = parse_gofile(gofile_path)
|
|
38
|
+
deps.each { |mod, ver| fetch(mod, ver) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def parse_gofile(path)
|
|
42
|
+
return {} unless File.exist?(path)
|
|
43
|
+
deps = {}
|
|
44
|
+
File.readlines(path).each do |line|
|
|
45
|
+
line = line.strip
|
|
46
|
+
next if line.empty? || line.start_with?("#")
|
|
47
|
+
parts = line.split(/\s+/)
|
|
48
|
+
deps[parts[0]] = parts[1]
|
|
49
|
+
end
|
|
50
|
+
deps
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def escape_path(path)
|
|
54
|
+
path.gsub(/[A-Z]/) { |c| "!#{c.downcase}" }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def resolve_require(path)
|
|
58
|
+
return nil unless path.include?("/")
|
|
59
|
+
parts = path.split("/")
|
|
60
|
+
return nil unless parts.length >= 3
|
|
61
|
+
|
|
62
|
+
# Try github.com/org/repo first
|
|
63
|
+
mod_path_candidate = parts[0, 3].join("/")
|
|
64
|
+
root = module_root(mod_path_candidate)
|
|
65
|
+
return nil unless root
|
|
66
|
+
|
|
67
|
+
gem_name = parts[2]
|
|
68
|
+
remainder = parts[3..]
|
|
69
|
+
|
|
70
|
+
if remainder.empty?
|
|
71
|
+
# require "github.com/rack/rack" -> look for lib/rack.rb
|
|
72
|
+
lib_dir = File.join(root, "lib")
|
|
73
|
+
main_file = File.join(lib_dir, "#{gem_name}.rb")
|
|
74
|
+
return main_file if File.exist?(main_file)
|
|
75
|
+
return lib_dir if File.directory?(lib_dir)
|
|
76
|
+
else
|
|
77
|
+
# require "github.com/rack/rack/request" -> lib/rack/request.rb
|
|
78
|
+
lib_path = File.join(root, "lib", gem_name, *remainder) + ".rb"
|
|
79
|
+
return lib_path if File.exist?(lib_path)
|
|
80
|
+
end
|
|
81
|
+
nil
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
module Kernel
|
|
88
|
+
alias_method :original_require, :require
|
|
89
|
+
|
|
90
|
+
def require(path)
|
|
91
|
+
if path.start_with?("github.com/", "gitlab.com/", "bitbucket.org/")
|
|
92
|
+
resolved = Go::Bundler.resolve_require(path)
|
|
93
|
+
if resolved
|
|
94
|
+
if File.directory?(resolved)
|
|
95
|
+
$LOAD_PATH.unshift(resolved) unless $LOAD_PATH.include?(resolved)
|
|
96
|
+
return original_require(File.basename(path))
|
|
97
|
+
else
|
|
98
|
+
return original_require(resolved)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
original_require(path)
|
|
103
|
+
end
|
|
104
|
+
end
|
data/sig/go/bundler.rbs
ADDED
metadata
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: go-bundler
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Andrew Nesbitt
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: Use Go's module system to fetch Ruby gems with require "github.com/org/repo"
|
|
13
|
+
syntax
|
|
14
|
+
email:
|
|
15
|
+
- andrewnez@gmail.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- CHANGELOG.md
|
|
21
|
+
- CODE_OF_CONDUCT.md
|
|
22
|
+
- README.md
|
|
23
|
+
- Rakefile
|
|
24
|
+
- example/Gofile
|
|
25
|
+
- example/app.rb
|
|
26
|
+
- example/manual_fetch.rb
|
|
27
|
+
- go.mod
|
|
28
|
+
- lib/go/bundler.rb
|
|
29
|
+
- lib/go/bundler/version.rb
|
|
30
|
+
- sig/go/bundler.rbs
|
|
31
|
+
homepage: https://github.com/andrew/go-bundler
|
|
32
|
+
licenses: []
|
|
33
|
+
metadata:
|
|
34
|
+
homepage_uri: https://github.com/andrew/go-bundler
|
|
35
|
+
source_code_uri: https://github.com/andrew/go-bundler
|
|
36
|
+
changelog_uri: https://github.com/andrew/go-bundler/blob/main/CHANGELOG.md
|
|
37
|
+
rdoc_options: []
|
|
38
|
+
require_paths:
|
|
39
|
+
- lib
|
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
41
|
+
requirements:
|
|
42
|
+
- - ">="
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
version: 3.2.0
|
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '0'
|
|
50
|
+
requirements: []
|
|
51
|
+
rubygems_version: 4.0.1
|
|
52
|
+
specification_version: 4
|
|
53
|
+
summary: Go-style imports for Ruby using Go's module proxy
|
|
54
|
+
test_files: []
|