gel 0.3.0 → 0.8.0.pre1
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 +4 -4
- data/README.md +26 -3
- data/RELEASING.md +12 -0
- data/exe/gel +4 -2
- data/gemlib/gel/stub.rb +20 -0
- data/lib/gel/catalog/common.rb +4 -2
- data/lib/gel/catalog/compact_index.rb +6 -10
- data/lib/gel/catalog/dependency_index.rb +10 -10
- data/lib/gel/catalog/legacy_index.rb +4 -6
- data/lib/gel/catalog/marshal_hacks.rb +2 -0
- data/lib/gel/catalog.rb +33 -52
- data/lib/gel/catalog_set.rb +100 -0
- data/lib/gel/command/help.rb +13 -2
- data/lib/gel/command/lock.rb +3 -3
- data/lib/gel/command/open.rb +24 -0
- data/lib/gel/command/shell_setup.rb +11 -8
- data/lib/gel/command/stub.rb +45 -2
- data/lib/gel/command/version.rb +7 -0
- data/lib/gel/command.rb +43 -6
- data/lib/gel/compatibility/rubygems.rb +10 -197
- data/lib/gel/compatibility.rb +2 -2
- data/lib/gel/config.rb +41 -7
- data/lib/gel/db.rb +93 -83
- data/lib/gel/direct_gem.rb +16 -4
- data/lib/gel/environment.rb +542 -249
- data/lib/gel/error.rb +156 -24
- data/lib/gel/gemfile_parser.rb +74 -12
- data/lib/gel/gemspec_parser.rb +26 -7
- data/lib/gel/git_catalog.rb +15 -3
- data/lib/gel/git_depot.rb +62 -28
- data/lib/gel/httpool.rb +5 -2
- data/lib/gel/installer.rb +61 -23
- data/lib/gel/lock_loader.rb +87 -112
- data/lib/gel/lock_parser.rb +23 -31
- data/lib/gel/locked_store.rb +30 -21
- data/lib/gel/multi_store.rb +13 -4
- data/lib/gel/null_solver.rb +67 -0
- data/lib/gel/package/abortable.rb +18 -0
- data/lib/gel/package/installer.rb +124 -49
- data/lib/gel/package.rb +21 -4
- data/lib/gel/path_catalog.rb +1 -1
- data/lib/gel/pinboard.rb +4 -2
- data/lib/gel/platform.rb +38 -0
- data/lib/gel/pub_grub/package.rb +67 -0
- data/lib/gel/pub_grub/preference_strategy.rb +10 -6
- data/lib/gel/pub_grub/solver.rb +37 -0
- data/lib/gel/pub_grub/source.rb +64 -92
- data/lib/gel/resolved_gem_set.rb +234 -0
- data/lib/gel/runtime.rb +3 -3
- data/lib/gel/set.rb +62 -0
- data/lib/gel/stdlib.rb +83 -0
- data/lib/gel/store.rb +94 -25
- data/lib/gel/store_catalog.rb +2 -2
- data/lib/gel/store_gem.rb +54 -6
- data/lib/gel/stub_set.rb +32 -2
- data/lib/gel/support/cgi_escape.rb +34 -0
- data/lib/gel/support/gem_platform.rb +0 -2
- data/lib/gel/support/sha512.rb +142 -0
- data/lib/gel/support/tar/tar_writer.rb +2 -2
- data/lib/gel/tail_file.rb +2 -1
- data/lib/gel/util.rb +108 -0
- data/lib/gel/vendor/pstore.rb +3 -0
- data/lib/gel/vendor/pub_grub.rb +3 -0
- data/lib/gel/vendor/ruby_digest.rb +3 -0
- data/lib/gel/vendor_catalog.rb +38 -0
- data/lib/gel/version.rb +1 -1
- data/lib/gel.rb +15 -0
- data/man/man1/gel-exec.1 +1 -1
- data/man/man1/gel-install.1 +1 -1
- data/man/man1/gel.1 +14 -1
- data/{lib/gel/compatibility → slib}/bundler/cli.rb +0 -0
- data/{lib/gel/compatibility → slib}/bundler/friendly_errors.rb +0 -0
- data/{lib/gel/compatibility/rubygems/dependency_installer.rb → slib/bundler/gem_helper.rb} +0 -0
- data/slib/bundler/gem_tasks.rb +0 -0
- data/{lib/gel/compatibility → slib}/bundler/setup.rb +0 -0
- data/{lib/gel/compatibility → slib}/bundler.rb +39 -3
- data/{lib/gel/compatibility → slib}/rubygems/command.rb +0 -0
- data/slib/rubygems/dependency_installer.rb +12 -0
- data/{lib/gel/compatibility → slib}/rubygems/gem_runner.rb +0 -0
- data/slib/rubygems/package.rb +6 -0
- data/slib/rubygems/package_task.rb +7 -0
- data/slib/rubygems/specification.rb +0 -0
- data/slib/rubygems/version.rb +0 -0
- data/slib/rubygems.rb +297 -0
- data/vendor/pstore/LICENSE.txt +22 -0
- data/vendor/pstore/lib/pstore.rb +488 -0
- data/vendor/pub_grub/LICENSE.txt +21 -0
- data/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
- data/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +183 -0
- data/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
- data/vendor/pub_grub/lib/pub_grub/incompatibility.rb +143 -0
- data/vendor/pub_grub/lib/pub_grub/package.rb +35 -0
- data/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
- data/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
- data/vendor/pub_grub/lib/pub_grub/solve_failure.rb +17 -0
- data/vendor/pub_grub/lib/pub_grub/static_package_source.rb +53 -0
- data/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
- data/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
- data/vendor/pub_grub/lib/pub_grub/version_constraint.rb +124 -0
- data/vendor/pub_grub/lib/pub_grub/version_range.rb +399 -0
- data/vendor/pub_grub/lib/pub_grub/version_solver.rb +247 -0
- data/vendor/pub_grub/lib/pub_grub/version_union.rb +174 -0
- data/vendor/pub_grub/lib/pub_grub.rb +31 -0
- data/vendor/ruby-digest/UNLICENSE +24 -0
- data/vendor/ruby-digest/lib/ruby_digest.rb +812 -0
- metadata +95 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 12fd6cb40e3a3ad1f972f80bda31dab9b894f61393469c6030fbd05394d0a248
|
|
4
|
+
data.tar.gz: ec8b72583200dc1c5679a6eedde63c333970acc5834a8e454dbd00aaa30d0135
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f27419701ba1c70f4ce7eef187ab61d9b681eade093f1966d5cc81a183a78ab8ff31dac4c365376b38e46331f3b66e0905930ff89044d948d26b9bc89b296df8
|
|
7
|
+
data.tar.gz: 1567767fb08472aa0fc1291ed0cfe56376acb28c7d5c3e56978952320694149910f9b8892f7a3937acef0aa5e22c89643afa1fc1e39b774ad04d0e39e834a53f
|
data/README.md
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
A modern gem manager.
|
|
6
6
|
|
|
7
|
-
Gel is a lightweight alternative to Bundler.
|
|
8
|
-
|
|
7
|
+
Gel is a lightweight alternative to Bundler.
|
|
9
8
|
|
|
10
9
|
| | Gel | Bundler & Rubygems |
|
|
11
10
|
|---------|--------------------|--------------------|
|
|
@@ -88,10 +87,34 @@ Or add it to your `.bashrc` or `.zshrc` to enable it everywhere:
|
|
|
88
87
|
|
|
89
88
|
Use `gel install`, `gel lock`, `gel update`, and `gel exec` as you would the equivalent `bundle` subcommands.
|
|
90
89
|
|
|
90
|
+
## ENVIRONMENT VARIABLES
|
|
91
|
+
|
|
92
|
+
* `GEL_GEMFILE`
|
|
93
|
+
The path to the gemfile gel should use
|
|
94
|
+
|
|
95
|
+
* `GEL_LOCKFILE`
|
|
96
|
+
The path to the lockfile that gel should use
|
|
97
|
+
|
|
98
|
+
* `GEL_CACHE`
|
|
99
|
+
The path to the gel version information cache
|
|
100
|
+
|
|
101
|
+
* `GEL_AUTH`
|
|
102
|
+
Gem server credentials as a space-separated list of URIs, e.g.:
|
|
103
|
+
"http://user:pass@ruby.example.com/ http://user2:pass2@gems.example.org/"
|
|
104
|
+
|
|
91
105
|
## Development
|
|
92
106
|
|
|
93
107
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/rake test` to run the tests.
|
|
94
108
|
|
|
109
|
+
To use your development instance as your primary Gel, add its `exe/` to your `$PATH` before running `shell-setup`, ensuring it comes before any RubyGems `bin` directory that might override it.
|
|
110
|
+
|
|
111
|
+
For example:
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
PATH="$HOME/projects/gel/exe:$PATH"
|
|
115
|
+
eval "$(gel shell-setup)"
|
|
116
|
+
```
|
|
117
|
+
|
|
95
118
|
## Contributing
|
|
96
119
|
|
|
97
120
|
Bug reports and pull requests are welcome on GitHub at https://github.com/gel-rb/gel. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
|
@@ -102,4 +125,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
102
125
|
|
|
103
126
|
## Code of Conduct
|
|
104
127
|
|
|
105
|
-
Everyone interacting in the Gel project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/gel-rb/gel/blob/
|
|
128
|
+
Everyone interacting in the Gel project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/gel-rb/gel/blob/main/CODE_OF_CONDUCT.md).
|
data/RELEASING.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Releasing Gel
|
|
2
|
+
|
|
3
|
+
1. Bump the version in `lib/gel/version.rb`
|
|
4
|
+
1. `gel lock`
|
|
5
|
+
1. `rake build`
|
|
6
|
+
1. `git commit`
|
|
7
|
+
1. `git tag vX.Y.Z`
|
|
8
|
+
1. `git push --tags origin main vX.Y.Z`
|
|
9
|
+
1. On GitHub, convert the tag to a release, and write a changelog
|
|
10
|
+
1. `gem push pkg/gel-X.Y.Z.gem`
|
|
11
|
+
1. `brew bump-formula-pr --url=https://github.com/gel-rb/gel/archive/vX.Y.Z.tar.gz`
|
|
12
|
+
1. Tweet a link to https://github.com/gel-rb/gel/releases/tag/vX.Y.Z
|
data/exe/gel
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
if defined?(::Gem) && !defined?(::Gel)
|
|
5
|
+
# Note there's a similar re-exec in gemlib/gel/stub.rb
|
|
6
|
+
|
|
5
7
|
exec ::Gem.ruby,
|
|
6
|
-
"-I", File.expand_path("../
|
|
8
|
+
"-I", File.expand_path("../slib", __dir__),
|
|
7
9
|
"--",
|
|
8
10
|
__FILE__,
|
|
9
11
|
*ARGV
|
data/gemlib/gel/stub.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file exists to be required from a Gel binstub if it has been
|
|
4
|
+
# loaded via 'ruby -S' and Rubygems was loaded. It (only) defines an
|
|
5
|
+
# alternative implementation of Gel.stub, which will re-exec Ruby to
|
|
6
|
+
# switch to Gel.
|
|
7
|
+
|
|
8
|
+
module Gel
|
|
9
|
+
def self.stub(name)
|
|
10
|
+
# Note there's a similar re-exec in exe/gel
|
|
11
|
+
|
|
12
|
+
exec ::Gem.ruby,
|
|
13
|
+
"-I", File.expand_path("../slib", __dir__),
|
|
14
|
+
"--",
|
|
15
|
+
File.expand_path("../exe/gel", __dir__),
|
|
16
|
+
"stub",
|
|
17
|
+
name,
|
|
18
|
+
*ARGV
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/gel/catalog/common.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "fileutils"
|
|
4
3
|
require "monitor"
|
|
4
|
+
require_relative "../util"
|
|
5
5
|
|
|
6
6
|
module Gel::Catalog::Common
|
|
7
7
|
def initialize(uri, uri_identifier, httpool:, work_pool:, cache:)
|
|
@@ -66,11 +66,13 @@ module Gel::Catalog::Common
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def pinboard
|
|
69
|
+
require_relative "../pinboard"
|
|
70
|
+
|
|
69
71
|
@pinboard || @monitor.synchronize do
|
|
70
72
|
@pinboard ||=
|
|
71
73
|
begin
|
|
72
74
|
pinboard_dir = File.expand_path("#{@cache}/#{self.class::CACHE_TYPE}/#{@uri_identifier}")
|
|
73
|
-
|
|
75
|
+
Gel::Util.mkdir_p(pinboard_dir)
|
|
74
76
|
Gel::Pinboard.new(pinboard_dir, httpool: @httpool, work_pool: @work_pool)
|
|
75
77
|
end
|
|
76
78
|
end
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
require_relative "../pinboard"
|
|
6
|
-
|
|
7
|
-
require_relative "common"
|
|
3
|
+
require_relative "../set"
|
|
8
4
|
|
|
9
5
|
class Gel::Catalog::CompactIndex
|
|
10
6
|
include Gel::Catalog::Common
|
|
11
7
|
CACHE_TYPE = "index"
|
|
12
8
|
|
|
13
|
-
def initialize(*)
|
|
14
|
-
super
|
|
9
|
+
def initialize(*args, **kwargs)
|
|
10
|
+
super(*args, **kwargs)
|
|
15
11
|
|
|
16
12
|
@gem_tokens = Hash.new("NONE")
|
|
17
13
|
@needs_update = true
|
|
18
14
|
@updating = false
|
|
19
|
-
@active_gems = Set.new
|
|
20
|
-
@pending_gems = Set.new
|
|
15
|
+
@active_gems = Gel::Set.new
|
|
16
|
+
@pending_gems = Gel::Set.new
|
|
21
17
|
end
|
|
22
18
|
|
|
23
19
|
def prepare(gems)
|
|
@@ -102,7 +98,7 @@ class Gel::Catalog::CompactIndex
|
|
|
102
98
|
end
|
|
103
99
|
|
|
104
100
|
pinboard.async_file(uri("info", gem_name), token: @gem_tokens[gem_name], only_updated: already_active, error: error) do |f|
|
|
105
|
-
dependency_names = Set.new
|
|
101
|
+
dependency_names = Gel::Set.new
|
|
106
102
|
info = {}
|
|
107
103
|
|
|
108
104
|
started = false
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "set"
|
|
4
|
-
require "cgi"
|
|
5
3
|
require "zlib"
|
|
6
4
|
|
|
7
|
-
require_relative "../
|
|
5
|
+
require_relative "../set"
|
|
6
|
+
require_relative "../support/cgi_escape"
|
|
8
7
|
|
|
9
|
-
require_relative "common"
|
|
10
8
|
require_relative "marshal_hacks"
|
|
11
9
|
|
|
12
10
|
class Gel::Catalog::DependencyIndex
|
|
13
11
|
include Gel::Catalog::Common
|
|
12
|
+
include Gel::Support::CGIEscape
|
|
13
|
+
|
|
14
14
|
CACHE_TYPE = "quick"
|
|
15
15
|
|
|
16
16
|
LIST_MAX = 40
|
|
17
17
|
|
|
18
|
-
def initialize(catalog, *args)
|
|
19
|
-
super(*args)
|
|
18
|
+
def initialize(catalog, *args, **kwargs)
|
|
19
|
+
super(*args, **kwargs)
|
|
20
20
|
|
|
21
21
|
@catalog = catalog
|
|
22
22
|
|
|
23
|
-
@active_gems = Set.new
|
|
24
|
-
@pending_gems = Set.new
|
|
23
|
+
@active_gems = Gel::Set.new
|
|
24
|
+
@pending_gems = Gel::Set.new
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def prepare(gems)
|
|
@@ -56,7 +56,7 @@ class Gel::Catalog::DependencyIndex
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def refresh_some_gems(gems)
|
|
59
|
-
gem_list = gems.map { |g|
|
|
59
|
+
gem_list = gems.map { |g| cgi_escape(g) }.sort.join(",")
|
|
60
60
|
@work_pool.queue(gem_list) do
|
|
61
61
|
response =
|
|
62
62
|
begin
|
|
@@ -72,7 +72,7 @@ class Gel::Catalog::DependencyIndex
|
|
|
72
72
|
new_info = {}
|
|
73
73
|
gems.each { |g| new_info[g] = {} }
|
|
74
74
|
|
|
75
|
-
new_dependencies = Set.new
|
|
75
|
+
new_dependencies = Gel::Set.new
|
|
76
76
|
|
|
77
77
|
hashes = Marshal.load(response.body)
|
|
78
78
|
hashes.each do |hash|
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "set"
|
|
4
3
|
require "zlib"
|
|
5
4
|
|
|
6
|
-
require_relative "../
|
|
5
|
+
require_relative "../set"
|
|
7
6
|
|
|
8
|
-
require_relative "common"
|
|
9
7
|
require_relative "marshal_hacks"
|
|
10
8
|
|
|
11
9
|
class Gel::Catalog::LegacyIndex
|
|
12
10
|
include Gel::Catalog::Common
|
|
13
11
|
CACHE_TYPE = "quick"
|
|
14
12
|
|
|
15
|
-
def initialize(*)
|
|
13
|
+
def initialize(*args, **kwargs)
|
|
16
14
|
super
|
|
17
15
|
|
|
18
16
|
@needs_update = true
|
|
19
17
|
@updating = false
|
|
20
|
-
@active_gems = Set.new
|
|
21
|
-
@pending_gems = Set.new
|
|
18
|
+
@active_gems = Gel::Set.new
|
|
19
|
+
@pending_gems = Gel::Set.new
|
|
22
20
|
|
|
23
21
|
@gem_versions = {}
|
|
24
22
|
end
|
data/lib/gel/catalog.rb
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "fileutils"
|
|
4
|
-
require "net/http"
|
|
5
3
|
require "uri"
|
|
6
|
-
require "digest"
|
|
7
4
|
|
|
8
5
|
require_relative "httpool"
|
|
6
|
+
require_relative "util"
|
|
9
7
|
require_relative "support/gem_platform"
|
|
8
|
+
require_relative "vendor/ruby_digest"
|
|
10
9
|
|
|
11
10
|
class Gel::Catalog
|
|
12
11
|
UPDATE_CONCURRENCY = 8
|
|
13
12
|
|
|
13
|
+
autoload :Common, File.expand_path("catalog/common", __dir__)
|
|
14
|
+
autoload :CompactIndex, File.expand_path("catalog/compact_index", __dir__)
|
|
15
|
+
autoload :DependencyIndex, File.expand_path("catalog/dependency_index", __dir__)
|
|
16
|
+
autoload :LegacyIndex, File.expand_path("catalog/legacy_index", __dir__)
|
|
17
|
+
|
|
14
18
|
def initialize(uri, httpool: Gel::Httpool.new, work_pool:, cache: ENV["GEL_CACHE"] || "~/.cache/gel", initial_gems: [])
|
|
15
19
|
@uri = normalize_uri(uri)
|
|
16
20
|
@httpool = httpool
|
|
@@ -25,10 +29,10 @@ class Gel::Catalog
|
|
|
25
29
|
]
|
|
26
30
|
end
|
|
27
31
|
|
|
28
|
-
def
|
|
29
|
-
|
|
30
|
-
rescue
|
|
31
|
-
if @indexes.size > 1
|
|
32
|
+
def attempting_each_index
|
|
33
|
+
yield send(@indexes.first)
|
|
34
|
+
rescue => ex
|
|
35
|
+
if recoverable?(ex) && @indexes.size > 1
|
|
32
36
|
@indexes.shift
|
|
33
37
|
retry
|
|
34
38
|
else
|
|
@@ -36,65 +40,44 @@ class Gel::Catalog
|
|
|
36
40
|
end
|
|
37
41
|
end
|
|
38
42
|
|
|
39
|
-
def
|
|
40
|
-
|
|
43
|
+
def recoverable?(exception)
|
|
44
|
+
defined?(Net::HTTPExceptions) && Net::HTTPExceptions === exception
|
|
41
45
|
end
|
|
42
46
|
|
|
43
|
-
def
|
|
44
|
-
|
|
47
|
+
def prepare
|
|
48
|
+
attempting_each_index { |index| index.prepare(@initial_gems) }
|
|
45
49
|
end
|
|
46
50
|
|
|
47
|
-
def
|
|
48
|
-
|
|
51
|
+
def gem_info(name)
|
|
52
|
+
attempting_each_index { |index| index.gem_info(name) }
|
|
49
53
|
end
|
|
50
54
|
|
|
51
|
-
def
|
|
52
|
-
|
|
55
|
+
def compact_index
|
|
56
|
+
@compact_index ||= Gel::Catalog::CompactIndex.new(@uri, uri_identifier, httpool: @httpool, work_pool: @work_pool, cache: @cache)
|
|
53
57
|
end
|
|
54
58
|
|
|
55
|
-
def
|
|
56
|
-
|
|
57
|
-
rescue Net::HTTPExceptions
|
|
58
|
-
if @indexes.size > 1
|
|
59
|
-
@indexes.shift
|
|
60
|
-
retry
|
|
61
|
-
else
|
|
62
|
-
raise
|
|
63
|
-
end
|
|
59
|
+
def dependency_index
|
|
60
|
+
@dependency_index ||= Gel::Catalog::DependencyIndex.new(self, @uri, uri_identifier, httpool: @httpool, work_pool: @work_pool, cache: @cache)
|
|
64
61
|
end
|
|
65
62
|
|
|
66
|
-
def
|
|
67
|
-
|
|
68
|
-
return path if File.exist?(path)
|
|
63
|
+
def legacy_index
|
|
64
|
+
@legacy_index ||= Gel::Catalog::LegacyIndex.new(@uri, uri_identifier, httpool: @httpool, work_pool: @work_pool, cache: @cache)
|
|
69
65
|
end
|
|
70
66
|
|
|
71
67
|
def download_gem(name, version)
|
|
72
68
|
path = cache_path(name, version)
|
|
73
69
|
return path if File.exist?(path)
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
path
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
VARIANT_GEMS = %w(libv8)
|
|
86
|
-
def guess_version(name, version)
|
|
87
|
-
if VARIANT_GEMS.include?(name)
|
|
88
|
-
[name, "#{version}-#{platform_specific_version}"]
|
|
89
|
-
else
|
|
90
|
-
[name, version]
|
|
71
|
+
if gem_info(name)
|
|
72
|
+
response = http_get("/gems/#{name}-#{version}.gem")
|
|
73
|
+
Gel::Util.mkdir_p(cache_dir)
|
|
74
|
+
File.open(path, "wb") do |f|
|
|
75
|
+
f.write(response.body)
|
|
76
|
+
end
|
|
77
|
+
path
|
|
91
78
|
end
|
|
92
79
|
end
|
|
93
80
|
|
|
94
|
-
def platform_specific_version
|
|
95
|
-
Gel::Support::GemPlatform.new(RbConfig::CONFIG["arch"])
|
|
96
|
-
end
|
|
97
|
-
|
|
98
81
|
def inspect
|
|
99
82
|
"#<#{self.class} #{to_s.inspect}>"
|
|
100
83
|
end
|
|
@@ -117,7 +100,7 @@ class Gel::Catalog
|
|
|
117
100
|
end
|
|
118
101
|
|
|
119
102
|
def uri_identifier
|
|
120
|
-
@uri.host + "-" +
|
|
103
|
+
@uri.host + "-" + Gel::Vendor::RubyDigest::SHA256.hexdigest(@uri.to_s)[0..10]
|
|
121
104
|
end
|
|
122
105
|
|
|
123
106
|
def cache_dir
|
|
@@ -129,6 +112,8 @@ class Gel::Catalog
|
|
|
129
112
|
end
|
|
130
113
|
|
|
131
114
|
def http_get(path)
|
|
115
|
+
require "net/http"
|
|
116
|
+
|
|
132
117
|
original_uri = uri = URI(File.join(@uri.to_s, path))
|
|
133
118
|
|
|
134
119
|
5.times do
|
|
@@ -147,7 +132,3 @@ class Gel::Catalog
|
|
|
147
132
|
raise Gel::Error::TooManyRedirectsError.new(original_uri: original_uri)
|
|
148
133
|
end
|
|
149
134
|
end
|
|
150
|
-
|
|
151
|
-
require_relative "catalog/compact_index"
|
|
152
|
-
require_relative "catalog/dependency_index"
|
|
153
|
-
require_relative "catalog/legacy_index"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "platform"
|
|
4
|
+
|
|
5
|
+
class Gel::CatalogSet
|
|
6
|
+
CatalogEntry = Struct.new(:catalog, :name, :version, :info) do
|
|
7
|
+
def gem_version
|
|
8
|
+
@gem_version ||= Gel::Support::GemVersion.new(version)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(catalogs)
|
|
13
|
+
@catalogs = catalogs
|
|
14
|
+
|
|
15
|
+
@cached_specs = Hash.new { |h, k| h[k] = {} }
|
|
16
|
+
@specs_by_package_version = {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def catalog_for_version(package, version)
|
|
20
|
+
@specs_by_package_version[package.name][version.to_s]&.catalog
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def entries_for(package)
|
|
24
|
+
fetch_package_info(package)
|
|
25
|
+
|
|
26
|
+
@specs_by_package_version[package.name].values.select do |spec|
|
|
27
|
+
available_platforms = spec.info.map(&:first)
|
|
28
|
+
Gel::Platform.match(package.platform, available_platforms)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Returns a list of [name, version_contraint] pairs representing the
|
|
33
|
+
# specified package's dependencies. Note that a given +name+ may
|
|
34
|
+
# appear multiple times, and the resulting dependency is the
|
|
35
|
+
# intersection of all constraints.
|
|
36
|
+
def dependencies_for(package, version)
|
|
37
|
+
fetch_package_info(package) # probably already done, can't hurt
|
|
38
|
+
|
|
39
|
+
spec = @specs_by_package_version[package.name][version.to_s]
|
|
40
|
+
|
|
41
|
+
raise "missing spec #{package.inspect} / #{version.inspect}" if spec.nil?
|
|
42
|
+
|
|
43
|
+
info = spec.info
|
|
44
|
+
|
|
45
|
+
available_platforms = info.map(&:first)
|
|
46
|
+
matching_platform = Gel::Platform.match(package.platform, available_platforms)
|
|
47
|
+
|
|
48
|
+
info = info.select { |p, i| p == matching_platform }
|
|
49
|
+
|
|
50
|
+
# FIXME: ruby_constraints ???
|
|
51
|
+
|
|
52
|
+
info.flat_map { |_, i| i[:dependencies] }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def platform_for(package, version)
|
|
56
|
+
fetch_package_info(package) # probably already done, can't hurt
|
|
57
|
+
|
|
58
|
+
spec = @specs_by_package_version[package.name][version.to_s]
|
|
59
|
+
|
|
60
|
+
info = spec.info
|
|
61
|
+
|
|
62
|
+
available_platforms = info.map(&:first)
|
|
63
|
+
Gel::Platform.match(package.platform, available_platforms)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def fetch_package_info(package)
|
|
69
|
+
return if @specs_by_package_version.key?(package.name)
|
|
70
|
+
|
|
71
|
+
specs = []
|
|
72
|
+
@catalogs.each do |catalog|
|
|
73
|
+
if catalog.nil?
|
|
74
|
+
break unless specs.empty?
|
|
75
|
+
next
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
if info = catalog.gem_info(package.name)
|
|
79
|
+
@cached_specs[catalog][package.name] ||=
|
|
80
|
+
begin
|
|
81
|
+
grouped_versions = info.to_a.map do |full_version, attributes|
|
|
82
|
+
version, platform = full_version.split("-", 2)
|
|
83
|
+
platform ||= "ruby"
|
|
84
|
+
[version, platform, attributes]
|
|
85
|
+
end.group_by(&:first)
|
|
86
|
+
|
|
87
|
+
grouped_versions.map { |version, tuples| CatalogEntry.new(catalog, package.name, version, tuples.map { |_, p, a| [p, a] }) }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
specs.concat @cached_specs[catalog][package.name]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
@specs_by_package_version[package.name] = {}
|
|
95
|
+
specs.each do |spec|
|
|
96
|
+
# TODO: are we going to find specs in multiple catalogs this way?
|
|
97
|
+
@specs_by_package_version[package.name][spec.version] = spec
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
data/lib/gel/command/help.rb
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Gel::Command::Help < Gel::Command
|
|
4
|
-
def run(
|
|
5
|
-
|
|
4
|
+
def run(_command_line)
|
|
5
|
+
puts <<~HELP
|
|
6
|
+
Gel is a modern gem manager.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
gel help Print this help message.
|
|
10
|
+
gel install Install the gems from Gemfile.
|
|
11
|
+
gel lock Update lockfile without installing.
|
|
12
|
+
gel exec Run command in context of the gel.
|
|
13
|
+
|
|
14
|
+
Further information:
|
|
15
|
+
https://gel.dev/
|
|
16
|
+
HELP
|
|
6
17
|
end
|
|
7
18
|
end
|
data/lib/gel/command/lock.rb
CHANGED
|
@@ -25,10 +25,10 @@ class Gel::Command::Lock < Gel::Command
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
require_relative "../pub_grub/preference_strategy"
|
|
28
|
-
options[:preference_strategy] = lambda do |
|
|
29
|
-
Gel::PubGrub::PreferenceStrategy.new(
|
|
28
|
+
options[:preference_strategy] = lambda do |gem_set|
|
|
29
|
+
Gel::PubGrub::PreferenceStrategy.new(gem_set, overrides, bump: mode, strict: strict)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
Gel::Environment.
|
|
32
|
+
Gel::Environment.write_lock(output: $stderr, **options)
|
|
33
33
|
end
|
|
34
34
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Gel::Command::Open < Gel::Command
|
|
4
|
+
def run(command_line)
|
|
5
|
+
require "shellwords"
|
|
6
|
+
|
|
7
|
+
raise "Please provide the name of a gem to open in your editor" if command_line.empty?
|
|
8
|
+
raise "Too many arguments, only 1 gem name is supported" if command_line.length > 1
|
|
9
|
+
gem_name = command_line.shift
|
|
10
|
+
|
|
11
|
+
editor = ENV.fetch("GEL_EDITOR", ENV["EDITOR"])
|
|
12
|
+
raise "An editor must be set using either $GEL_EDITOR or $EDITOR" unless editor
|
|
13
|
+
|
|
14
|
+
Gel::Environment.activate(output: $stderr)
|
|
15
|
+
|
|
16
|
+
found_gem = Gel::Environment.find_gem(gem_name)
|
|
17
|
+
raise "Can't find gem `#{gem_name}`" unless found_gem
|
|
18
|
+
|
|
19
|
+
command = [*Shellwords.split(editor), found_gem.root]
|
|
20
|
+
Dir.chdir(found_gem.root) do
|
|
21
|
+
exec(*command)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -4,22 +4,25 @@ class Gel::Command::ShellSetup < Gel::Command
|
|
|
4
4
|
def run(command_line)
|
|
5
5
|
require "shellwords"
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
shell = command_line[0] || File.basename(ENV.fetch("SHELL", "bash"))
|
|
8
8
|
|
|
9
9
|
bin_dir = File.expand_path("~/.local/gel/bin")
|
|
10
10
|
unless ENV.fetch("PATH", "").split(File::PATH_SEPARATOR).include?(bin_dir)
|
|
11
|
-
puts "PATH
|
|
12
|
-
variables << "PATH"
|
|
11
|
+
puts export("PATH", "\"#{Shellwords.shellescape bin_dir}#{File::PATH_SEPARATOR}$PATH\"", shell: shell)
|
|
13
12
|
end
|
|
14
13
|
|
|
15
|
-
lib_dir = File.expand_path("
|
|
14
|
+
lib_dir = File.expand_path("../../slib", __dir__)
|
|
16
15
|
unless ENV.fetch("RUBYLIB", "").split(File::PATH_SEPARATOR).include?(lib_dir)
|
|
17
|
-
puts "RUBYLIB
|
|
18
|
-
variables << "RUBYLIB"
|
|
16
|
+
puts export("RUBYLIB", "\"#{Shellwords.shellescape lib_dir}:$RUBYLIB\"", shell: shell)
|
|
19
17
|
end
|
|
18
|
+
end
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
def export(env, value, shell: nil)
|
|
21
|
+
case shell
|
|
22
|
+
when "fish"
|
|
23
|
+
"set -x #{env} #{value}"
|
|
24
|
+
else
|
|
25
|
+
"export #{env}=#{value}"
|
|
23
26
|
end
|
|
24
27
|
end
|
|
25
28
|
end
|
data/lib/gel/command/stub.rb
CHANGED
|
@@ -2,11 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
class Gel::Command::Stub < Gel::Command
|
|
4
4
|
def run(command_line)
|
|
5
|
-
|
|
5
|
+
if command_line.first == "--rebuild"
|
|
6
|
+
Gel::Environment.store.stub_set.rebuild!
|
|
7
|
+
return
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Note that the most common stub invocation doesn't actually pass
|
|
11
|
+
# through here at all: a stubfile being run directly will present
|
|
12
|
+
# as `gel <full-path-to-stubfile>` and will be handled by the
|
|
13
|
+
# corresponding special case in the top level Gel::Command.run.
|
|
14
|
+
#
|
|
15
|
+
# We do get here when invoked by Gel.stub, or manual `gel stub foo`
|
|
16
|
+
# execution, though. In both of those cases, the first element of
|
|
17
|
+
# command_line will be the unqualified command to run, and the rest
|
|
18
|
+
# will be its arguments -- so we can just pass command_line along to
|
|
19
|
+
# Exec unmodified.
|
|
20
|
+
#
|
|
21
|
+
# However, there is one more situation that will end up here: when a
|
|
22
|
+
# legacy stub file is invoked. In that case, after the unqualified
|
|
23
|
+
# command name and before any supplied arguments, the shebang
|
|
24
|
+
# invocation will have inserted the fully-qualified stubfile path as
|
|
25
|
+
# well. We need to detect that, and strip it out.
|
|
26
|
+
|
|
27
|
+
command_line.slice!(1) if redundant_stub_argument?(command_line)
|
|
6
28
|
|
|
7
29
|
command = Gel::Command::Exec.new
|
|
8
|
-
command.run(
|
|
30
|
+
command.run(command_line, from_stub: true)
|
|
9
31
|
ensure
|
|
10
32
|
self.reraise = command.reraise if command
|
|
11
33
|
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def redundant_stub_argument?((command, possible_stub_path, *))
|
|
38
|
+
return false unless possible_stub_path
|
|
39
|
+
|
|
40
|
+
# Gel.stub injects a symbol to disambiguate the subsequent
|
|
41
|
+
# arguments; we don't need to look any further, and definitely want
|
|
42
|
+
# to strip it out.
|
|
43
|
+
return true if possible_stub_path == :stub
|
|
44
|
+
|
|
45
|
+
# A true redundant argument is a fully-qualified version of the
|
|
46
|
+
# stubbed command. Does it even look like the names match?
|
|
47
|
+
return false unless possible_stub_path.end_with?(command)
|
|
48
|
+
|
|
49
|
+
# Okay, it seems plausible; in that case, it's time to check
|
|
50
|
+
# properly.
|
|
51
|
+
stub_set = Gel::Environment.store.stub_set
|
|
52
|
+
stub_set.own_stub?(possible_stub_path) &&
|
|
53
|
+
stub_set.parse_stub(possible_stub_path) == command
|
|
54
|
+
end
|
|
12
55
|
end
|