bundler-source-pathext 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +20 -0
- data/LICENSE +28 -0
- data/README.md +24 -0
- data/Rakefile +2 -0
- data/bundler-source-pathext.gemspec +21 -0
- data/lib/bundler-source-pathext/version.rb +3 -0
- data/lib/bundler-source-pathext.rb +166 -0
- data/plugins.rb +2 -0
- metadata +52 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: fe992635560597c121fa90491f6501471dedddf344d497cfa87f4c512e51deb8
|
|
4
|
+
data.tar.gz: afd9e49a4916dbf8b9ec52505ef19fee11de8052716d94411a15e3961f93e628
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: eafc5e0d6fd8e7ff002ed82cc766332ec1b9e371fa596bc20f9877625a8feb5afc28160f5a698eedc85d8c9c6281e9c52e7fbb78cf18d0727c5791fc7788265d
|
|
7
|
+
data.tar.gz: c89d33b02882c2bb025e16a097cf48940ed86c7f0ce653bf4422e3bdf08d49db6dea1e885dc7c2062d261b8fab8932c0c0972d7d239f1712d58254a969c8b3ed
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
bundler-source-pathext (0.2.0)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
rake (12.3.3)
|
|
10
|
+
|
|
11
|
+
PLATFORMS
|
|
12
|
+
arm64-darwin-24
|
|
13
|
+
x86_64-darwin-17
|
|
14
|
+
|
|
15
|
+
DEPENDENCIES
|
|
16
|
+
bundler-source-pathext!
|
|
17
|
+
rake (~> 12.0)
|
|
18
|
+
|
|
19
|
+
BUNDLED WITH
|
|
20
|
+
2.2.3
|
data/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Copyright (c) 2026, pganalyze Team <team@pganalyze.com>
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
8
|
+
list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
|
12
|
+
and/or other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
* Neither the name of pganalyze nor the names of its contributors may be used
|
|
15
|
+
to endorse or promote products derived from this software without specific
|
|
16
|
+
prior written permission.
|
|
17
|
+
|
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
19
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
20
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
21
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
22
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
23
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
24
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
25
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
26
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
27
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
28
|
+
POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# bundle-source-pathext [ ](https://rubygems.org/gems/bundle-source-pathext) [ ](https://rubygems.org/gems/bundle-source-pathext)
|
|
2
|
+
|
|
3
|
+
This bundler plugin allows building local Ruby extensions that are referred to by a local path, similar to how gems are built when they are fetched from a remote path.
|
|
4
|
+
|
|
5
|
+
Rubygems/Bundler itself unfortunately does not build local extensions automatically, making workflows complicated that utilize gems with an extension build, as part of an application.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
In your Gemfile, replace something like `gem 'mygem', path: './folder` with:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
source './folder', type: 'pathext' do
|
|
13
|
+
gem 'mygem'
|
|
14
|
+
end
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Different from Rubygems, this plugin will prefer `rake compile` when an extension has a Rakefile, only falling back to the [Gem::Ext::Builder](https://github.com/ruby/rubygems/blob/master/lib/rubygems/ext/builder.rb) (or [other builders](https://github.com/ruby/rubygems/blob/master/lib/rubygems/ext/builder.rb#L173)) if needed. This is aimed at making debugging easier.
|
|
18
|
+
|
|
19
|
+
## LICENSE
|
|
20
|
+
|
|
21
|
+
Licensed under the 3-clause BSD license, see LICENSE file for details.
|
|
22
|
+
|
|
23
|
+
Copyright (c) 2026, pganalyze Team <team@pganalyze.com>
|
|
24
|
+
All rights reserved.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative 'lib/bundler-source-pathext/version'
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |spec|
|
|
4
|
+
spec.name = "bundler-source-pathext"
|
|
5
|
+
spec.version = BundlerSourcePathext::VERSION
|
|
6
|
+
spec.authors = ["pganalyze Team"]
|
|
7
|
+
spec.email = ["team@pganalyze.com"]
|
|
8
|
+
|
|
9
|
+
spec.summary = ''
|
|
10
|
+
spec.description = ''
|
|
11
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
|
12
|
+
|
|
13
|
+
# Specify which files should be added to the gem when it is released.
|
|
14
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
15
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
16
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
17
|
+
end
|
|
18
|
+
spec.bindir = "exe"
|
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
20
|
+
spec.require_paths = ["lib"]
|
|
21
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
require "bundler-source-pathext/version"
|
|
2
|
+
|
|
3
|
+
class BundlerSourcePathext < Bundler::Plugin::API
|
|
4
|
+
class PathExtSource < Bundler::Source#Bundler::Source::Path
|
|
5
|
+
def install(spec, opts)
|
|
6
|
+
print_using_message "Using #{spec.name} #{spec.version} from #{self}"
|
|
7
|
+
|
|
8
|
+
using_message = "Using #{version_message(spec, options[:previous_spec])} from #{self}"
|
|
9
|
+
using_message += " and installing its executables" unless spec.executables.empty?
|
|
10
|
+
print_using_message using_message
|
|
11
|
+
generate_bin(spec, disable_extensions: true) # Turned off!
|
|
12
|
+
|
|
13
|
+
build_local_extensions(spec)
|
|
14
|
+
|
|
15
|
+
nil # no post-install message
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Bundler plugin api, we need to return a Bundler::Index
|
|
19
|
+
def specs
|
|
20
|
+
files = Dir.glob(File.join(File.expand_path(uri), '*.gemspec'))
|
|
21
|
+
|
|
22
|
+
Bundler::Index.build do |index|
|
|
23
|
+
files.each do |file|
|
|
24
|
+
next unless spec = Bundler.load_gemspec(file)
|
|
25
|
+
spec.installed_by_version = Gem::VERSION
|
|
26
|
+
spec.source = self
|
|
27
|
+
spec.extension_dir = File.join(File.dirname(file), 'tmp', RUBY_PLATFORM, spec.name, RUBY_VERSION)
|
|
28
|
+
Bundler.rubygems.validate(spec)
|
|
29
|
+
|
|
30
|
+
index << spec
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Set internal representation to fetch the gems/specs locally.
|
|
36
|
+
#
|
|
37
|
+
# When this is called, the source should try to fetch the specs and
|
|
38
|
+
# install from the local system.
|
|
39
|
+
def local!
|
|
40
|
+
# not applicable
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Set internal representation to fetch the gems/specs from remote.
|
|
44
|
+
#
|
|
45
|
+
# When this is called, the source should try to fetch the specs and
|
|
46
|
+
# install from remote path.
|
|
47
|
+
def remote!
|
|
48
|
+
# not applicable
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Set internal representation to fetch the gems/specs from app cache.
|
|
52
|
+
#
|
|
53
|
+
# When this is called, the source should try to fetch the specs and
|
|
54
|
+
# install from the path provided by `app_cache_path`.
|
|
55
|
+
def cached!
|
|
56
|
+
# not applicable
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# This is called to update the spec and installation.
|
|
60
|
+
#
|
|
61
|
+
# If the source plugin is loaded from lockfile or otherwise, it shall
|
|
62
|
+
# refresh the cache/specs (e.g. git sources can make a fresh clone).
|
|
63
|
+
def unlock!
|
|
64
|
+
# not applicable
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def build_local_extensions(spec)
|
|
70
|
+
build_args = options[:build_args] || Bundler.rubygems.build_args || begin
|
|
71
|
+
require_relative "command"
|
|
72
|
+
Gem::Command.build_args
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
builder = Gem::Ext::Builder.new spec, build_args
|
|
76
|
+
|
|
77
|
+
build_extensions(spec, build_args, builder)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def build_extensions(spec, build_args, builder)
|
|
81
|
+
return if spec.extensions.empty?
|
|
82
|
+
|
|
83
|
+
if build_args.empty?
|
|
84
|
+
puts "Building native extensions for #{spec.name}. This could take a while..."
|
|
85
|
+
else
|
|
86
|
+
puts "Building native extensions for #{spec.name} with: '#{@build_args.join " "}'"
|
|
87
|
+
puts "This could take a while..."
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
dest_path = spec.extension_dir
|
|
91
|
+
start = Time.now
|
|
92
|
+
load_dir = File.dirname(spec.loaded_from)
|
|
93
|
+
|
|
94
|
+
success = true
|
|
95
|
+
spec.extensions.each do |extension|
|
|
96
|
+
if extension[/extconf/] && File.exist?(File.join(load_dir, 'Rakefile'))
|
|
97
|
+
rake_args = ['compile']
|
|
98
|
+
builder.class.run(rake + rake_args, [], 'rake compile (via ' + self.class.to_s + ')', load_dir) do |status, results|
|
|
99
|
+
unless status.success?
|
|
100
|
+
success = false
|
|
101
|
+
puts results
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
else
|
|
105
|
+
builder.build_extension extension, dest_path
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
puts format(' Finished after %0.2f seconds', Time.now - start)
|
|
109
|
+
FileUtils.touch(spec.gem_build_complete_path) if success
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def rake
|
|
113
|
+
rake = ENV["rake"]
|
|
114
|
+
|
|
115
|
+
if rake
|
|
116
|
+
rake = Shellwords.split(rake)
|
|
117
|
+
else
|
|
118
|
+
begin
|
|
119
|
+
rake = Gem::Ext::Builder.ruby << "-rrubygems" << Gem.bin_path("rake", "rake")
|
|
120
|
+
rescue Gem::Exception
|
|
121
|
+
rake = [Gem.default_exec_format % "rake"]
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
rake
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def generate_bin(spec, options = {})
|
|
128
|
+
gem_dir = Pathname.new(spec.full_gem_path)
|
|
129
|
+
|
|
130
|
+
# Some gem authors put absolute paths in their gemspec
|
|
131
|
+
# and we have to save them from themselves
|
|
132
|
+
spec.files = spec.files.filter_map do |path|
|
|
133
|
+
next path unless /\A#{Pathname::SEPARATOR_PAT}/o.match?(path)
|
|
134
|
+
next if File.directory?(path)
|
|
135
|
+
begin
|
|
136
|
+
Pathname.new(path).relative_path_from(gem_dir).to_s
|
|
137
|
+
rescue ArgumentError
|
|
138
|
+
path
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
installer = Path::Installer.new(
|
|
143
|
+
spec,
|
|
144
|
+
env_shebang: false,
|
|
145
|
+
disable_extensions: options[:disable_extensions],
|
|
146
|
+
build_args: options[:build_args],
|
|
147
|
+
bundler_extension_cache_path: extension_cache_path(spec)
|
|
148
|
+
)
|
|
149
|
+
installer.post_install
|
|
150
|
+
rescue Gem::InvalidSpecificationException => e
|
|
151
|
+
Bundler.ui.warn "\n#{spec.name} at #{spec.full_gem_path} did not have a valid gemspec.\n" \
|
|
152
|
+
"This prevents bundler from installing bins or native extensions, but " \
|
|
153
|
+
"that may not affect its functionality."
|
|
154
|
+
|
|
155
|
+
if !spec.extensions.empty? && !spec.email.empty?
|
|
156
|
+
Bundler.ui.warn "If you need to use this package without installing it from a gem " \
|
|
157
|
+
"repository, please contact #{spec.email} and ask them " \
|
|
158
|
+
"to modify their .gemspec so it can work with `gem build`."
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
Bundler.ui.warn "The validation message from RubyGems was:\n #{e.message}"
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
source 'pathext', PathExtSource
|
|
166
|
+
end
|
data/plugins.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bundler-source-pathext
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- pganalyze Team
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-01-17 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: ''
|
|
14
|
+
email:
|
|
15
|
+
- team@pganalyze.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- ".gitignore"
|
|
21
|
+
- Gemfile
|
|
22
|
+
- Gemfile.lock
|
|
23
|
+
- LICENSE
|
|
24
|
+
- README.md
|
|
25
|
+
- Rakefile
|
|
26
|
+
- bundler-source-pathext.gemspec
|
|
27
|
+
- lib/bundler-source-pathext.rb
|
|
28
|
+
- lib/bundler-source-pathext/version.rb
|
|
29
|
+
- plugins.rb
|
|
30
|
+
homepage:
|
|
31
|
+
licenses: []
|
|
32
|
+
metadata: {}
|
|
33
|
+
post_install_message:
|
|
34
|
+
rdoc_options: []
|
|
35
|
+
require_paths:
|
|
36
|
+
- lib
|
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: 2.3.0
|
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
requirements: []
|
|
48
|
+
rubygems_version: 3.5.22
|
|
49
|
+
signing_key:
|
|
50
|
+
specification_version: 4
|
|
51
|
+
summary: ''
|
|
52
|
+
test_files: []
|