binbundle 1.0.8 → 1.0.10
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/.irbrc +6 -0
- data/.rubocop.yml +9 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile.lock +20 -1
- data/README.md +8 -1
- data/README.rdoc +6 -0
- data/Rakefile +7 -0
- data/bin/binbundle +30 -9
- data/binbundle.gemspec +4 -0
- data/lib/binbundle/gem_bins.rb +100 -31
- data/lib/binbundle/jewel.rb +69 -0
- data/lib/binbundle/jewelry_box.rb +89 -0
- data/lib/binbundle/prompt.rb +1 -1
- data/lib/binbundle/version.rb +3 -1
- data/lib/binbundle.rb +4 -1
- data/src/_README.md +8 -1
- metadata +55 -4
- data/lib/binbundle/gem_list.rb +0 -46
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5004c2ef304f3a5f5fd17c78847d857090408f0e9a1a2bea3ce23553006362bf
|
|
4
|
+
data.tar.gz: c4b5d368b0166251fd6a6e60e46dd867c54901945e0d47d642430b3638bb66d9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 970e55c036810e670b77e276c8da27b98552e4410e1a15741c7d60e7a03a7fd7243ffdb13d7fa64c190c0bd2cf7d59a16f7219a81534131c9a7c8e3971a67aa9
|
|
7
|
+
data.tar.gz: c28dfe8cb48c87f1f1aef43fd3b3e8afb986815297ba13f264aca90880b7b71526df27d1780afeffdb473c3216d0f07a511984bc233ffdf6da2afc0308b53096
|
data/.irbrc
ADDED
data/.rubocop.yml
CHANGED
|
@@ -20,6 +20,12 @@ Layout/LineLength:
|
|
|
20
20
|
Metrics/MethodLength:
|
|
21
21
|
Max: 40
|
|
22
22
|
|
|
23
|
+
Metrics/BlockLength:
|
|
24
|
+
Max: 40
|
|
25
|
+
|
|
26
|
+
Metrics/ClassLength:
|
|
27
|
+
Max: 200
|
|
28
|
+
|
|
23
29
|
Metrics/CyclomaticComplexity:
|
|
24
30
|
Max: 10
|
|
25
31
|
|
|
@@ -28,3 +34,6 @@ Metrics/PerceivedComplexity:
|
|
|
28
34
|
|
|
29
35
|
Metrics/AbcSize:
|
|
30
36
|
Max: 40
|
|
37
|
+
|
|
38
|
+
Metrics/CyclomaticComplexity:
|
|
39
|
+
Max: 15
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
### 1.0.10
|
|
2
|
+
|
|
3
|
+
2024-08-04 06:48
|
|
4
|
+
|
|
5
|
+
#### IMPROVED
|
|
6
|
+
|
|
7
|
+
- Code refactoring, tests
|
|
8
|
+
- More tests, more fixes
|
|
9
|
+
|
|
10
|
+
### 1.0.9
|
|
11
|
+
|
|
12
|
+
2024-08-02 10:42
|
|
13
|
+
|
|
14
|
+
#### NEW
|
|
15
|
+
|
|
16
|
+
- `binbundle gem for BIN` will show what gem is responsible for a binary
|
|
17
|
+
- `binbundle bins for GEM` will show what binaries a gem installs
|
|
18
|
+
|
|
1
19
|
### 1.0.8
|
|
2
20
|
|
|
3
21
|
2024-08-02 09:23
|
data/Gemfile.lock
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
binbundle (1.0.
|
|
4
|
+
binbundle (1.0.10)
|
|
5
5
|
tty-spinner (~> 0.9)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
+
ansi (1.5.0)
|
|
10
11
|
ast (2.4.2)
|
|
11
12
|
diff-lcs (1.5.1)
|
|
13
|
+
docile (1.4.1)
|
|
12
14
|
json (2.7.2)
|
|
13
15
|
language_server-protocol (3.17.0.3)
|
|
14
16
|
parallel (1.25.1)
|
|
@@ -52,13 +54,27 @@ GEM
|
|
|
52
54
|
rubocop-rspec (3.0.3)
|
|
53
55
|
rubocop (~> 1.61)
|
|
54
56
|
ruby-progressbar (1.13.0)
|
|
57
|
+
simplecov (0.22.0)
|
|
58
|
+
docile (~> 1.1)
|
|
59
|
+
simplecov-html (~> 0.11)
|
|
60
|
+
simplecov_json_formatter (~> 0.1)
|
|
61
|
+
simplecov-console (0.9.1)
|
|
62
|
+
ansi
|
|
63
|
+
simplecov
|
|
64
|
+
terminal-table
|
|
65
|
+
simplecov-html (0.12.3)
|
|
66
|
+
simplecov_json_formatter (0.1.4)
|
|
55
67
|
strscan (3.1.0)
|
|
68
|
+
terminal-table (3.0.2)
|
|
69
|
+
unicode-display_width (>= 1.1.1, < 3)
|
|
56
70
|
tty-cursor (0.7.1)
|
|
57
71
|
tty-spinner (0.9.3)
|
|
58
72
|
tty-cursor (~> 0.7)
|
|
59
73
|
unicode-display_width (2.5.0)
|
|
74
|
+
yard (0.9.36)
|
|
60
75
|
|
|
61
76
|
PLATFORMS
|
|
77
|
+
arm64-darwin-20
|
|
62
78
|
x86_64-darwin-20
|
|
63
79
|
|
|
64
80
|
DEPENDENCIES
|
|
@@ -68,6 +84,9 @@ DEPENDENCIES
|
|
|
68
84
|
rubocop (~> 1.21)
|
|
69
85
|
rubocop-rake
|
|
70
86
|
rubocop-rspec
|
|
87
|
+
simplecov (~> 0.21)
|
|
88
|
+
simplecov-console (~> 0.9)
|
|
89
|
+
yard (~> 0.9, >= 0.9.26)
|
|
71
90
|
|
|
72
91
|
BUNDLED WITH
|
|
73
92
|
2.2.29
|
data/README.md
CHANGED
|
@@ -42,13 +42,20 @@ Usage: binbundle [options] [bundle|install]
|
|
|
42
42
|
-s, --sudo Install gems with sudo
|
|
43
43
|
-u, --user-install Use --user-install to install gems
|
|
44
44
|
-f, --file FILE Output to alternative filename (default Binfile)
|
|
45
|
+
-l, --local Use installed gems instead of Binfile for gem_for and bins_for
|
|
45
46
|
-v, --version Display version
|
|
46
47
|
-h, --help Display this screen
|
|
47
48
|
```
|
|
48
49
|
|
|
50
|
+
#### Info commands
|
|
51
|
+
|
|
52
|
+
You can retrieve some basic info about gems and their binaries using `binbundle gem for BIN` or `binbundle bins for GEM`. This will read `Binfile` or any file specified by `--file` and return the requested info, either the gem associated with the given binary (BIN), or the binaries associated with the given gem name (GEM).
|
|
53
|
+
|
|
54
|
+
Use either info command with `--local` to parse installed gems rather than a Binfile.
|
|
55
|
+
|
|
49
56
|
### Recommendations
|
|
50
57
|
|
|
51
|
-
I recommend using Binbundle along with a tool like
|
|
58
|
+
I recommend using Binbundle along with a tool like [Dotbot](https://github.com/anishathalye/dotbot). Commit your bundle to a repo that you can easily clone to a new machine and then make `gem install binbundle` and `binbundle install ~/dotfiles/Binfile` part of your restore process.
|
|
52
59
|
|
|
53
60
|
|
|
54
61
|
### Support
|
data/README.rdoc
ADDED
data/Rakefile
CHANGED
|
@@ -7,6 +7,7 @@ require 'rdoc/task'
|
|
|
7
7
|
require 'bundler/gem_tasks'
|
|
8
8
|
require 'rspec/core/rake_task'
|
|
9
9
|
require 'rubocop/rake_task'
|
|
10
|
+
require 'yard'
|
|
10
11
|
|
|
11
12
|
desc 'Run test suite'
|
|
12
13
|
task test: %i[rubocop spec]
|
|
@@ -26,6 +27,12 @@ Rake::RDocTask.new do |rd|
|
|
|
26
27
|
rd.title = 'binbundle'
|
|
27
28
|
end
|
|
28
29
|
|
|
30
|
+
YARD::Rake::YardocTask.new do |t|
|
|
31
|
+
t.files = ['lib/binbundle/*.rb']
|
|
32
|
+
t.options = ['--markup-provider=redcarpet', '--markup=markdown', '--no-private', '-p', 'yard_templates']
|
|
33
|
+
# t.stats_options = ['--list-undoc']
|
|
34
|
+
end
|
|
35
|
+
|
|
29
36
|
desc 'Development version check'
|
|
30
37
|
task :ver do
|
|
31
38
|
gver = `git ver`
|
data/bin/binbundle
CHANGED
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
require_relative '../lib/binbundle'
|
|
5
5
|
|
|
6
6
|
options = {
|
|
7
|
+
bin_for: nil,
|
|
7
8
|
dry_run: false,
|
|
8
9
|
file: 'Binfile',
|
|
10
|
+
gem_for: nil,
|
|
9
11
|
include_version: true,
|
|
12
|
+
local: false,
|
|
10
13
|
sudo: false,
|
|
11
14
|
user_install: false
|
|
12
15
|
}
|
|
@@ -14,12 +17,20 @@ options = {
|
|
|
14
17
|
optparse = OptionParser.new do |opts|
|
|
15
18
|
opts.banner = "Usage: #{File.basename(__FILE__)} [options] [bundle|install]"
|
|
16
19
|
|
|
17
|
-
opts.on('--
|
|
20
|
+
opts.on('--dry-run', 'Output to STDOUT instead of file') do
|
|
21
|
+
options[:dry_run] = true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
opts.on('-f', '--file FILE', 'Output to alternative filename (default Binfile)') do |opt|
|
|
25
|
+
options[:file] = opt
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
opts.on('--[no-]versions', 'Include version info in output or restore (default true)') do |opt|
|
|
18
29
|
options[:include_version] = opt
|
|
19
30
|
end
|
|
20
31
|
|
|
21
|
-
opts.on('
|
|
22
|
-
options[:
|
|
32
|
+
opts.on('-l', '--local', 'Use installed gems instead of Binfile for gem_for and bins_for') do
|
|
33
|
+
options[:local] = true
|
|
23
34
|
end
|
|
24
35
|
|
|
25
36
|
opts.on('-s', '--sudo', 'Install gems with sudo') do
|
|
@@ -30,10 +41,6 @@ optparse = OptionParser.new do |opts|
|
|
|
30
41
|
options[:user_install] = true
|
|
31
42
|
end
|
|
32
43
|
|
|
33
|
-
opts.on('-f', '--file FILE', 'Output to alternative filename (default Binfile)') do |opt|
|
|
34
|
-
options[:file] = opt
|
|
35
|
-
end
|
|
36
|
-
|
|
37
44
|
opts.on('-v', '--version', 'Display version') do
|
|
38
45
|
puts "#{File.basename(__FILE__)} v#{Binbundle::VERSION}"
|
|
39
46
|
Process.exit 0
|
|
@@ -54,9 +61,23 @@ end
|
|
|
54
61
|
|
|
55
62
|
gb = Binbundle::GemBins.new(options)
|
|
56
63
|
|
|
57
|
-
|
|
64
|
+
if ARGV.count.positive?
|
|
65
|
+
subcommand = ARGV.shift
|
|
66
|
+
params = ARGV.join(' ').sub(/ *for */, '')
|
|
67
|
+
|
|
68
|
+
case subcommand
|
|
69
|
+
when /^(inst|rest)/
|
|
70
|
+
options[:install] = true
|
|
71
|
+
when /^gem/
|
|
72
|
+
options[:gem_for] = params
|
|
73
|
+
when /^bin/
|
|
74
|
+
options[:bin_for] = params
|
|
75
|
+
end
|
|
76
|
+
end
|
|
58
77
|
|
|
59
|
-
if options[:
|
|
78
|
+
if options[:gem_for] || options[:bin_for]
|
|
79
|
+
puts gb.info(options)
|
|
80
|
+
elsif options[:install]
|
|
60
81
|
gb.install
|
|
61
82
|
else
|
|
62
83
|
gb.generate
|
data/binbundle.gemspec
CHANGED
|
@@ -31,5 +31,9 @@ Gem::Specification.new do |s|
|
|
|
31
31
|
s.executables = s.files.grep(%r{\Abin/}) { |f| File.basename(f) }
|
|
32
32
|
s.require_paths = ['lib']
|
|
33
33
|
|
|
34
|
+
s.add_development_dependency 'simplecov', '~> 0.21'
|
|
35
|
+
s.add_development_dependency 'simplecov-console', '~> 0.9'
|
|
36
|
+
s.add_development_dependency 'yard', '~> 0.9', '>= 0.9.26'
|
|
37
|
+
|
|
34
38
|
s.add_runtime_dependency('tty-spinner', '~> 0.9')
|
|
35
39
|
end
|
data/lib/binbundle/gem_bins.rb
CHANGED
|
@@ -3,44 +3,89 @@
|
|
|
3
3
|
module Binbundle
|
|
4
4
|
# Main class
|
|
5
5
|
class GemBins
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
# Get gem for bin :gem_for
|
|
7
|
+
attr_writer :gem_for
|
|
8
|
+
|
|
9
|
+
# Get bins for gem :bin_for
|
|
10
|
+
attr_writer :bin_for
|
|
11
|
+
|
|
12
|
+
# Set options (for testing)
|
|
13
|
+
attr_writer :file, :dry_run
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
## Create a new GemBins object
|
|
17
|
+
##
|
|
18
|
+
## @param options The options
|
|
19
|
+
## @option options [Boolean] :include_version Include version number in output
|
|
20
|
+
## @option options [Boolean] :sudo Include sudo in output
|
|
21
|
+
## @option options [Boolean] :user_install Include --user-install in output
|
|
22
|
+
## @option options [Boolean] :dry_run Output to STDOUT
|
|
23
|
+
## @option options [String] :file File to parse
|
|
24
|
+
## @option options [Boolean] :local Work from local gems instead of Binfile
|
|
25
|
+
##
|
|
10
26
|
def initialize(options = {})
|
|
11
27
|
@include_version = options[:include_version] || false
|
|
12
28
|
@user_install = options[:user_install]
|
|
13
29
|
@sudo = options[:sudo]
|
|
14
30
|
@dry_run = options[:dry_run]
|
|
15
31
|
@file = File.expand_path(options[:file])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
## Retrieve info (bin_for or gem_for)
|
|
36
|
+
##
|
|
37
|
+
## @param options The options
|
|
38
|
+
## @option options [Boolean] :local Work from local gems instead of Binfile
|
|
39
|
+
## @option options [String] :gem_for Find gem for this binary
|
|
40
|
+
## @option options [String] :bin_for Find bins for this gem
|
|
41
|
+
##
|
|
42
|
+
## @return [String] resulting gem or bins
|
|
43
|
+
def info(options)
|
|
44
|
+
unless File.exist?(@file) || options[:local]
|
|
45
|
+
puts "File #{@file} not found"
|
|
46
|
+
Process.exit 1
|
|
47
|
+
end
|
|
16
48
|
|
|
17
|
-
|
|
49
|
+
contents = if options[:local]
|
|
50
|
+
bins_to_s
|
|
51
|
+
else
|
|
52
|
+
IO.read(@file)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
gem_list = JewelryBox.new(contents: contents,
|
|
56
|
+
include_version: @include_version,
|
|
57
|
+
sudo: @sudo,
|
|
58
|
+
user_install: @user_install)
|
|
59
|
+
if options[:gem_for]
|
|
60
|
+
gem_list.gem_for_bin(options[:gem_for])
|
|
61
|
+
elsif options[:bin_for]
|
|
62
|
+
gem_list.bins_for_gem(options[:bin_for])
|
|
63
|
+
end
|
|
18
64
|
end
|
|
19
65
|
|
|
66
|
+
##
|
|
67
|
+
## Install all gems in Binfile
|
|
68
|
+
##
|
|
20
69
|
def install
|
|
21
70
|
unless File.exist?(@file)
|
|
22
71
|
puts "File #{@file} not found"
|
|
23
72
|
Process.exit 1
|
|
24
73
|
end
|
|
25
74
|
|
|
26
|
-
|
|
75
|
+
contents = IO.read(@file)
|
|
76
|
+
lines = JewelryBox.new(contents: contents, include_version: @include_version, sudo: @sudo,
|
|
77
|
+
user_install: @user_install)
|
|
27
78
|
|
|
79
|
+
total = lines.count
|
|
80
|
+
successes = 0
|
|
81
|
+
failures = 0
|
|
82
|
+
res = Prompt.yn("Install #{total} gems from #{File.basename(@file)}", default_response: true)
|
|
28
83
|
Process.exit 0 unless res
|
|
29
84
|
|
|
30
85
|
puts "Installing gems from #{@file}"
|
|
31
86
|
|
|
32
|
-
contents = IO.read(@file)
|
|
33
|
-
gem_list = GemList.new(contents, include_version: @include_version)
|
|
34
|
-
lines = if @sudo
|
|
35
|
-
gem_list.sudo
|
|
36
|
-
elsif @user_install
|
|
37
|
-
gem_list.user_install
|
|
38
|
-
else
|
|
39
|
-
gem_list.normal_install
|
|
40
|
-
end
|
|
41
|
-
|
|
42
87
|
if @dry_run
|
|
43
|
-
puts lines
|
|
88
|
+
puts lines
|
|
44
89
|
Process.exit 0
|
|
45
90
|
end
|
|
46
91
|
|
|
@@ -59,38 +104,40 @@ module Binbundle
|
|
|
59
104
|
result = $CHILD_STATUS.success?
|
|
60
105
|
|
|
61
106
|
if result
|
|
107
|
+
successes += 1
|
|
62
108
|
spinner.success
|
|
63
109
|
spinner.stop
|
|
64
110
|
else
|
|
111
|
+
failures += 1
|
|
65
112
|
spinner.error
|
|
66
113
|
spinner.stop
|
|
67
114
|
@errors << output
|
|
68
115
|
end
|
|
69
116
|
end
|
|
70
117
|
|
|
118
|
+
puts "Total #{total}, installed: #{successes}, #{failures} errors."
|
|
119
|
+
|
|
71
120
|
return if @errors.empty?
|
|
72
121
|
|
|
73
122
|
puts 'ERRORS:'
|
|
74
123
|
puts @errors.join("\n")
|
|
124
|
+
Process.exit 1
|
|
75
125
|
end
|
|
76
126
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
127
|
+
##
|
|
128
|
+
## Output all gems as Binfile format
|
|
129
|
+
##
|
|
130
|
+
## @return [String] Binfile format
|
|
131
|
+
##
|
|
132
|
+
def bins_to_s
|
|
133
|
+
local_gems.map(&:gem_command).join("\n\n")
|
|
82
134
|
end
|
|
83
135
|
|
|
136
|
+
##
|
|
137
|
+
## Output or write Binfile
|
|
138
|
+
##
|
|
84
139
|
def generate
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@local_gems.each do |g, specs|
|
|
88
|
-
versions = specs.map { |spec| spec.version.to_s }
|
|
89
|
-
bins = specs.map(&:executables)
|
|
90
|
-
gems_with_bins[g] = { version: versions.max, bins: bins.sort.uniq }
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
output = gems_with_bins.map { |gem, attrs| gem_command(gem, attrs) }.join("\n\n")
|
|
140
|
+
output = bins_to_s
|
|
94
141
|
|
|
95
142
|
if @dry_run
|
|
96
143
|
puts output
|
|
@@ -99,6 +146,9 @@ module Binbundle
|
|
|
99
146
|
end
|
|
100
147
|
end
|
|
101
148
|
|
|
149
|
+
##
|
|
150
|
+
## Writes to Binfile
|
|
151
|
+
##
|
|
102
152
|
def write_file(output)
|
|
103
153
|
if File.exist?(@file)
|
|
104
154
|
res = Prompt.yn("#{@file} already exists, overwrite", default_response: false)
|
|
@@ -120,5 +170,24 @@ module Binbundle
|
|
|
120
170
|
FileUtils.chmod 0o777, @file
|
|
121
171
|
puts 'Made file executable'
|
|
122
172
|
end
|
|
173
|
+
|
|
174
|
+
private
|
|
175
|
+
|
|
176
|
+
##
|
|
177
|
+
## Find local gems and group by name
|
|
178
|
+
##
|
|
179
|
+
## @return [Array] array of local gems as Hashes
|
|
180
|
+
##
|
|
181
|
+
def local_gems
|
|
182
|
+
gems_with_bins = JewelryBox.new(include_version: @include_version, sudo: @sudo, user_install: @user_install)
|
|
183
|
+
|
|
184
|
+
all = Gem::Specification.sort_by { |g| [g.name.downcase, g.version] }.group_by(&:name)
|
|
185
|
+
all.delete_if { |_, specs| specs.delete_if { |spec| spec.executables.empty? }.empty? }
|
|
186
|
+
all.each do |g, specs|
|
|
187
|
+
gems_with_bins << Jewel.new(g, specs.last.executables.sort.uniq, specs.last.version.to_s)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
gems_with_bins
|
|
191
|
+
end
|
|
123
192
|
end
|
|
124
193
|
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Binbundle
|
|
4
|
+
# String helpers
|
|
5
|
+
class Jewel
|
|
6
|
+
# Include version info in output
|
|
7
|
+
attr_writer :include_version
|
|
8
|
+
|
|
9
|
+
# Include sudo
|
|
10
|
+
attr_writer :sudo
|
|
11
|
+
|
|
12
|
+
# Include --user-install
|
|
13
|
+
attr_writer :user_install
|
|
14
|
+
|
|
15
|
+
# Binaries
|
|
16
|
+
attr_reader :bins
|
|
17
|
+
|
|
18
|
+
# Gem name
|
|
19
|
+
attr_reader :gem
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
## Create a new Jewel object
|
|
23
|
+
##
|
|
24
|
+
## @param gem_name [String] The gem name
|
|
25
|
+
## @param bins [Array|String] The executables
|
|
26
|
+
## @param version [String] The semantic version
|
|
27
|
+
##
|
|
28
|
+
## @return [Jewel] new jewel object
|
|
29
|
+
##
|
|
30
|
+
def initialize(gem_name = '', bins = [], version = nil)
|
|
31
|
+
@gem = gem_name
|
|
32
|
+
@bins = if bins.is_a?(String)
|
|
33
|
+
bins.split(/ *, */)
|
|
34
|
+
else
|
|
35
|
+
bins
|
|
36
|
+
end
|
|
37
|
+
@version = version
|
|
38
|
+
@include_version = true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
## Output Jewel as command
|
|
43
|
+
##
|
|
44
|
+
## @return [String] Command representation of the object.
|
|
45
|
+
##
|
|
46
|
+
def to_s
|
|
47
|
+
version = @include_version && @version ? " -v '#{@version}'" : ''
|
|
48
|
+
if @sudo
|
|
49
|
+
"sudo gem install #{@gem}#{version}"
|
|
50
|
+
elsif @user_install
|
|
51
|
+
"gem install --user-install #{@gem}#{version}"
|
|
52
|
+
else
|
|
53
|
+
"gem install #{@gem}#{version}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
##
|
|
58
|
+
## Output a Binfile-ready version of the Jewel
|
|
59
|
+
##
|
|
60
|
+
## @return [String] Binfile string
|
|
61
|
+
##
|
|
62
|
+
def gem_command
|
|
63
|
+
ver = @include_version ? " -v '#{@version}'" : ''
|
|
64
|
+
ui = @user_install ? '--user-install ' : ''
|
|
65
|
+
sudo = @sudo ? 'sudo ' : ''
|
|
66
|
+
"# Executables: #{@bins.join(', ')}\n#{to_s}"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Binbundle
|
|
4
|
+
# String helpers
|
|
5
|
+
class JewelryBox < Array
|
|
6
|
+
# Include version info in output
|
|
7
|
+
attr_writer :include_version
|
|
8
|
+
|
|
9
|
+
# Include sudo
|
|
10
|
+
attr_writer :sudo
|
|
11
|
+
|
|
12
|
+
# Include --user-install
|
|
13
|
+
attr_writer :user_install
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
## Create a new JewelryBox object
|
|
17
|
+
##
|
|
18
|
+
## @param include_version [Boolean] include version
|
|
19
|
+
## @param sudo [Boolean] include sudo
|
|
20
|
+
## @param user_install [Boolean] include --user-install
|
|
21
|
+
## @param contents [String] The contents to parse
|
|
22
|
+
##
|
|
23
|
+
## @return [JewelryBox] New JewelryBox object
|
|
24
|
+
def initialize(include_version: true, sudo: false, user_install: false, contents: nil)
|
|
25
|
+
@include_version = include_version
|
|
26
|
+
@sudo = sudo
|
|
27
|
+
@user_install = user_install
|
|
28
|
+
|
|
29
|
+
super()
|
|
30
|
+
|
|
31
|
+
return unless contents
|
|
32
|
+
|
|
33
|
+
init_from_contents(contents)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
## Read and parse a Binfile for gems to install
|
|
38
|
+
##
|
|
39
|
+
## @param contents [String] The contents
|
|
40
|
+
##
|
|
41
|
+
def init_from_contents(contents)
|
|
42
|
+
rx = /(?mix)(?:\#\sExecutables:\s(?<bins>[\S\s,]+?)\n)?(?:sudo\s)?gem\sinstall
|
|
43
|
+
\s(?:--user-install\s)?
|
|
44
|
+
(?<gem>\S+)(?:\s(?:-v|--version)\s'(?<version>[0-9.]+)')?/
|
|
45
|
+
contents.to_enum(:scan, rx).map { Regexp.last_match }.each do |m|
|
|
46
|
+
g = Jewel.new(m['gem'], m['bins'], m['version'])
|
|
47
|
+
g.include_version = @include_version
|
|
48
|
+
g.sudo = @sudo
|
|
49
|
+
g.user_install = @user_install
|
|
50
|
+
push(g)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
##
|
|
55
|
+
## Find a gem for a given binary name
|
|
56
|
+
##
|
|
57
|
+
## @param bin [String] The bin to search for
|
|
58
|
+
##
|
|
59
|
+
## @return [String] Associated gem name
|
|
60
|
+
##
|
|
61
|
+
def gem_for_bin(bin)
|
|
62
|
+
m = select { |gem| gem.bins&.include?(bin) }.first
|
|
63
|
+
return "Gem for #{bin} not found" unless m
|
|
64
|
+
|
|
65
|
+
m.gem
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
##
|
|
69
|
+
## List binaries for a given gem name
|
|
70
|
+
##
|
|
71
|
+
## @param gem [String] The gem name to search for
|
|
72
|
+
##
|
|
73
|
+
def bins_for_gem(gem)
|
|
74
|
+
m = select { |g| g.gem == gem }.first
|
|
75
|
+
return "Gem #{gem} not found" unless m
|
|
76
|
+
|
|
77
|
+
m.bins ? m.bins.join(', ') : 'Missing info'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
## Output a Binfile version of the JewelryBox
|
|
82
|
+
##
|
|
83
|
+
## @return [String] String representation of the object.
|
|
84
|
+
##
|
|
85
|
+
def to_s
|
|
86
|
+
map(&:to_s).join("\n")
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
data/lib/binbundle/prompt.rb
CHANGED
data/lib/binbundle/version.rb
CHANGED
data/lib/binbundle.rb
CHANGED
|
@@ -6,10 +6,13 @@ require 'tty-spinner'
|
|
|
6
6
|
require 'english'
|
|
7
7
|
require_relative 'binbundle/version'
|
|
8
8
|
require_relative 'binbundle/prompt'
|
|
9
|
-
require_relative 'binbundle/
|
|
9
|
+
require_relative 'binbundle/jewel'
|
|
10
|
+
require_relative 'binbundle/jewelry_box'
|
|
10
11
|
require_relative 'binbundle/gem_bins'
|
|
11
12
|
|
|
13
|
+
# Parent module
|
|
12
14
|
module Binbundle
|
|
15
|
+
# StandardError class
|
|
13
16
|
class Error < StandardError; end
|
|
14
17
|
# Your code goes here...
|
|
15
18
|
end
|
data/src/_README.md
CHANGED
|
@@ -42,13 +42,20 @@ Usage: binbundle [options] [bundle|install]
|
|
|
42
42
|
-s, --sudo Install gems with sudo
|
|
43
43
|
-u, --user-install Use --user-install to install gems
|
|
44
44
|
-f, --file FILE Output to alternative filename (default Binfile)
|
|
45
|
+
-l, --local Use installed gems instead of Binfile for gem_for and bins_for
|
|
45
46
|
-v, --version Display version
|
|
46
47
|
-h, --help Display this screen
|
|
47
48
|
```
|
|
48
49
|
|
|
50
|
+
#### Info commands
|
|
51
|
+
|
|
52
|
+
You can retrieve some basic info about gems and their binaries using `binbundle gem for BIN` or `binbundle bins for GEM`. This will read `Binfile` or any file specified by `--file` and return the requested info, either the gem associated with the given binary (BIN), or the binaries associated with the given gem name (GEM).
|
|
53
|
+
|
|
54
|
+
Use either info command with `--local` to parse installed gems rather than a Binfile.
|
|
55
|
+
|
|
49
56
|
### Recommendations
|
|
50
57
|
|
|
51
|
-
I recommend using Binbundle along with a tool like
|
|
58
|
+
I recommend using Binbundle along with a tool like [Dotbot](https://github.com/anishathalye/dotbot). Commit your bundle to a repo that you can easily clone to a new machine and then make `gem install binbundle` and `binbundle install ~/dotfiles/Binfile` part of your restore process.
|
|
52
59
|
|
|
53
60
|
<!--GITHUB-->
|
|
54
61
|
### Support
|
metadata
CHANGED
|
@@ -1,15 +1,63 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: binbundle
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brett Terpstra
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-08-
|
|
11
|
+
date: 2024-08-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: simplecov
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.21'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.21'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: simplecov-console
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.9'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.9'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: yard
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0.9'
|
|
48
|
+
- - ">="
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
version: 0.9.26
|
|
51
|
+
type: :development
|
|
52
|
+
prerelease: false
|
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - "~>"
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '0.9'
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 0.9.26
|
|
13
61
|
- !ruby/object:Gem::Dependency
|
|
14
62
|
name: tty-spinner
|
|
15
63
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -33,6 +81,7 @@ executables:
|
|
|
33
81
|
extensions: []
|
|
34
82
|
extra_rdoc_files: []
|
|
35
83
|
files:
|
|
84
|
+
- ".irbrc"
|
|
36
85
|
- ".rspec"
|
|
37
86
|
- ".rubocop.yml"
|
|
38
87
|
- CHANGELOG.md
|
|
@@ -41,12 +90,14 @@ files:
|
|
|
41
90
|
- Gemfile.lock
|
|
42
91
|
- LICENSE.txt
|
|
43
92
|
- README.md
|
|
93
|
+
- README.rdoc
|
|
44
94
|
- Rakefile
|
|
45
95
|
- bin/binbundle
|
|
46
96
|
- binbundle.gemspec
|
|
47
97
|
- lib/binbundle.rb
|
|
48
98
|
- lib/binbundle/gem_bins.rb
|
|
49
|
-
- lib/binbundle/
|
|
99
|
+
- lib/binbundle/jewel.rb
|
|
100
|
+
- lib/binbundle/jewelry_box.rb
|
|
50
101
|
- lib/binbundle/prompt.rb
|
|
51
102
|
- lib/binbundle/version.rb
|
|
52
103
|
- src/_README.md
|
|
@@ -72,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
72
123
|
- !ruby/object:Gem::Version
|
|
73
124
|
version: '0'
|
|
74
125
|
requirements: []
|
|
75
|
-
rubygems_version: 3.2.
|
|
126
|
+
rubygems_version: 3.2.16
|
|
76
127
|
signing_key:
|
|
77
128
|
specification_version: 4
|
|
78
129
|
summary: Bundle all your gem binaries.
|
data/lib/binbundle/gem_list.rb
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Binbundle
|
|
4
|
-
# String helpers
|
|
5
|
-
class GemList
|
|
6
|
-
attr_writer :include_version
|
|
7
|
-
|
|
8
|
-
def initialize(contents, include_version: true)
|
|
9
|
-
@contents = contents
|
|
10
|
-
@include_version = include_version
|
|
11
|
-
@gem_list = gem_list
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def gem_list
|
|
15
|
-
@gem_list ||= @contents.split("\n")
|
|
16
|
-
.delete_if { |line| line.strip.empty? || line =~ /^#/ }
|
|
17
|
-
.each_with_object([]) do |l, arr|
|
|
18
|
-
rx = /^(?x)(?:sudo\s)?gem\sinstall\s(?:--user-install\s)?
|
|
19
|
-
(?<gem>\S+)(?:\s(?:-v|--version)\s'(?<version>[0-9.]+)')?/
|
|
20
|
-
m = l.match(rx)
|
|
21
|
-
arr << { gem: m['gem'], version: m['version'] }
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def sudo
|
|
26
|
-
@gem_list.map do |gem|
|
|
27
|
-
version = @include_version && gem[:version] ? " -v '#{gem[:version]}'" : ''
|
|
28
|
-
"sudo gem install #{gem[:gem]}#{version}"
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def user_install
|
|
33
|
-
@gem_list.map do |gem|
|
|
34
|
-
version = @include_version && gem[:version] ? " -v '#{gem[:version]}'" : ''
|
|
35
|
-
"gem install --user-install #{gem[:gem]}#{version}"
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def normal_install
|
|
40
|
-
@gem_list.map do |gem|
|
|
41
|
-
version = @include_version && gem[:version] ? " -v '#{gem[:version]}'" : ''
|
|
42
|
-
"gem install #{gem[:gem]}#{version}"
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|