toy-executable-hooks 1.6.2.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4228b8fc482489f26f465e9343a7f4cf8441c1028f8355a9b4eab920a3305bf9
4
+ data.tar.gz: f9724765c712ad7a708e2df328d684277426dc1e597e82ad5eee411f708c0a57
5
+ SHA512:
6
+ metadata.gz: bbb46a195def1f1d8fbb5498d832d00ebc1fbbfd7df426218d267c0485edbe27b70df9b64f7d52e69ae5fd7bc9534a6515c58378e625994dccc55ca6a79dfdcc
7
+ data.tar.gz: 6e089e4c1fca69a9518ab2621cd918e5f57de5d3a102f2d69aea8459c7ab7e4d1da68987ba97def73ece83ff6227d2ca95a2b06050008982064212b6dfa99256
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .idea
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
data/.travis.yml ADDED
@@ -0,0 +1,47 @@
1
+ language: ruby
2
+ rvm:
3
+ - jruby
4
+ - jruby-head
5
+ - rbx-3
6
+ before_install:
7
+ - 'rvm @global do gem uninstall -a -x rubygems-bundler executable-hooks || true'
8
+ - 'rm -f $(rvm @global do gem env home)/bin/jruby_executable_hooks'
9
+ - 'rm -rf $rvm_path/gems/*/{bin,gems}/rubygems-bundler-* $rvm_path/gems/*/{bin,gems}/executable-hooks-* $rvm_path/gems/*/bin/ruby_*_{wrapper,hooks}'
10
+ - hash -r
11
+ - 'if [[ -n "${WITH_RUBYGEMS:-}" ]] ; then gem update --system "${WITH_RUBYGEMS}" ; fi'
12
+ - gem build executable-hooks.gemspec
13
+ - gem install executable-hooks-$(awk -F'"' '/VERSION/{print $2}' < lib/executable-hooks/version.rb).gem --development
14
+ before_script:
15
+ - unset BUNDLE_GEMFILE
16
+ script: NOEXEC=0 tf --text test-tf${TEST_SUFFIX:-}/*
17
+ notifications:
18
+ irc:
19
+ channels:
20
+ - "irc.freenode.org#rubygems-bundler"
21
+ email:
22
+ recipients:
23
+ - mpapis@gmail.com
24
+ on_failure: change
25
+ matrix:
26
+ fast_finish: true
27
+ include:
28
+ - rvm: 1.8.7
29
+ env: WITH_RUBYGEMS=1.4.2
30
+ - rvm: 1.8.7
31
+ env: WITH_RUBYGEMS=1.6.2
32
+ - rvm: 2.5
33
+ env: TEST_SUFFIX=-bundle
34
+ - rvm: 2.5
35
+ env: TEST_SUFFIX=-truffleruby
36
+ - rvm: 1.8.7
37
+ - rvm: 1.9.2
38
+ - rvm: 1.9.3
39
+ - rvm: 2.0.0
40
+ - rvm: 2.1
41
+ - rvm: 2.2
42
+ - rvm: 2.3
43
+ - rvm: 2.4
44
+ - rvm: 2.5
45
+ - rvm: ruby-head
46
+ allow_failures:
47
+ - rvm: rbx-3
data/CHANGELOG.md ADDED
@@ -0,0 +1,103 @@
1
+ # Changelog
2
+
3
+ ## 1.6.2
4
+ date: 2021-01-26
5
+
6
+ - Converts end_with? to match for Ruby 1.8.6 compatibility #37
7
+
8
+ ## 1.6.1
9
+ date: 2021-01-26
10
+
11
+ - Avoid Ruby 2.7 warning, merge #38
12
+
13
+ ## 1.6.0
14
+ date: 2018-10-25
15
+
16
+ - Restore support for ruby-1.8.6, fixes #34
17
+ - Do not force overwrite wrapper, fixes #33
18
+
19
+ ## 1.5.0
20
+ date: 2018-06-25
21
+
22
+ - Support truffleruby, fixes rvm/rvm#4408
23
+
24
+ ## 1.4.2
25
+ date: 2018-02-14
26
+
27
+ - Support rubygems 1.4.2, fixes #29
28
+
29
+ ## 1.4.1
30
+ date: 2018-02-12
31
+
32
+ - Fix bundle install, fixes #28
33
+
34
+ ## 1.4.0
35
+ date: 2018-02-08
36
+
37
+ - Add bindir support, fixes #24
38
+
39
+ ## 1.3.2
40
+ date: 2014-06-06
41
+
42
+ - make sure executable mode is set on binaries when using fast fix, update wayneeseguin/rvm#2894
43
+
44
+ ## 1.3.1
45
+ date: 2014-01-16
46
+
47
+ - do not hardcode env ruby_executable_hooks when using shortcut try_to_fix_binstubs, fix #12
48
+
49
+ ## 1.3.0
50
+ date: 2014-01-11
51
+
52
+ - First try to fix binstubs before installing them, fix wayneeseguin/rvm#2536
53
+
54
+ ## 1.2.6
55
+ date: 2013-10-21
56
+
57
+ - Remind users about regenerating binstubs "in case of problems", merge #11
58
+
59
+ ## 1.2.5
60
+ date: 2013-10-12
61
+
62
+ - first try to create the bin dir then check if it is writable, update #9, update wayneeseguin/rvm#2277
63
+
64
+ ## 1.2.4
65
+ date: 2013-10-10
66
+
67
+ - raise exception if can not write to bindir, fix #9
68
+
69
+ ## 1.2.3
70
+ date: 2013-09-24
71
+
72
+ - fix detecting program name and system process title, fix #8, update #7, update #5
73
+
74
+ ## 1.2.2
75
+ date: 2013-09-23
76
+
77
+ - change process title only when supported by Process, fix #7, update #5
78
+
79
+ ## 1.2.1
80
+ date: 2013-09-22
81
+
82
+ - fix installing wrapper when first time installing the gem, fix #6
83
+
84
+ ## 1.2.0
85
+ date: 2013-09-17
86
+
87
+ - fix full program name with params, fix #5
88
+ - RG 2.1 introduces find_latest_files
89
+ - add license to gemspec, fix #4
90
+
91
+ ## 1.1.0
92
+ date: 2013-07-11
93
+
94
+ - fix hooks for older rubygems versions
95
+ - add regenerating wrappers on gem installation, closes #2
96
+ - fix uninstaller
97
+ - honor the program suffix, fix #3
98
+ - add a warning for custom custom_shebang, fix #1
99
+
100
+ ## 1.0.0
101
+ date: 2013-07-10
102
+
103
+ - extracted hooking to rubygems executables from https://github.com/mpapis/rubygems-bundler
data/DEVELOPMENT.md ADDED
@@ -0,0 +1,11 @@
1
+ # Releasing
2
+
3
+ - update `lib/executable-hooks/version.rb` with new version (use semantic versioning)
4
+ - update `CHANGELOG.md` with changes relevant to running hooks
5
+ - git commit changes with version as comment
6
+ - git tag version
7
+ - `git push`
8
+ - `git push --tags`
9
+ - use ruby 1.8.7 for releasing `rvm use 1.8.7 --install`
10
+ - `gem build executable-hooks.gemspec`
11
+ - `gem push executable-hooks-1.6.1.gem` - update version
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ #ruby=1.8.7
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2013-2014 Michal Papis
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # Rubygems executable hooks
2
+
3
+ Add next rubygems plugin support for executables.
4
+
5
+ ## Usage
6
+
7
+ Install the gem:
8
+
9
+ gem install executable-hooks
10
+
11
+ In gem `lib` dir create `rubygems_executable_plugin.rb`:
12
+
13
+ Gem.execute do |original_file|
14
+ warn("Executing: #{original_file}")
15
+ end
16
+
17
+ Generate and install the new gem with executable hook.
18
+
19
+ Now try it:
20
+
21
+ gem install haml
22
+ haml --version
23
+
24
+ Returns:
25
+
26
+ Executing: /home/mpapis/.rvm/gems/ruby-1.8.7-p374-new1/bin/haml
27
+ Haml 4.0.3
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'executable-hooks/uninstaller'
4
+
5
+ ExecutableHooks.uninstall
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ title = "ruby #{ARGV*" "}"
4
+ $0 = ARGV.shift
5
+ Process.setproctitle(title) if Process.methods.include?(:setproctitle)
6
+
7
+ require 'rubygems'
8
+ begin
9
+ require 'executable-hooks/hooks'
10
+ Gem::ExecutableHooks.run($0)
11
+ rescue LoadError
12
+ warn "unable to load executable-hooks/hooks" if ENV.key?('ExecutableHooks_DEBUG')
13
+ end unless $0.match(/\/executable-hooks-uninstaller$/)
14
+
15
+ content = File.read($0)
16
+
17
+ if (index = content.index("\n#!ruby\n")) && index > 0
18
+ skipped_content = content.slice!(0..index)
19
+ start_line = skipped_content.count("\n") + 1
20
+ eval content, binding, $0, start_line
21
+ else
22
+ eval content, binding, $0
23
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding: utf-8 -*-
3
+
4
+ Kernel.load(File.expand_path("../lib/executable-hooks/version.rb", __FILE__))
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "toy-executable-hooks"
8
+ s.version = ExecutableHooks::VERSION
9
+ s.license = 'Apache 2.0'
10
+ s.authors = ["Michal Papis"]
11
+ s.email = ["mpapis@gmail.com"]
12
+ s.homepage = "https://github.com/rvm/executable-hooks"
13
+ s.summary = %q{
14
+ Hook into rubygems executables allowing extra actions to be taken before executable is run.
15
+ }
16
+ s.post_install_message = <<-MESSAGE
17
+ # In case of problems run the following command to update binstubs:
18
+ gem regenerate_binstubs
19
+ MESSAGE
20
+
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.extensions = %w( ext/wrapper_installer/extconf.rb )
25
+ s.executables = %w( executable-hooks-uninstaller )
26
+
27
+ s.add_development_dependency "tf", "~>0.4"
28
+ end
@@ -0,0 +1,25 @@
1
+ # Fake building extension
2
+ File.open('Makefile', 'w') { |f| f.write("all:\n\ninstall:\n\n") }
3
+ File.open('make', 'w') do |f|
4
+ f.write('#!/bin/sh')
5
+ f.chmod(f.stat.mode | 0111)
6
+ end
7
+ File.open('wrapper_installer.so', 'w') {}
8
+ File.open('wrapper_installer.dll', 'w') {}
9
+ File.open('nmake.bat', 'w') { |f| }
10
+
11
+
12
+ # add the gem to load path
13
+ $: << File.expand_path("../../../lib", __FILE__)
14
+ # load the actions
15
+ require 'executable-hooks/wrapper'
16
+ require 'executable-hooks/regenerate_binstubs_command'
17
+ # call the actions
18
+ options = RegenerateBinstubsCommand.default_install_options
19
+ ExecutableHooks::Wrapper.new(options).install_from(File.expand_path("../../..", __FILE__))
20
+ RegenerateBinstubsCommand.new.execute_no_wrapper
21
+ # unload the path, what was required stays ... but there is that much we can do
22
+ $:.pop
23
+
24
+ # just in case - it worked
25
+ true
@@ -0,0 +1,54 @@
1
+ module Gem
2
+ @executables_hooks ||= []
3
+
4
+ class << self
5
+ unless method_defined?(:execute)
6
+ def execute(&hook)
7
+ @executables_hooks << hook
8
+ end
9
+
10
+ attr_reader :executables_hooks
11
+ end
12
+
13
+ unless method_defined?(:load_executable_plugins)
14
+ def load_executable_plugins
15
+ if ENV['RUBYGEMS_LOAD_ALL_PLUGINS']
16
+ load_plugin_files find_files('rubygems_executable_plugin', false)
17
+ else
18
+ begin
19
+ load_plugin_files find_latest_files('rubygems_executable_plugin', false)
20
+ rescue NoMethodError
21
+ load_plugin_files find_files('rubygems_executable_plugin', false)
22
+ end
23
+ end
24
+ rescue ArgumentError, NoMethodError
25
+ # old rubygems
26
+ plugins = find_files('rubygems_executable_plugin')
27
+
28
+ plugins.each do |plugin|
29
+
30
+ # Skip older versions of the GemCutter plugin: Its commands are in
31
+ # RubyGems proper now.
32
+
33
+ next if plugin =~ /gemcutter-0\.[0-3]/
34
+
35
+ begin
36
+ load plugin
37
+ rescue ::Exception => e
38
+ details = "#{plugin.inspect}: #{e.message} (#{e.class})"
39
+ warn "Error loading RubyGems plugin #{details}"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ class ExecutableHooks
47
+ def self.run(original_file)
48
+ Gem.load_executable_plugins
49
+ Gem.executables_hooks.each do |hook|
50
+ hook.call(original_file)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,100 @@
1
+ module ExecutableHooksInstaller
2
+ # Iterate through executables and generate wrapper for each one,
3
+ # extract of rubygems code
4
+ def self.bundler_generate_bin(inst)
5
+ return if inst.spec.executables.nil?
6
+ executables = inst.spec.executables.reject{ |name| name == 'executable-hooks-uninstaller' }
7
+ return if executables.empty?
8
+ bindir = inst.bin_dir ? inst.bin_dir : Gem.bindir(inst.gem_home)
9
+ executables.each do |filename|
10
+ filename.untaint
11
+ original = File.join bindir, filename
12
+ if File.exists?( original )
13
+ bin_script_path = File.join bindir, inst.formatted_program_filename(filename)
14
+ FileUtils.rm_f bin_script_path
15
+ File.open bin_script_path, 'wb', 0755 do |file|
16
+ file.print bundler_app_script_text(inst, filename)
17
+ end
18
+ inst.say bin_script_path if Gem.configuration.really_verbose
19
+ else
20
+ inst.say "Can not find #{inst.spec.name} in GEM_PATH"
21
+ break
22
+ end
23
+ end
24
+ end
25
+
26
+
27
+ def self.shebang(inst, bin_file_name)
28
+ # options were defined first in 1.5, we want to support back to 1.3.7
29
+ ruby_name = Gem::ConfigMap[:ruby_install_name] if inst.instance_variable_get(:@env_shebang)
30
+ bindir = inst.bin_dir ? inst.bin_dir : Gem.bindir(inst.gem_home)
31
+ path = File.join bindir, inst.formatted_program_filename(bin_file_name)
32
+ first_line = File.open(path, "rb") {|file| file.gets}
33
+
34
+ if /\A#!/ =~ first_line then
35
+ # Preserve extra words on shebang line, like "-w". Thanks RPA.
36
+ shebang = first_line.sub(/\A\#!.*?ruby\S*((\s+\S+)+)/, "#!#{Gem.ruby}")
37
+ opts = $1
38
+ shebang.strip! # Avoid nasty ^M issues.
39
+ end
40
+
41
+ if which = Gem.configuration[:custom_shebang]
42
+ which = which.gsub(/\$(\w+)/) do
43
+ case $1
44
+ when "env"
45
+ env_path
46
+ when "ruby"
47
+ "#{Gem.ruby}#{opts}"
48
+ when "exec"
49
+ bin_file_name
50
+ when "name"
51
+ inst.spec.name
52
+ end
53
+ end
54
+
55
+ return "#!#{which}"
56
+ end
57
+
58
+ if not ruby_name then
59
+ "#!#{Gem.ruby}#{opts}"
60
+ elsif opts then
61
+ "#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
62
+ else
63
+ "#!#{env_path} #{ruby_name}"
64
+ end
65
+ end
66
+
67
+ def self.env_path
68
+ @env_path ||= Gem::Installer::ENV_PATHS.find {|path| File.executable?(path) }
69
+ end
70
+
71
+ # Return the text for an application file.
72
+ def self.bundler_app_script_text(inst, bin_file_name)
73
+ <<-TEXT
74
+ #{shebang(inst, bin_file_name)}
75
+ #
76
+ # This file was generated by RubyGems.
77
+ #
78
+ # The application '#{inst.spec.name}' is installed as part of a gem, and
79
+ # this file is here to facilitate running it.
80
+ #
81
+
82
+ require 'rubygems'
83
+
84
+ version = "#{Gem::Requirement.default}"
85
+
86
+ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
87
+ version = $1
88
+ ARGV.shift
89
+ end
90
+
91
+ gem '#{inst.spec.name}', version
92
+ load Gem.bin_path('#{inst.spec.name}', '#{bin_file_name}', version)
93
+ TEXT
94
+ end
95
+
96
+ end
97
+
98
+ Gem.post_install do |inst|
99
+ ExecutableHooksInstaller.bundler_generate_bin(inst)
100
+ end
@@ -0,0 +1,154 @@
1
+ require 'rubygems/command_manager'
2
+ require 'rubygems/installer'
3
+ require 'rubygems/version'
4
+ require 'executable-hooks/wrapper'
5
+
6
+ class RegenerateBinstubsCommand < Gem::Command
7
+ def self.default_install_options
8
+ require 'rubygems/commands/install_command'
9
+ Gem::Command.extra_args = Gem.configuration[:gem]
10
+ config_args = Gem.configuration[:install]
11
+ config_args =
12
+ case config_args
13
+ when String
14
+ config_args.split ' '
15
+ else
16
+ Array(config_args)
17
+ end
18
+ Gem::Command.add_specific_extra_args 'install', config_args
19
+ ic = Gem::Commands::InstallCommand.new
20
+ ic.handle_options ["install"]
21
+ ic.options
22
+ end
23
+
24
+ def initialize
25
+ super 'regenerate_binstubs', 'Re run generation of executable wrappers for gems.'
26
+
27
+ add_option(:"Install/Update", '-i', '--install-dir DIR',
28
+ 'Gem repository directory to get installed',
29
+ 'gems') do |value, options|
30
+ options[:install_dir] = File.expand_path(value)
31
+ end
32
+
33
+ add_option(:"Install/Update", '-n', '--bindir DIR',
34
+ 'Directory where binary files are',
35
+ 'located') do |value, options|
36
+ options[:bin_dir] = File.expand_path(value)
37
+ end
38
+ end
39
+
40
+ def arguments # :nodoc:
41
+ "STRING start of gem name to regenerate binstubs"
42
+ end
43
+
44
+ def usage # :nodoc:
45
+ "#{program_name} [STRING]"
46
+ end
47
+
48
+ def defaults_str # :nodoc:
49
+ ""
50
+ end
51
+
52
+ def description # :nodoc:
53
+ 'Re run generation of executable wrappers for all gems. '+
54
+ 'Wrappers will be compatible with both rubygems and bundler. '+
55
+ 'The switcher is BUNDLE_GEMFILE environment variable, '+
56
+ 'when set it switches to bundler mode, when not set, '+
57
+ 'then the command will work as it was with pure rubygems.'
58
+ end
59
+
60
+ def execute
61
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('2.0.0') then
62
+ # https://github.com/rubygems/rubygems/issues/326
63
+ puts "try also: gem pristine --binstubs"
64
+ end
65
+ ExecutableHooks::Wrapper.new(options).install
66
+ execute_no_wrapper
67
+ end
68
+
69
+ def execute_no_wrapper(wrapper_name = ExecutableHooks::Wrapper.expanded_wrapper_name)
70
+ require 'executable-hooks/installer'
71
+ name = get_one_optional_argument || ''
72
+ specs = installed_gems.select{|spec| spec.name =~ /^#{name}/i }
73
+ specs.each do |spec|
74
+ executables = spec.executables.reject{ |name| name == 'executable-hooks-uninstaller' }
75
+ unless executables.empty?
76
+ try_to_fix_binstubs(spec, executables, wrapper_name) or
77
+ try_to_install_binstubs(spec) or
78
+ $stderr.puts "##{spec.name} #{spec.version} not found in GEM_PATH"
79
+ end
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def try_to_fix_binstubs(spec, executables, wrapper_name)
86
+ executable_paths =
87
+ executables.map do |executable|
88
+ path = expanded_bin_paths.detect{|bin_path| File.exist?(File.join(bin_path, executable)) }
89
+ File.join(path, executable) if path
90
+ end
91
+ return false if executable_paths.include?(nil) # not found
92
+ executable_shebangs =
93
+ executable_paths.map do |path|
94
+ [path, File.readlines(path).map{|l|l.chomp}]
95
+ end
96
+ return false if executable_shebangs.detect{|path, lines| !(lines[0] =~ /^#!\//) }
97
+ puts "#{spec.name} #{spec.version}"
98
+ executable_mode = 0111
99
+ executable_shebangs.map do |path, lines|
100
+ lines[0] = "#!#{ExecutableHooksInstaller.env_path} #{wrapper_name}"
101
+ File.open(path, "w") do |file|
102
+ file.puts(lines)
103
+ end
104
+ mode = File.stat(path).mode
105
+ File.chmod(mode | executable_mode, path) if mode & executable_mode != executable_mode
106
+ end
107
+ end
108
+
109
+ def expanded_bin_paths
110
+ @expanded_bin_paths ||= begin
111
+ paths = expanded_gem_paths.map{|path| File.join(path, "bin") }
112
+ paths << RbConfig::CONFIG["bindir"]
113
+ # TODO: bindir from options?
114
+ paths
115
+ end
116
+ end
117
+
118
+ def try_to_install_binstubs(spec)
119
+ org_gem_path = options[:install_dir] || existing_gem_path(spec.full_name) || Gem.dir
120
+ cache_gem = File.join(org_gem_path, 'cache', spec.file_name)
121
+ if File.exist? cache_gem
122
+ puts "#{spec.name} #{spec.version}"
123
+ installer_method = Gem::Installer.respond_to?(:at) ? :at : :new
124
+ inst = Gem::Installer.public_send installer_method, Dir[cache_gem].first, :wrappers => true, :force => true, :install_dir => org_gem_path, :bin_dir => options[:bin_dir]
125
+ ExecutableHooksInstaller.bundler_generate_bin(inst)
126
+ else
127
+ false
128
+ end
129
+ end
130
+
131
+ def existing_gem_path(full_name)
132
+ expanded_gem_paths.find{|path| File.exists?(File.join(path, 'gems', full_name))}
133
+ end
134
+
135
+ def expanded_gem_paths
136
+ @expanded_gem_paths ||=
137
+ Gem.path.map do |path|
138
+ paths = [path]
139
+ while File.symlink?(path)
140
+ path = File.readlink(path)
141
+ paths << path
142
+ end
143
+ paths
144
+ end.flatten
145
+ end
146
+
147
+ def installed_gems
148
+ if Gem::VERSION > '1.8' then
149
+ Gem::Specification.to_a
150
+ else
151
+ Gem.source_index.map{|name,spec| spec}
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,17 @@
1
+ module ExecutableHooks
2
+ module Specification
3
+ def self.find
4
+ @executable_hooks_spec ||=
5
+ if Gem::Specification.respond_to?(:find_by_name)
6
+ Gem::Specification.find_by_name("executable-hooks", ">=0", ">=0.alpha")
7
+ else
8
+ Gem.source_index.find_name("executable-hooks").last
9
+ end
10
+ rescue Gem::LoadError
11
+ nil
12
+ end
13
+ def self.version
14
+ find ? find.version.to_s : nil
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ require 'executable-hooks/wrapper'
2
+ require 'executable-hooks/regenerate_binstubs_command'
3
+ require 'rubygems/uninstaller'
4
+
5
+ module ExecutableHooks
6
+ def self.uninstall
7
+ Gem.configuration[:custom_shebang] = "$env #{Gem.default_exec_format % "ruby"}"
8
+ options = RegenerateBinstubsCommand.default_install_options
9
+ RegenerateBinstubsCommand.new.execute_no_wrapper("ruby")
10
+ ExecutableHooks::Wrapper.new(options).uninstall
11
+ options.merge!(:executables => true, :all => true, :ignore => true)
12
+ Gem::Uninstaller.new("executable-hooks", options).uninstall
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module ExecutableHooks
2
+ VERSION = "1.6.2.1"
3
+ end
@@ -0,0 +1,85 @@
1
+ # install / uninstall wrapper
2
+ require 'fileutils'
3
+ require 'rubygems'
4
+ require 'executable-hooks/specification'
5
+
6
+ module ExecutableHooks
7
+ class Wrapper
8
+ def self.wrapper_name
9
+ 'ruby_executable_hooks'
10
+ end
11
+
12
+ def self.expanded_wrapper_name
13
+ Gem.default_exec_format % self.wrapper_name
14
+ end
15
+
16
+ attr_reader :options
17
+
18
+ def initialize(options)
19
+ @options = options || RegenerateBinstubsCommand.default_install_options
20
+ end
21
+
22
+ def install
23
+ @bindir = options[:bin_dir] if options[:bin_dir]
24
+ ensure_custom_shebang
25
+
26
+ executable_hooks_spec = ExecutableHooks::Specification.find
27
+
28
+ if executable_hooks_spec
29
+ install_from( executable_hooks_spec.full_gem_path )
30
+ end
31
+ end
32
+
33
+ def install_from(full_gem_path)
34
+ wrapper_path = File.expand_path( "bin/#{self.class.wrapper_name}", full_gem_path )
35
+ bindir = calculate_bindir(options)
36
+ destination = calculate_destination(bindir)
37
+
38
+ if File.exist?(wrapper_path) && !same_file(wrapper_path, destination)
39
+ FileUtils.mkdir_p(bindir) unless File.exist?(bindir)
40
+ # exception based on Gem::Installer.generate_bin
41
+ raise Gem::FilePermissionError.new(bindir) unless File.writable?(bindir)
42
+ FileUtils.cp(wrapper_path, destination)
43
+ File.chmod(0775, destination)
44
+ end
45
+ end
46
+
47
+ def same_file(file1, file2)
48
+ File.exist?(file1) && File.exist?(file2) &&
49
+ File.read(file1) == File.read(file2)
50
+ end
51
+ private :same_file
52
+
53
+ def uninstall
54
+ destination = calculate_destination(calculate_bindir(options))
55
+ FileUtils.rm_f(destination) if File.exist?(destination)
56
+ end
57
+
58
+ def calculate_bindir(options)
59
+ return options[:bin_dir] if options[:bin_dir]
60
+ Gem.respond_to?(:bindir,true) ? Gem.send(:bindir) : File.join(Gem.dir, 'bin')
61
+ end
62
+
63
+ def calculate_destination(bindir)
64
+ File.expand_path(self.class.expanded_wrapper_name, bindir)
65
+ end
66
+
67
+
68
+ def ensure_custom_shebang
69
+ expected_shebang = "$env #{self.class.expanded_wrapper_name}"
70
+
71
+ Gem.configuration[:custom_shebang] ||= expected_shebang
72
+
73
+ if Gem.configuration[:custom_shebang] != expected_shebang
74
+ warn("
75
+ Warning:
76
+ Found custom_shebang: '#{Gem.configuration[:custom_shebang]}',
77
+ Expected custom_shebang: '#{expected_shebang}',
78
+ this can potentially break 'executable-hooks' and gem executables overall!
79
+ Check your '~/.gemrc' and '/etc/gemrc' for 'custom_shebang' and remove it.
80
+ ")
81
+ end
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,3 @@
1
+ Gem.execute do |original_file|
2
+ warn("Executing: #{original_file}") if ENV.key?('ExecutableHooks_DEBUG')
3
+ end
@@ -0,0 +1,29 @@
1
+ # Simulate require_relative - it's required as the plugin can be called in wrong version or from bundler.
2
+ require File.expand_path('../executable-hooks/specification.rb', __FILE__)
3
+
4
+ called_path, called_version = __FILE__.match(/^(.*\/executable-hooks-([^\/]+)\/lib).*$/)[1..2]
5
+
6
+ # continue only if loaded and called versions all the same, and not shared gems disabled in bundler
7
+ if
8
+ ( $:.include?(called_path) || ExecutableHooks::Specification.version == called_version ) and
9
+ ( !defined?(Bundler) || ( defined?(Bundler) && Bundler::SharedHelpers.in_bundle? && !Bundler.settings[:disable_shared_gems]) )
10
+
11
+ require 'rubygems/version'
12
+ require 'executable-hooks/wrapper'
13
+
14
+ # Set the custom_shebang if user did not set one
15
+ Gem.pre_install do |gem_installer|
16
+ options = if gem_installer.methods.map{|m|m.to_s}.include?('options')
17
+ gem_installer.options
18
+ end
19
+ ExecutableHooks::Wrapper.new(options).install
20
+ end
21
+
22
+ if Gem::Version.new(Gem::VERSION) < Gem::Version.new('2.0') then
23
+ # Add custom_shebang support to rubygems
24
+ require 'executable-hooks/installer'
25
+ end
26
+
27
+ require 'executable-hooks/regenerate_binstubs_command'
28
+ Gem::CommandManager.instance.register_command :regenerate_binstubs
29
+ end
@@ -0,0 +1,15 @@
1
+ gem install executable-hooks-$(awk -F'"' '/VERSION/{print $2}' < lib/executable-hooks/version.rb).gem --development
2
+ # match=/installed/
3
+ wrapper_name=$(ruby -I ./lib/ -r executable-hooks/wrapper -e "puts ExecutableHooks::Wrapper.expanded_wrapper_name")
4
+
5
+ gem install haml -v "<5" # match=/installed/
6
+ head -n 1 $(which haml ) # match=/ruby_executable_hooks/
7
+ which ${wrapper_name} # status=0
8
+
9
+ gem list # match=/haml/
10
+ executable-hooks-uninstaller # match=/haml/
11
+
12
+ head -n 1 $(which haml) # match!=/ruby_executable_hooks/
13
+ which ${wrapper_name} # status=1
14
+
15
+ gem uninstall -x haml # match=/Successfully uninstalled/
@@ -0,0 +1,20 @@
1
+ gem install executable-hooks-$(awk -F'"' '/VERSION/{print $2}' < lib/executable-hooks/version.rb).gem --development
2
+ # match=/installed/
3
+ gem install rubygems-bundler bundler
4
+ # match=/installed/
5
+ gem install haml -v "4.0.7" # match=/installed/
6
+ # match=/installed/
7
+
8
+ true TMPDIR:${TMPDIR:=/tmp}:
9
+ d=$TMPDIR/test-bundled
10
+ mkdir $d
11
+ pushd $d
12
+
13
+ NOEXEC=1 haml -v # match=/4.0.7/
14
+
15
+ echo -e 'source "https://rubygems.org"\ngem "haml", "4.0.6"' > Gemfile
16
+ bundle install # match=/haml 4.0.6/
17
+ NOEXEC=1 haml -v # match=/4.0.6/
18
+
19
+ popd
20
+ rm -rf $d
@@ -0,0 +1,16 @@
1
+ gem install executable-hooks-$(awk -F'"' '/VERSION/{print $2}' < lib/executable-hooks/version.rb).gem --development
2
+ # match=/installed/
3
+
4
+ gem install haml -v "4.0.7" # match=/installed/
5
+ haml_bin=$(which haml )
6
+ head -n 1 $haml_bin # match=/ruby_executable_hooks/
7
+
8
+ ## simulate truffleruby style binary with shell code mixed in
9
+ ## \043 - is a # ... somehow it breaks tf
10
+ ( head -n 1 $haml_bin; echo -e 'echo $HOME\n\043!ruby'; tail -n +2 $haml_bin ) > $haml_bin.new
11
+ mv $haml_bin.new $haml_bin
12
+ chmod +x $haml_bin
13
+
14
+ haml _4.0.7_ -v # match=/4.0.7/
15
+
16
+ gem uninstall -x haml -v 4.0.7 # match=/Successfully uninstalled/
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: toy-executable-hooks
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.6.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Michal Papis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-01-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tf
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.4'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.4'
27
+ description:
28
+ email:
29
+ - mpapis@gmail.com
30
+ executables:
31
+ - executable-hooks-uninstaller
32
+ extensions:
33
+ - ext/wrapper_installer/extconf.rb
34
+ extra_rdoc_files: []
35
+ files:
36
+ - ".gitignore"
37
+ - ".travis.yml"
38
+ - CHANGELOG.md
39
+ - DEVELOPMENT.md
40
+ - Gemfile
41
+ - LICENSE
42
+ - README.md
43
+ - bin/executable-hooks-uninstaller
44
+ - bin/ruby_executable_hooks
45
+ - executable-hooks.gemspec
46
+ - ext/wrapper_installer/extconf.rb
47
+ - lib/executable-hooks/hooks.rb
48
+ - lib/executable-hooks/installer.rb
49
+ - lib/executable-hooks/regenerate_binstubs_command.rb
50
+ - lib/executable-hooks/specification.rb
51
+ - lib/executable-hooks/uninstaller.rb
52
+ - lib/executable-hooks/version.rb
53
+ - lib/executable-hooks/wrapper.rb
54
+ - lib/rubygems_executable_plugin.rb
55
+ - lib/rubygems_plugin.rb
56
+ - test-tf-bundle/bundle_comment_test.sh
57
+ - test-tf-truffleruby/truffleruby_comment_test.sh
58
+ - test-tf/rubygems_comment_test.sh
59
+ homepage: https://github.com/rvm/executable-hooks
60
+ licenses:
61
+ - Apache 2.0
62
+ metadata: {}
63
+ post_install_message: |
64
+ # In case of problems run the following command to update binstubs:
65
+ gem regenerate_binstubs
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubygems_version: 3.3.26
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Hook into rubygems executables allowing extra actions to be taken before
84
+ executable is run.
85
+ test_files: []