uprb 0.1.0 → 0.1.1
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 +24 -31
- data/lib/uprb/cli.rb +8 -1
- data/lib/uprb/gemspec_metadata.rb +48 -0
- data/lib/uprb/version.rb +1 -1
- data/lib/uprb.rb +1 -0
- metadata +4 -31
- data/CLAUDE.md +0 -55
- data/Rakefile +0 -8
- data/examples/rls/.gitignore +0 -8
- data/examples/rls/Gemfile +0 -9
- data/examples/rls/README.md +0 -9
- data/examples/rls/Rakefile +0 -4
- data/examples/rls/bin/console +0 -11
- data/examples/rls/bin/setup +0 -8
- data/examples/rls/exe/rls +0 -7
- data/examples/rls/lib/rls/cli.rb +0 -48
- data/examples/rls/lib/rls/version.rb +0 -5
- data/examples/rls/lib/rls.rb +0 -8
- data/examples/rls/rls.gemspec +0 -28
- data/examples/rls/sig/rls.rbs +0 -4
- data/examples/s3-ls/.gitignore +0 -8
- data/examples/s3-ls/Gemfile +0 -9
- data/examples/s3-ls/Gemfile.lock +0 -91
- data/examples/s3-ls/README.md +0 -19
- data/examples/s3-ls/Rakefile +0 -4
- data/examples/s3-ls/bin/console +0 -11
- data/examples/s3-ls/bin/setup +0 -8
- data/examples/s3-ls/exe/s3-ls +0 -7
- data/examples/s3-ls/lib/s3/ls/cli.rb +0 -78
- data/examples/s3-ls/lib/s3/ls/version.rb +0 -7
- data/examples/s3-ls/lib/s3/ls.rb +0 -10
- data/examples/s3-ls/s3-ls.gemspec +0 -36
- data/examples/s3-ls/sig/s3/ls.rbs +0 -6
- data/tmp/.keep +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c79e09b63bc16daf49de2a04627cd3825ad40ad973a835341339828c3854b51c
|
|
4
|
+
data.tar.gz: '081a3f3ee78a32fee28cc5e05db07c211c61e8af666da4fa7b364f6fe18928e2'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1ede8e2f96412adb1c4d76938b437758d78d4f46943cc1d7de7dc81c72a1fcc1d171428f41e735149c5837933454ecedca4009e0bbc6ca421d0fc96c92ab0c97
|
|
7
|
+
data.tar.gz: de104925689191bdf21068b0257002ebcae2cda12d6ca39eb970fe958dbaf351e20ad2b8cdcc169a9d891df104e15db726139cd8d330272ed9fe3faf2c05fcca
|
data/README.md
CHANGED
|
@@ -1,36 +1,25 @@
|
|
|
1
1
|
# uprb
|
|
2
2
|
|
|
3
|
-
uprb
|
|
4
|
-
|
|
3
|
+
[](https://github.com/hogelog/uprb/actions/workflows/test.yml)
|
|
4
|
+
[](http://badge.fury.io/rb/uprb)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
a Ruby interpreter on the machine that runs it, and it is tied to the
|
|
8
|
-
Ruby and gems that were active when you packed.
|
|
6
|
+
uprb packs a Ruby script into a single executable with fast, deterministic startup.
|
|
9
7
|
|
|
10
|
-
The
|
|
11
|
-
Gems that depend on rubygems at load time will not work as-is — use
|
|
12
|
-
`--with-rubygems` to embed rubygems into the output, or
|
|
13
|
-
`--skip-disable-gems` to drop the flag entirely (vendoring only; gives
|
|
14
|
-
up the fast-startup headline).
|
|
8
|
+
The output still requires a Ruby interpreter and is tied to the Ruby and gems active at pack time. The default shebang runs Ruby with `--disable-gems`; flags below can change this.
|
|
15
9
|
|
|
16
|
-
##
|
|
17
|
-
|
|
18
|
-
Pack a script into a single executable:
|
|
10
|
+
## Install
|
|
19
11
|
|
|
20
12
|
```bash
|
|
21
|
-
|
|
13
|
+
gem install uprb
|
|
22
14
|
```
|
|
23
15
|
|
|
24
|
-
|
|
16
|
+
## Usage
|
|
25
17
|
|
|
26
|
-
|
|
27
|
-
- `-r`, `--require LIB`: pre-`require` `LIB` so it is embedded and loaded before the script runs. Repeatable.
|
|
28
|
-
- `--with-rubygems`: shortcut for `--require rubygems`. Needed when the script references `Gem::Version` / `Gem::Requirement` / `Gem::Platform` etc. Trade-off: larger output.
|
|
29
|
-
- `--dynamic`: execute the entry script at pack time so runtime-only requires (e.g. interpolated `require`s) are captured. The entry actually runs, which is a problem for scripts that do I/O on startup — arguments after `--` are forwarded as `ARGV` so you can steer into a safe path (e.g. `-- --help`).
|
|
30
|
-
- `--skip-disable-gems`: drop `--disable-gems` from the shebang. The output then behaves like a normal Ruby invocation — rubygems, `RUBYOPT`, and Bundler's Gemfile autodetection all run as usual. Use this when you want single-file vendoring of `.rb` dependencies and don't care about startup latency.
|
|
31
|
-
- `--skip-ruby-path-replace`: keep the source file's shebang ruby invocation (e.g. `/usr/bin/env ruby`) instead of rewriting it to an absolute `RbConfig.ruby` path. `--disable-gems` is still appended (unless `--skip-disable-gems` is also passed), so this is orthogonal to `--skip-disable-gems`. Use for vendoring when you want a portable Ruby reference in the output.
|
|
18
|
+
Pack a script:
|
|
32
19
|
|
|
33
|
-
|
|
20
|
+
```bash
|
|
21
|
+
uprb pack path/to/script.rb path/to/output
|
|
22
|
+
```
|
|
34
23
|
|
|
35
24
|
Pack executables from an installed gem:
|
|
36
25
|
|
|
@@ -44,16 +33,20 @@ Install a gem and pack its executables:
|
|
|
44
33
|
uprb gem install GEM_NAME
|
|
45
34
|
```
|
|
46
35
|
|
|
47
|
-
|
|
48
|
-
`-f`/`--force`, `-r`/`--require LIB`, `--with-rubygems`, `--dynamic`,
|
|
49
|
-
`--skip-disable-gems`, and `--skip-ruby-path-replace`.
|
|
36
|
+
## Options
|
|
50
37
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
38
|
+
- `-f`, `--force` — overwrite destination
|
|
39
|
+
- `-r`, `--require LIB` — pre-`require` `LIB` (repeatable)
|
|
40
|
+
- `--with-rubygems` — embed rubygems; needed when the script references `Gem::Version` etc.
|
|
41
|
+
- `--dynamic` — run the entry script at pack time to capture runtime `require`s. Arguments after `--` become `ARGV` (e.g. `-- --help` to avoid side effects)
|
|
42
|
+
- `--skip-disable-gems` — drop `--disable-gems` from the shebang (vendoring mode; gives up fast startup)
|
|
43
|
+
- `--skip-ruby-path-replace` — keep the source shebang's ruby invocation instead of rewriting to an absolute path
|
|
44
|
+
- `--path DIR` — destination directory (`gem` subcommands only)
|
|
54
45
|
|
|
55
|
-
##
|
|
46
|
+
## Gemspec metadata
|
|
56
47
|
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
`uprb gem pack` / `uprb gem install` honors `uprb.requires` (comma-separated) in `Gem::Specification#metadata` as additional pre-`require` libraries, merged with `-r`:
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
spec.metadata["uprb.requires"] = "openssl,json"
|
|
59
52
|
```
|
data/lib/uprb/cli.rb
CHANGED
|
@@ -155,6 +155,13 @@ module Uprb
|
|
|
155
155
|
raise Uprb::Error, "no executables for gem: #{gem_name}" if executables.empty?
|
|
156
156
|
bindir = spec.bindir
|
|
157
157
|
|
|
158
|
+
metadata_result = Uprb::GemspecMetadata.read(spec)
|
|
159
|
+
metadata_result.warnings.each { |w| $stderr.puts(w) }
|
|
160
|
+
unless metadata_result.requires.empty?
|
|
161
|
+
$stderr.puts("uprb: applying gemspec metadata uprb.requires: #{metadata_result.requires.inspect}")
|
|
162
|
+
end
|
|
163
|
+
requires = (metadata_result.requires + options[:requires]).uniq
|
|
164
|
+
|
|
158
165
|
dest_dir = options[:path] ? File.expand_path(options[:path]) : Gem.bindir
|
|
159
166
|
FileUtils.mkdir_p(dest_dir)
|
|
160
167
|
|
|
@@ -166,7 +173,7 @@ module Uprb
|
|
|
166
173
|
|
|
167
174
|
next unless confirm_overwrite(dest_path, options)
|
|
168
175
|
|
|
169
|
-
Uprb::RequireReplacer.pack(source_path, dest_path:, requires
|
|
176
|
+
Uprb::RequireReplacer.pack(source_path, dest_path:, requires:, dynamic: options[:dynamic], script_argv: options[:script_argv], skip_disable_gems: options[:skip_disable_gems], skip_ruby_path_replace: options[:skip_ruby_path_replace])
|
|
170
177
|
$stdout.puts("Packed #{dest_path}")
|
|
171
178
|
end
|
|
172
179
|
rescue Gem::LoadError => e
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Uprb
|
|
4
|
+
module GemspecMetadata
|
|
5
|
+
KNOWN_KEYS = %w[uprb.requires].freeze
|
|
6
|
+
REQUIRES_KEY = "uprb.requires"
|
|
7
|
+
REQUIRE_ENTRY_PATTERN = %r{\A[A-Za-z0-9_.][A-Za-z0-9_./-]*\z}
|
|
8
|
+
|
|
9
|
+
Result = Struct.new(:requires, :warnings, keyword_init: true)
|
|
10
|
+
|
|
11
|
+
def self.read(spec)
|
|
12
|
+
metadata = spec.metadata || {}
|
|
13
|
+
warnings = []
|
|
14
|
+
requires = []
|
|
15
|
+
|
|
16
|
+
metadata.each do |key, value|
|
|
17
|
+
next unless key.start_with?("uprb.")
|
|
18
|
+
|
|
19
|
+
unless KNOWN_KEYS.include?(key)
|
|
20
|
+
warnings << "uprb: ignoring unknown gemspec metadata key #{key.inspect}"
|
|
21
|
+
next
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if key == REQUIRES_KEY
|
|
25
|
+
parsed, entry_warnings = parse_requires(value)
|
|
26
|
+
requires.concat(parsed)
|
|
27
|
+
warnings.concat(entry_warnings)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Result.new(requires:, warnings:)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.parse_requires(value)
|
|
35
|
+
warnings = []
|
|
36
|
+
entries = value.to_s.split(",").map(&:strip).reject(&:empty?)
|
|
37
|
+
kept = entries.select do |entry|
|
|
38
|
+
if REQUIRE_ENTRY_PATTERN.match?(entry)
|
|
39
|
+
true
|
|
40
|
+
else
|
|
41
|
+
warnings << "uprb: ignoring gemspec metadata #{REQUIRES_KEY} entry #{entry.inspect}"
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
[kept, warnings]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/uprb/version.rb
CHANGED
data/lib/uprb.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: uprb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- hogelog
|
|
@@ -31,44 +31,17 @@ executables:
|
|
|
31
31
|
extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
|
33
33
|
files:
|
|
34
|
-
- CLAUDE.md
|
|
35
34
|
- LICENSE.txt
|
|
36
35
|
- README.md
|
|
37
|
-
- Rakefile
|
|
38
|
-
- examples/rls/.gitignore
|
|
39
|
-
- examples/rls/Gemfile
|
|
40
|
-
- examples/rls/README.md
|
|
41
|
-
- examples/rls/Rakefile
|
|
42
|
-
- examples/rls/bin/console
|
|
43
|
-
- examples/rls/bin/setup
|
|
44
|
-
- examples/rls/exe/rls
|
|
45
|
-
- examples/rls/lib/rls.rb
|
|
46
|
-
- examples/rls/lib/rls/cli.rb
|
|
47
|
-
- examples/rls/lib/rls/version.rb
|
|
48
|
-
- examples/rls/rls.gemspec
|
|
49
|
-
- examples/rls/sig/rls.rbs
|
|
50
|
-
- examples/s3-ls/.gitignore
|
|
51
|
-
- examples/s3-ls/Gemfile
|
|
52
|
-
- examples/s3-ls/Gemfile.lock
|
|
53
|
-
- examples/s3-ls/README.md
|
|
54
|
-
- examples/s3-ls/Rakefile
|
|
55
|
-
- examples/s3-ls/bin/console
|
|
56
|
-
- examples/s3-ls/bin/setup
|
|
57
|
-
- examples/s3-ls/exe/s3-ls
|
|
58
|
-
- examples/s3-ls/lib/s3/ls.rb
|
|
59
|
-
- examples/s3-ls/lib/s3/ls/cli.rb
|
|
60
|
-
- examples/s3-ls/lib/s3/ls/version.rb
|
|
61
|
-
- examples/s3-ls/s3-ls.gemspec
|
|
62
|
-
- examples/s3-ls/sig/s3/ls.rbs
|
|
63
36
|
- exe/uprb
|
|
64
37
|
- lib/uprb.rb
|
|
65
38
|
- lib/uprb/cli.rb
|
|
39
|
+
- lib/uprb/gemspec_metadata.rb
|
|
66
40
|
- lib/uprb/require_replacer.rb
|
|
67
41
|
- lib/uprb/require_tracker.rb
|
|
68
42
|
- lib/uprb/static_require_tracker.rb
|
|
69
43
|
- lib/uprb/version.rb
|
|
70
44
|
- sig/uprb.rbs
|
|
71
|
-
- tmp/.keep
|
|
72
45
|
homepage: https://github.com/hogelog/uprb
|
|
73
46
|
licenses:
|
|
74
47
|
- MIT
|
|
@@ -82,14 +55,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
82
55
|
requirements:
|
|
83
56
|
- - ">="
|
|
84
57
|
- !ruby/object:Gem::Version
|
|
85
|
-
version: 3.
|
|
58
|
+
version: 3.3.0
|
|
86
59
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
60
|
requirements:
|
|
88
61
|
- - ">="
|
|
89
62
|
- !ruby/object:Gem::Version
|
|
90
63
|
version: '0'
|
|
91
64
|
requirements: []
|
|
92
|
-
rubygems_version:
|
|
65
|
+
rubygems_version: 3.6.9
|
|
93
66
|
specification_version: 4
|
|
94
67
|
summary: Pack Ruby scripts into deterministic, fast-starting executables.
|
|
95
68
|
test_files: []
|
data/CLAUDE.md
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. User-facing docs live in `README.md`.
|
|
4
|
-
|
|
5
|
-
## Commands
|
|
6
|
-
|
|
7
|
-
- `bin/setup` — `bundle install`.
|
|
8
|
-
- `bundle exec rake` — run the full test suite.
|
|
9
|
-
- `bundle exec ruby -Itest test/test_uprb_cli.rb -n test_pack_builds_executable` — run a single test by name.
|
|
10
|
-
- `bundle exec exe/uprb pack path/to/script.rb path/to/out` — run the CLI from the working tree.
|
|
11
|
-
|
|
12
|
-
Ruby 3.1+ (`uprb.gemspec`). CI: 3.4.7.
|
|
13
|
-
|
|
14
|
-
## What uprb does
|
|
15
|
-
|
|
16
|
-
Packs a Ruby script into a deterministic, fast-starting executable by **freezing every observed `require` at pack time**. At runtime, the frozen mapping is preferred; anything else falls through to Ruby's normal `require`. If the environment changes, the executable is expected to break — the only remediation is repack.
|
|
17
|
-
|
|
18
|
-
## Architecture
|
|
19
|
-
|
|
20
|
-
- `lib/uprb/require_tracker.rb` — aliases `Kernel#require` / `Kernel#require_relative` and records `name => $LOADED_FEATURES` path on every successful call.
|
|
21
|
-
- `lib/uprb/static_require_tracker.rb` — the **default** tracer. Two passes: (1) parse the entry with Prism and actually `require` each literal require/autoload target — libraries load normally but the entry's other top-level code (e.g. `App.start(ARGV)`) does not run, and everything pulled in transitively is recorded via `RequireTracker`; (2) `StaticWalker` recursively parses every reachable `.rb` file to pick up literal requires and autoload paths that the runtime never hit (rescued `LoadError` alternates, unused autoloads, feature-flag branches). The merged map uses dynamic results on conflict since those reflect the actually-resolved path. Interpolated-string requires triggered only by runtime execution (e.g. `require "foo/#{name}"` inside a method called by the entry) are still missed — those need `--dynamic`.
|
|
22
|
-
- `lib/uprb/require_replacer.rb` — `pack` builds the mapping via `build_mapping` (default: `StaticRequireTracker.trace`; `--dynamic`: `execute_with_tracker` + `StaticWalker` as a second pass so the runtime-only captures are augmented with literal/autoload paths not exercised by the execution). Then compiles the main script and every `.rb` entry into `RubyVM::InstructionSequence` binaries and appends a `Marshal` payload after `__END__`. A prepended `FixedRequire` module serves embedded ISeqs; non-`.rb` requires (C extensions etc.) are resolved via a `REQUIRE_MAP` of original absolute paths; unknown names defer to `super`. `execute_with_tracker` captures stdout/stderr to `Tempfile`, clears `ARGV`, sets `$PROGRAM_NAME`, and `Kernel#load`s the source in-process.
|
|
23
|
-
- `lib/uprb/cli.rb`, `exe/uprb` — CLI: `pack`, `gem install`, `gem pack`. Options: `--path DIR` (gem subcommands; default `Gem.bindir`).
|
|
24
|
-
|
|
25
|
-
The output gets a shebang only when the source does. With a source shebang, the wrapper's shebang is the absolute `RbConfig.ruby` path plus `--disable-gems` by default. Two orthogonal opt-outs:
|
|
26
|
-
|
|
27
|
-
- `--skip-disable-gems` drops the `--disable-gems` flag so the output starts Ruby normally (rubygems / `RUBYOPT` / Bundler Gemfile autodetection all active) — intended for vendoring-only use cases that accept normal startup cost.
|
|
28
|
-
- `--skip-ruby-path-replace` keeps the source file's shebang ruby invocation verbatim (e.g. `/usr/bin/env ruby`) instead of rewriting it to `RbConfig.ruby` — intended for vendoring that wants a portable Ruby reference in the output.
|
|
29
|
-
|
|
30
|
-
The two flags can be combined (e.g. `#!/usr/bin/env ruby` with no `--disable-gems`). When the source has no shebang, the packed output also has none and is not chmod'd executable — invoke via `ruby packed_file`. This is uniform across all flag combinations.
|
|
31
|
-
|
|
32
|
-
## Hard constraints on the generated executable
|
|
33
|
-
|
|
34
|
-
Any change to the output generator must preserve these — violating any is a bug:
|
|
35
|
-
|
|
36
|
-
- Absolute `RbConfig.ruby` path in the shebang by default; never `/usr/bin/env ruby`, never a PATH lookup. `--skip-ruby-path-replace` is the one documented opt-out, for vendoring-only outputs that preserve the source's shebang ruby invocation
|
|
37
|
-
- `--disable-gems` in the shebang by default; rubygems is not available at runtime. `--skip-disable-gems` is the one documented opt-out, for vendoring-only outputs that accept normal Ruby startup cost
|
|
38
|
-
- No `-I`, no `$LOAD_PATH` modification, no `RUBYLIB`, no Bundler
|
|
39
|
-
- `.rb` dependencies are always embedded as ISeq binaries inside the `Marshal` payload; C extensions and other non-`.rb` requires are always referenced by their **original absolute path** via `REQUIRE_MAP` — never copied, never relocated
|
|
40
|
-
|
|
41
|
-
## Non-goals
|
|
42
|
-
|
|
43
|
-
Declining these is a design choice, not a todo:
|
|
44
|
-
|
|
45
|
-
- Bundling Ruby itself; vendoring C extensions; cross-machine portability
|
|
46
|
-
- Surviving Ruby/gem upgrades, graceful degradation
|
|
47
|
-
- Plugin systems or dynamic resolution beyond the frozen mapping
|
|
48
|
-
|
|
49
|
-
(Compiled `.rb` sources are embedded in the output, so it is *partially* self-contained for pure-Ruby deps. C extensions and the Ruby interpreter are still referenced by absolute path, so the output remains tied to the machine it was packed on.)
|
|
50
|
-
|
|
51
|
-
The output is expected to break when the Ruby path moves, C extension paths change, gems are up/downgraded, or new code paths hit unseen `require`s. The only remediation is `uprb pack <src> <dest>`.
|
|
52
|
-
|
|
53
|
-
## Testing notes
|
|
54
|
-
|
|
55
|
-
`test/test_uprb_cli.rb` shells out to `exe/uprb` via `Open3` and writes artifacts under `./tmp/` (gitignored). `aws-sdk-core` is a dev dependency so the suite can verify that a library pulling in rubygems vendored stdlib still packs successfully; the packed output itself is not runnable under `--disable-gems` and is not executed by the test. `examples/rls` and `examples/s3-ls` are sample gems, not part of the suite. `examples/s3-ls` depends on `aws-sdk-s3` and is kept as a reference — with a bare `uprb gem pack` it won't run under `--disable-gems`, but `uprb gem pack s3-ls --with-rubygems --dynamic` runs it up to the AWS credential/region resolution path (see `examples/s3-ls/README.md`).
|
data/Rakefile
DELETED
data/examples/rls/.gitignore
DELETED
data/examples/rls/Gemfile
DELETED
data/examples/rls/README.md
DELETED
data/examples/rls/Rakefile
DELETED
data/examples/rls/bin/console
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require "bundler/setup"
|
|
5
|
-
require "rls"
|
|
6
|
-
|
|
7
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
-
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
-
|
|
10
|
-
require "irb"
|
|
11
|
-
IRB.start(__FILE__)
|
data/examples/rls/bin/setup
DELETED
data/examples/rls/exe/rls
DELETED
data/examples/rls/lib/rls/cli.rb
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
module Rls
|
|
2
|
-
class CLI
|
|
3
|
-
USAGE = <<~USAGE.chomp
|
|
4
|
-
Usage:
|
|
5
|
-
rls [path]
|
|
6
|
-
USAGE
|
|
7
|
-
|
|
8
|
-
class << self
|
|
9
|
-
def start(argv)
|
|
10
|
-
new(argv).start
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def initialize(argv)
|
|
15
|
-
@argv = argv.dup
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def start
|
|
19
|
-
arg = @argv.shift
|
|
20
|
-
|
|
21
|
-
case arg
|
|
22
|
-
when "--help", "-h"
|
|
23
|
-
STDOUT.puts(USAGE)
|
|
24
|
-
when nil
|
|
25
|
-
ls_command
|
|
26
|
-
else
|
|
27
|
-
ls_command(arg)
|
|
28
|
-
end
|
|
29
|
-
rescue Rls::Error => e
|
|
30
|
-
STDERR.puts("rls: #{e.message}")
|
|
31
|
-
rescue StandardError => e
|
|
32
|
-
STDERR.puts("rls: #{e.class}: #{e.message}")
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
def ls_command(path = ".")
|
|
38
|
-
raise Rls::Error, "unexpected arguments: #{@argv.join(' ')}" unless @argv.empty?
|
|
39
|
-
|
|
40
|
-
abs_path = File.expand_path(path)
|
|
41
|
-
raise Rls::Error, "not a directory: #{path}" unless File.directory?(abs_path)
|
|
42
|
-
|
|
43
|
-
Dir.children(abs_path).sort.each do |entry|
|
|
44
|
-
STDOUT.puts(entry)
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
data/examples/rls/lib/rls.rb
DELETED
data/examples/rls/rls.gemspec
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "lib/rls/version"
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name = "rls"
|
|
7
|
-
spec.version = Rls::VERSION
|
|
8
|
-
spec.authors = ["hogelog"]
|
|
9
|
-
spec.email = ["konbu.komuro@gmail.com"]
|
|
10
|
-
|
|
11
|
-
spec.summary = "Example ls command gem"
|
|
12
|
-
spec.description = "Example ls command gem"
|
|
13
|
-
spec.homepage = "https://github.com/hogelog/uprb"
|
|
14
|
-
spec.required_ruby_version = ">= 3.2.0"
|
|
15
|
-
|
|
16
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
|
17
|
-
|
|
18
|
-
gemspec = File.basename(__FILE__)
|
|
19
|
-
spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
|
|
20
|
-
ls.readlines("\x0", chomp: true).reject do |f|
|
|
21
|
-
(f == gemspec) ||
|
|
22
|
-
f.start_with?(*%w[bin/ Gemfile .gitignore])
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
spec.bindir = "exe"
|
|
26
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) {|f| File.basename(f) }
|
|
27
|
-
spec.require_paths = ["lib"]
|
|
28
|
-
end
|
data/examples/rls/sig/rls.rbs
DELETED
data/examples/s3-ls/.gitignore
DELETED
data/examples/s3-ls/Gemfile
DELETED
data/examples/s3-ls/Gemfile.lock
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
s3-ls (0.1.0)
|
|
5
|
-
aws-sdk-s3 (>= 1.0)
|
|
6
|
-
|
|
7
|
-
GEM
|
|
8
|
-
remote: https://rubygems.org/
|
|
9
|
-
specs:
|
|
10
|
-
aws-eventstream (1.4.0)
|
|
11
|
-
aws-partitions (1.1202.0)
|
|
12
|
-
aws-sdk-core (3.241.3)
|
|
13
|
-
aws-eventstream (~> 1, >= 1.3.0)
|
|
14
|
-
aws-partitions (~> 1, >= 1.992.0)
|
|
15
|
-
aws-sigv4 (~> 1.9)
|
|
16
|
-
base64
|
|
17
|
-
bigdecimal
|
|
18
|
-
jmespath (~> 1, >= 1.6.1)
|
|
19
|
-
logger
|
|
20
|
-
aws-sdk-kms (1.120.0)
|
|
21
|
-
aws-sdk-core (~> 3, >= 3.241.3)
|
|
22
|
-
aws-sigv4 (~> 1.5)
|
|
23
|
-
aws-sdk-s3 (1.211.0)
|
|
24
|
-
aws-sdk-core (~> 3, >= 3.241.3)
|
|
25
|
-
aws-sdk-kms (~> 1)
|
|
26
|
-
aws-sigv4 (~> 1.5)
|
|
27
|
-
aws-sigv4 (1.12.1)
|
|
28
|
-
aws-eventstream (~> 1, >= 1.0.2)
|
|
29
|
-
base64 (0.3.0)
|
|
30
|
-
bigdecimal (4.0.1)
|
|
31
|
-
date (3.5.1)
|
|
32
|
-
erb (6.0.1)
|
|
33
|
-
io-console (0.8.2)
|
|
34
|
-
irb (1.16.0)
|
|
35
|
-
pp (>= 0.6.0)
|
|
36
|
-
rdoc (>= 4.0.0)
|
|
37
|
-
reline (>= 0.4.2)
|
|
38
|
-
jmespath (1.6.2)
|
|
39
|
-
logger (1.7.0)
|
|
40
|
-
pp (0.6.3)
|
|
41
|
-
prettyprint
|
|
42
|
-
prettyprint (0.2.0)
|
|
43
|
-
psych (5.3.1)
|
|
44
|
-
date
|
|
45
|
-
stringio
|
|
46
|
-
rake (13.3.1)
|
|
47
|
-
rdoc (7.0.3)
|
|
48
|
-
erb
|
|
49
|
-
psych (>= 4.0.0)
|
|
50
|
-
tsort
|
|
51
|
-
reline (0.6.3)
|
|
52
|
-
io-console (~> 0.5)
|
|
53
|
-
stringio (3.2.0)
|
|
54
|
-
tsort (0.2.0)
|
|
55
|
-
|
|
56
|
-
PLATFORMS
|
|
57
|
-
arm64-darwin-25
|
|
58
|
-
ruby
|
|
59
|
-
|
|
60
|
-
DEPENDENCIES
|
|
61
|
-
irb
|
|
62
|
-
rake (~> 13.0)
|
|
63
|
-
s3-ls!
|
|
64
|
-
|
|
65
|
-
CHECKSUMS
|
|
66
|
-
aws-eventstream (1.4.0) sha256=116bf85c436200d1060811e6f5d2d40c88f65448f2125bc77ffce5121e6e183b
|
|
67
|
-
aws-partitions (1.1202.0) sha256=c8aa0f134a23464c61cfd00edfb4b6d968b01847a8b591d4dcc0c63a4897c301
|
|
68
|
-
aws-sdk-core (3.241.3) sha256=c7c445ecf1c601c860fd537458b2eb8df0c5df01e63c371849e6594e6b1d4f47
|
|
69
|
-
aws-sdk-kms (1.120.0) sha256=a206ac6f62efbe971f802e8399d2702496a5c5bc800abcf94ead87bdddfdfd80
|
|
70
|
-
aws-sdk-s3 (1.211.0) sha256=2ae5feb09ff4862462824f267b76601ed16922a15de56cf51e4fa99bc5b3f519
|
|
71
|
-
aws-sigv4 (1.12.1) sha256=6973ff95cb0fd0dc58ba26e90e9510a2219525d07620c8babeb70ef831826c00
|
|
72
|
-
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
|
73
|
-
bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
|
|
74
|
-
date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
|
|
75
|
-
erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5
|
|
76
|
-
io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
|
|
77
|
-
irb (1.16.0) sha256=2abe56c9ac947cdcb2f150572904ba798c1e93c890c256f8429981a7675b0806
|
|
78
|
-
jmespath (1.6.2) sha256=238d774a58723d6c090494c8879b5e9918c19485f7e840f2c1c7532cf84ebcb1
|
|
79
|
-
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
|
|
80
|
-
pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6
|
|
81
|
-
prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
|
|
82
|
-
psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974
|
|
83
|
-
rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c
|
|
84
|
-
rdoc (7.0.3) sha256=dfe3d0981d19b7bba71d9dbaeb57c9f4e3a7a4103162148a559c4fc687ea81f9
|
|
85
|
-
reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
|
|
86
|
-
s3-ls (0.1.0)
|
|
87
|
-
stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
|
|
88
|
-
tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
|
|
89
|
-
|
|
90
|
-
BUNDLED WITH
|
|
91
|
-
4.0.3
|
data/examples/s3-ls/README.md
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# s3-ls
|
|
2
|
-
|
|
3
|
-
Example S3 ls command gem.
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
s3-ls s3://bucket[/prefix]
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Packing with uprb
|
|
12
|
-
|
|
13
|
-
`aws-sdk-core` pulls in rubygems vendored stdlib, so embed rubygems with `--with-rubygems`. Its credential provider chain uses runtime-only interpolated requires (e.g. `aws-sdk-core/json/#{name}_engine`), so pack in `--dynamic` mode so the entry actually runs and those requires fire:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
uprb gem pack s3-ls --with-rubygems --dynamic --path ~/local/bin/
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
`--dynamic` also augments its trace with a static walk of every reachable `.rb`, so literal requires in unexecuted credential-provider branches get embedded too. If a runtime path still falls through to something that wasn't observed or statically reachable, repack with additional `-r` flags for the missing libs.
|
data/examples/s3-ls/Rakefile
DELETED
data/examples/s3-ls/bin/console
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require "bundler/setup"
|
|
5
|
-
require "s3/ls"
|
|
6
|
-
|
|
7
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
-
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
-
|
|
10
|
-
require "irb"
|
|
11
|
-
IRB.start(__FILE__)
|
data/examples/s3-ls/bin/setup
DELETED
data/examples/s3-ls/exe/s3-ls
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "uri"
|
|
4
|
-
require "aws-sdk-s3"
|
|
5
|
-
require_relative "../ls"
|
|
6
|
-
|
|
7
|
-
module S3
|
|
8
|
-
module Ls
|
|
9
|
-
class CLI
|
|
10
|
-
USAGE = <<~USAGE.chomp
|
|
11
|
-
Usage:
|
|
12
|
-
s3-ls s3://bucket[/prefix]
|
|
13
|
-
s3-ls -h | --help
|
|
14
|
-
USAGE
|
|
15
|
-
|
|
16
|
-
def self.start(argv)
|
|
17
|
-
new(argv).start
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def initialize(argv)
|
|
21
|
-
@argv = argv.dup
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def start
|
|
25
|
-
if @argv.first == "-h" || @argv.first == "--help"
|
|
26
|
-
$stdout.puts USAGE
|
|
27
|
-
return
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
client = Aws::S3::Client.new
|
|
31
|
-
|
|
32
|
-
if @argv.empty?
|
|
33
|
-
list_buckets(client)
|
|
34
|
-
else
|
|
35
|
-
uri = @argv.shift
|
|
36
|
-
bucket, prefix = parse_s3_uri(uri)
|
|
37
|
-
list_objects(client, bucket, prefix)
|
|
38
|
-
end
|
|
39
|
-
rescue S3::Ls::Error => e
|
|
40
|
-
$stderr.puts "s3-ls: #{e.message}"
|
|
41
|
-
exit 1
|
|
42
|
-
rescue StandardError => e
|
|
43
|
-
$stderr.puts "s3-ls: #{e.class}: #{e.message}"
|
|
44
|
-
exit 1
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
private
|
|
48
|
-
|
|
49
|
-
def list_objects(client, bucket, prefix)
|
|
50
|
-
client.list_objects_v2(bucket: bucket, prefix: prefix).each_page do |page|
|
|
51
|
-
page.contents.each do |object|
|
|
52
|
-
$stdout.puts "s3://#{bucket}/#{object.key}"
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def list_buckets(client)
|
|
58
|
-
client.list_buckets.buckets.each do |bucket|
|
|
59
|
-
$stdout.puts "s3://#{bucket.name}"
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def parse_s3_uri(input)
|
|
64
|
-
uri = URI.parse(input)
|
|
65
|
-
raise S3::Ls::Error, "invalid s3 uri: #{input}" unless uri.scheme == "s3"
|
|
66
|
-
raise S3::Ls::Error, "missing bucket in s3 uri: #{input}" if uri.host.to_s.empty?
|
|
67
|
-
|
|
68
|
-
bucket = uri.host
|
|
69
|
-
prefix = uri.path
|
|
70
|
-
prefix = prefix.sub(%r{\A/}, "")
|
|
71
|
-
prefix = nil if prefix.empty?
|
|
72
|
-
[bucket, prefix]
|
|
73
|
-
rescue URI::InvalidURIError
|
|
74
|
-
raise S3::Ls::Error, "invalid s3 uri: #{input}"
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
data/examples/s3-ls/lib/s3/ls.rb
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "lib/s3/ls/version"
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name = "s3-ls"
|
|
7
|
-
spec.version = S3::Ls::VERSION
|
|
8
|
-
spec.authors = ["hogelog"]
|
|
9
|
-
spec.email = ["konbu.komuro@gmail.com"]
|
|
10
|
-
|
|
11
|
-
spec.summary = "Example S3 ls command gem"
|
|
12
|
-
spec.description = "Example S3 ls command gem"
|
|
13
|
-
spec.homepage = "https://github.com/hogelog/uprb"
|
|
14
|
-
spec.required_ruby_version = ">= 3.2.0"
|
|
15
|
-
|
|
16
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
|
17
|
-
spec.metadata["source_code_uri"] = spec.homepage
|
|
18
|
-
|
|
19
|
-
# Specify which files should be added to the gem when it is released.
|
|
20
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
21
|
-
gemspec = File.basename(__FILE__)
|
|
22
|
-
spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
|
|
23
|
-
ls.readlines("\x0", chomp: true).reject do |f|
|
|
24
|
-
(f == gemspec) ||
|
|
25
|
-
f.start_with?(*%w[bin/ Gemfile .gitignore])
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
spec.bindir = "exe"
|
|
29
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) {|f| File.basename(f) }
|
|
30
|
-
spec.require_paths = ["lib"]
|
|
31
|
-
|
|
32
|
-
spec.add_dependency "aws-sdk-s3", ">= 1.0"
|
|
33
|
-
|
|
34
|
-
# For more information and examples about making a new gem, check out our
|
|
35
|
-
# guide at: https://bundler.io/guides/creating_gem.html
|
|
36
|
-
end
|
data/tmp/.keep
DELETED
|
File without changes
|