carat 1.9.9.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +3 -0
- data/.travis.yml +24 -0
- data/CHANGELOG.md +2006 -0
- data/CODE_OF_CONDUCT.md +40 -0
- data/CONTRIBUTING.md +23 -0
- data/DEVELOPMENT.md +119 -0
- data/ISSUES.md +96 -0
- data/LICENSE.md +23 -0
- data/README.md +32 -0
- data/Rakefile +308 -0
- data/bin/carat +21 -0
- data/bin/carat_ruby +56 -0
- data/carat.gemspec +32 -0
- data/lib/carat.rb +446 -0
- data/lib/carat/anonymizable_uri.rb +32 -0
- data/lib/carat/capistrano.rb +16 -0
- data/lib/carat/cli.rb +407 -0
- data/lib/carat/cli/binstubs.rb +38 -0
- data/lib/carat/cli/cache.rb +35 -0
- data/lib/carat/cli/check.rb +35 -0
- data/lib/carat/cli/clean.rb +26 -0
- data/lib/carat/cli/common.rb +56 -0
- data/lib/carat/cli/config.rb +84 -0
- data/lib/carat/cli/console.rb +38 -0
- data/lib/carat/cli/exec.rb +44 -0
- data/lib/carat/cli/gem.rb +195 -0
- data/lib/carat/cli/init.rb +33 -0
- data/lib/carat/cli/inject.rb +33 -0
- data/lib/carat/cli/install.rb +156 -0
- data/lib/carat/cli/open.rb +23 -0
- data/lib/carat/cli/outdated.rb +80 -0
- data/lib/carat/cli/package.rb +45 -0
- data/lib/carat/cli/platform.rb +43 -0
- data/lib/carat/cli/show.rb +74 -0
- data/lib/carat/cli/update.rb +73 -0
- data/lib/carat/cli/viz.rb +27 -0
- data/lib/carat/constants.rb +5 -0
- data/lib/carat/current_ruby.rb +183 -0
- data/lib/carat/definition.rb +628 -0
- data/lib/carat/dep_proxy.rb +43 -0
- data/lib/carat/dependency.rb +110 -0
- data/lib/carat/deployment.rb +59 -0
- data/lib/carat/deprecate.rb +15 -0
- data/lib/carat/dsl.rb +331 -0
- data/lib/carat/endpoint_specification.rb +76 -0
- data/lib/carat/env.rb +75 -0
- data/lib/carat/environment.rb +42 -0
- data/lib/carat/fetcher.rb +423 -0
- data/lib/carat/friendly_errors.rb +85 -0
- data/lib/carat/gem_helper.rb +180 -0
- data/lib/carat/gem_helpers.rb +26 -0
- data/lib/carat/gem_installer.rb +9 -0
- data/lib/carat/gem_path_manipulation.rb +8 -0
- data/lib/carat/gem_tasks.rb +2 -0
- data/lib/carat/graph.rb +169 -0
- data/lib/carat/index.rb +197 -0
- data/lib/carat/injector.rb +64 -0
- data/lib/carat/installer.rb +339 -0
- data/lib/carat/lazy_specification.rb +83 -0
- data/lib/carat/lockfile_parser.rb +167 -0
- data/lib/carat/match_platform.rb +13 -0
- data/lib/carat/psyched_yaml.rb +26 -0
- data/lib/carat/remote_specification.rb +57 -0
- data/lib/carat/resolver.rb +334 -0
- data/lib/carat/retry.rb +60 -0
- data/lib/carat/ruby_dsl.rb +11 -0
- data/lib/carat/ruby_version.rb +117 -0
- data/lib/carat/rubygems_ext.rb +170 -0
- data/lib/carat/rubygems_integration.rb +619 -0
- data/lib/carat/runtime.rb +289 -0
- data/lib/carat/settings.rb +208 -0
- data/lib/carat/setup.rb +24 -0
- data/lib/carat/shared_helpers.rb +149 -0
- data/lib/carat/similarity_detector.rb +63 -0
- data/lib/carat/source.rb +46 -0
- data/lib/carat/source/git.rb +294 -0
- data/lib/carat/source/git/git_proxy.rb +162 -0
- data/lib/carat/source/path.rb +226 -0
- data/lib/carat/source/path/installer.rb +43 -0
- data/lib/carat/source/rubygems.rb +381 -0
- data/lib/carat/source_list.rb +101 -0
- data/lib/carat/spec_set.rb +154 -0
- data/lib/carat/ssl_certs/.document +1 -0
- data/lib/carat/ssl_certs/AddTrustExternalCARoot-2048.pem +25 -0
- data/lib/carat/ssl_certs/AddTrustExternalCARoot.pem +32 -0
- data/lib/carat/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +14 -0
- data/lib/carat/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +23 -0
- data/lib/carat/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +28 -0
- data/lib/carat/ssl_certs/GeoTrustGlobalCA.pem +20 -0
- data/lib/carat/ssl_certs/certificate_manager.rb +66 -0
- data/lib/carat/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
- data/lib/carat/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +23 -0
- data/lib/carat/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +25 -0
- data/lib/carat/templates/Executable +16 -0
- data/lib/carat/templates/Executable.standalone +12 -0
- data/lib/carat/templates/Gemfile +4 -0
- data/lib/carat/templates/newgem/.travis.yml.tt +3 -0
- data/lib/carat/templates/newgem/CODE_OF_CONDUCT.md.tt +13 -0
- data/lib/carat/templates/newgem/Gemfile.tt +4 -0
- data/lib/carat/templates/newgem/LICENSE.txt.tt +21 -0
- data/lib/carat/templates/newgem/README.md.tt +39 -0
- data/lib/carat/templates/newgem/Rakefile.tt +25 -0
- data/lib/carat/templates/newgem/bin/console.tt +14 -0
- data/lib/carat/templates/newgem/bin/setup.tt +7 -0
- data/lib/carat/templates/newgem/exe/newgem.tt +3 -0
- data/lib/carat/templates/newgem/ext/newgem/extconf.rb.tt +3 -0
- data/lib/carat/templates/newgem/ext/newgem/newgem.c.tt +9 -0
- data/lib/carat/templates/newgem/ext/newgem/newgem.h.tt +6 -0
- data/lib/carat/templates/newgem/gitignore.tt +16 -0
- data/lib/carat/templates/newgem/lib/newgem.rb.tt +12 -0
- data/lib/carat/templates/newgem/lib/newgem/version.rb.tt +7 -0
- data/lib/carat/templates/newgem/newgem.gemspec.tt +43 -0
- data/lib/carat/templates/newgem/rspec.tt +2 -0
- data/lib/carat/templates/newgem/spec/newgem_spec.rb.tt +11 -0
- data/lib/carat/templates/newgem/spec/spec_helper.rb.tt +2 -0
- data/lib/carat/templates/newgem/test/minitest_helper.rb.tt +4 -0
- data/lib/carat/templates/newgem/test/test_newgem.rb.tt +11 -0
- data/lib/carat/ui.rb +7 -0
- data/lib/carat/ui/rg_proxy.rb +21 -0
- data/lib/carat/ui/shell.rb +103 -0
- data/lib/carat/ui/silent.rb +44 -0
- data/lib/carat/vendor/molinillo/lib/molinillo.rb +5 -0
- data/lib/carat/vendor/molinillo/lib/molinillo/dependency_graph.rb +266 -0
- data/lib/carat/vendor/molinillo/lib/molinillo/errors.rb +69 -0
- data/lib/carat/vendor/molinillo/lib/molinillo/gem_metadata.rb +3 -0
- data/lib/carat/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +90 -0
- data/lib/carat/vendor/molinillo/lib/molinillo/modules/ui.rb +63 -0
- data/lib/carat/vendor/molinillo/lib/molinillo/resolution.rb +415 -0
- data/lib/carat/vendor/molinillo/lib/molinillo/resolver.rb +43 -0
- data/lib/carat/vendor/molinillo/lib/molinillo/state.rb +43 -0
- data/lib/carat/vendor/net/http/faster.rb +26 -0
- data/lib/carat/vendor/net/http/persistent.rb +1230 -0
- data/lib/carat/vendor/net/http/persistent/ssl_reuse.rb +128 -0
- data/lib/carat/vendor/thor/lib/thor.rb +484 -0
- data/lib/carat/vendor/thor/lib/thor/actions.rb +319 -0
- data/lib/carat/vendor/thor/lib/thor/actions/create_file.rb +103 -0
- data/lib/carat/vendor/thor/lib/thor/actions/create_link.rb +59 -0
- data/lib/carat/vendor/thor/lib/thor/actions/directory.rb +118 -0
- data/lib/carat/vendor/thor/lib/thor/actions/empty_directory.rb +135 -0
- data/lib/carat/vendor/thor/lib/thor/actions/file_manipulation.rb +316 -0
- data/lib/carat/vendor/thor/lib/thor/actions/inject_into_file.rb +107 -0
- data/lib/carat/vendor/thor/lib/thor/base.rb +656 -0
- data/lib/carat/vendor/thor/lib/thor/command.rb +133 -0
- data/lib/carat/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +77 -0
- data/lib/carat/vendor/thor/lib/thor/core_ext/io_binary_read.rb +10 -0
- data/lib/carat/vendor/thor/lib/thor/core_ext/ordered_hash.rb +98 -0
- data/lib/carat/vendor/thor/lib/thor/error.rb +32 -0
- data/lib/carat/vendor/thor/lib/thor/group.rb +281 -0
- data/lib/carat/vendor/thor/lib/thor/invocation.rb +178 -0
- data/lib/carat/vendor/thor/lib/thor/line_editor.rb +17 -0
- data/lib/carat/vendor/thor/lib/thor/line_editor/basic.rb +35 -0
- data/lib/carat/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
- data/lib/carat/vendor/thor/lib/thor/parser.rb +4 -0
- data/lib/carat/vendor/thor/lib/thor/parser/argument.rb +73 -0
- data/lib/carat/vendor/thor/lib/thor/parser/arguments.rb +175 -0
- data/lib/carat/vendor/thor/lib/thor/parser/option.rb +125 -0
- data/lib/carat/vendor/thor/lib/thor/parser/options.rb +218 -0
- data/lib/carat/vendor/thor/lib/thor/rake_compat.rb +71 -0
- data/lib/carat/vendor/thor/lib/thor/runner.rb +322 -0
- data/lib/carat/vendor/thor/lib/thor/shell.rb +81 -0
- data/lib/carat/vendor/thor/lib/thor/shell/basic.rb +421 -0
- data/lib/carat/vendor/thor/lib/thor/shell/color.rb +149 -0
- data/lib/carat/vendor/thor/lib/thor/shell/html.rb +126 -0
- data/lib/carat/vendor/thor/lib/thor/util.rb +267 -0
- data/lib/carat/vendor/thor/lib/thor/version.rb +3 -0
- data/lib/carat/vendored_fileutils.rb +9 -0
- data/lib/carat/vendored_molinillo.rb +2 -0
- data/lib/carat/vendored_persistent.rb +11 -0
- data/lib/carat/vendored_thor.rb +3 -0
- data/lib/carat/version.rb +6 -0
- data/lib/carat/vlad.rb +11 -0
- data/lib/carat/worker.rb +73 -0
- data/man/carat-config.ronn +178 -0
- data/man/carat-exec.ronn +136 -0
- data/man/carat-install.ronn +383 -0
- data/man/carat-package.ronn +66 -0
- data/man/carat-platform.ronn +42 -0
- data/man/carat-update.ronn +188 -0
- data/man/carat.ronn +98 -0
- data/man/gemfile.5.ronn +473 -0
- data/man/index.txt +7 -0
- metadata +321 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
require "digest/sha1"
|
|
2
|
+
|
|
3
|
+
module Carat
|
|
4
|
+
class Runtime < Environment
|
|
5
|
+
include SharedHelpers
|
|
6
|
+
|
|
7
|
+
def setup(*groups)
|
|
8
|
+
groups.map! { |g| g.to_sym }
|
|
9
|
+
|
|
10
|
+
# Has to happen first
|
|
11
|
+
clean_load_path
|
|
12
|
+
|
|
13
|
+
specs = groups.any? ? @definition.specs_for(groups) : requested_specs
|
|
14
|
+
|
|
15
|
+
setup_environment
|
|
16
|
+
Carat.rubygems.replace_entrypoints(specs)
|
|
17
|
+
|
|
18
|
+
# Activate the specs
|
|
19
|
+
specs.each do |spec|
|
|
20
|
+
unless spec.loaded_from
|
|
21
|
+
raise GemNotFound, "#{spec.full_name} is missing. Run `carat` to get it."
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if activated_spec = Carat.rubygems.loaded_specs(spec.name) and activated_spec.version != spec.version
|
|
25
|
+
e = Gem::LoadError.new "You have already activated #{activated_spec.name} #{activated_spec.version}, " \
|
|
26
|
+
"but your Gemfile requires #{spec.name} #{spec.version}. Prepending " \
|
|
27
|
+
"`carat exec` to your command may solve this."
|
|
28
|
+
e.name = spec.name
|
|
29
|
+
if e.respond_to?(:requirement=)
|
|
30
|
+
e.requirement = Gem::Requirement.new(spec.version.to_s)
|
|
31
|
+
else
|
|
32
|
+
e.version_requirement = Gem::Requirement.new(spec.version.to_s)
|
|
33
|
+
end
|
|
34
|
+
raise e
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Carat.rubygems.mark_loaded(spec)
|
|
38
|
+
load_paths = spec.load_paths.reject {|path| $LOAD_PATH.include?(path)}
|
|
39
|
+
$LOAD_PATH.unshift(*load_paths)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
setup_manpath
|
|
43
|
+
|
|
44
|
+
lock
|
|
45
|
+
|
|
46
|
+
self
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
REQUIRE_ERRORS = [
|
|
50
|
+
/^no such file to load -- (.+)$/i,
|
|
51
|
+
/^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
|
|
52
|
+
/^Missing API definition file in (.+)$/i,
|
|
53
|
+
/^cannot load such file -- (.+)$/i,
|
|
54
|
+
/^dlopen\([^)]*\): Library not loaded: (.+)$/i,
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
def require(*groups)
|
|
58
|
+
groups.map! { |g| g.to_sym }
|
|
59
|
+
groups = [:default] if groups.empty?
|
|
60
|
+
|
|
61
|
+
@definition.dependencies.each do |dep|
|
|
62
|
+
# Skip the dependency if it is not in any of the requested
|
|
63
|
+
# groups
|
|
64
|
+
next unless ((dep.groups & groups).any? && dep.current_platform?)
|
|
65
|
+
|
|
66
|
+
required_file = nil
|
|
67
|
+
|
|
68
|
+
begin
|
|
69
|
+
# Loop through all the specified autorequires for the
|
|
70
|
+
# dependency. If there are none, use the dependency's name
|
|
71
|
+
# as the autorequire.
|
|
72
|
+
Array(dep.autorequire || dep.name).each do |file|
|
|
73
|
+
# Allow `require: true` as an alias for `require: <name>`
|
|
74
|
+
file = dep.name if file == true
|
|
75
|
+
required_file = file
|
|
76
|
+
Kernel.require file
|
|
77
|
+
end
|
|
78
|
+
rescue LoadError => e
|
|
79
|
+
REQUIRE_ERRORS.find { |r| r =~ e.message }
|
|
80
|
+
raise if dep.autorequire || $1 != required_file
|
|
81
|
+
|
|
82
|
+
if dep.autorequire.nil? && dep.name.include?('-')
|
|
83
|
+
begin
|
|
84
|
+
namespaced_file = dep.name.gsub('-', '/')
|
|
85
|
+
Kernel.require namespaced_file
|
|
86
|
+
rescue LoadError => e
|
|
87
|
+
REQUIRE_ERRORS.find { |r| r =~ e.message }
|
|
88
|
+
raise if $1 != namespaced_file
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def dependencies_for(*groups)
|
|
96
|
+
if groups.empty?
|
|
97
|
+
dependencies
|
|
98
|
+
else
|
|
99
|
+
dependencies.select { |d| (groups & d.groups).any? }
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
alias gems specs
|
|
104
|
+
|
|
105
|
+
def cache(custom_path = nil)
|
|
106
|
+
cache_path = Carat.app_cache(custom_path)
|
|
107
|
+
FileUtils.mkdir_p(cache_path) unless File.exist?(cache_path)
|
|
108
|
+
|
|
109
|
+
Carat.ui.info "Updating files in #{Carat.settings.app_cache_path}"
|
|
110
|
+
specs.each do |spec|
|
|
111
|
+
next if spec.name == 'carat'
|
|
112
|
+
spec.source.send(:fetch_gem, spec) if Carat.settings[:cache_all_platforms] && spec.source.respond_to?(:fetch_gem, true)
|
|
113
|
+
spec.source.cache(spec, custom_path) if spec.source.respond_to?(:cache)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
Dir[cache_path.join("*/.git")].each do |git_dir|
|
|
117
|
+
FileUtils.rm_rf(git_dir)
|
|
118
|
+
FileUtils.touch(File.expand_path("../.caratcache", git_dir))
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
prune_cache(cache_path) unless Carat.settings[:no_prune]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def prune_cache(cache_path)
|
|
125
|
+
FileUtils.mkdir_p(cache_path) unless File.exist?(cache_path)
|
|
126
|
+
resolve = @definition.resolve
|
|
127
|
+
prune_gem_cache(resolve, cache_path)
|
|
128
|
+
prune_git_and_path_cache(resolve, cache_path)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def clean(dry_run = false)
|
|
132
|
+
gem_bins = Dir["#{Gem.dir}/bin/*"]
|
|
133
|
+
git_dirs = Dir["#{Gem.dir}/carat/gems/*"]
|
|
134
|
+
git_cache_dirs = Dir["#{Gem.dir}/cache/carat/git/*"]
|
|
135
|
+
gem_dirs = Dir["#{Gem.dir}/gems/*"]
|
|
136
|
+
gem_files = Dir["#{Gem.dir}/cache/*.gem"]
|
|
137
|
+
gemspec_files = Dir["#{Gem.dir}/specifications/*.gemspec"]
|
|
138
|
+
spec_gem_paths = []
|
|
139
|
+
# need to keep git sources around
|
|
140
|
+
spec_git_paths = @definition.spec_git_paths
|
|
141
|
+
spec_git_cache_dirs = []
|
|
142
|
+
spec_gem_executables = []
|
|
143
|
+
spec_cache_paths = []
|
|
144
|
+
spec_gemspec_paths = []
|
|
145
|
+
specs.each do |spec|
|
|
146
|
+
spec_gem_paths << spec.full_gem_path
|
|
147
|
+
# need to check here in case gems are nested like for the rails git repo
|
|
148
|
+
md = %r{(.+carat/gems/.+-[a-f0-9]{7,12})}.match(spec.full_gem_path)
|
|
149
|
+
spec_git_paths << md[1] if md
|
|
150
|
+
spec_gem_executables << spec.executables.collect do |executable|
|
|
151
|
+
e = "#{Carat.rubygems.gem_bindir}/#{executable}"
|
|
152
|
+
[e, "#{e}.bat"]
|
|
153
|
+
end
|
|
154
|
+
spec_cache_paths << spec.cache_file
|
|
155
|
+
spec_gemspec_paths << spec.spec_file
|
|
156
|
+
spec_git_cache_dirs << spec.source.cache_path.to_s if spec.source.is_a?(Carat::Source::Git)
|
|
157
|
+
end
|
|
158
|
+
spec_gem_paths.uniq!
|
|
159
|
+
spec_gem_executables.flatten!
|
|
160
|
+
|
|
161
|
+
stale_gem_bins = gem_bins - spec_gem_executables
|
|
162
|
+
stale_git_dirs = git_dirs - spec_git_paths
|
|
163
|
+
stale_git_cache_dirs = git_cache_dirs - spec_git_cache_dirs
|
|
164
|
+
stale_gem_dirs = gem_dirs - spec_gem_paths
|
|
165
|
+
stale_gem_files = gem_files - spec_cache_paths
|
|
166
|
+
stale_gemspec_files = gemspec_files - spec_gemspec_paths
|
|
167
|
+
|
|
168
|
+
output = stale_gem_dirs.collect do |gem_dir|
|
|
169
|
+
full_name = Pathname.new(gem_dir).basename.to_s
|
|
170
|
+
|
|
171
|
+
parts = full_name.split('-')
|
|
172
|
+
name = parts[0..-2].join('-')
|
|
173
|
+
version = parts.last
|
|
174
|
+
output = "#{name} (#{version})"
|
|
175
|
+
|
|
176
|
+
if dry_run
|
|
177
|
+
Carat.ui.info "Would have removed #{output}"
|
|
178
|
+
else
|
|
179
|
+
Carat.ui.info "Removing #{output}"
|
|
180
|
+
FileUtils.rm_rf(gem_dir)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
output
|
|
184
|
+
end + stale_git_dirs.collect do |gem_dir|
|
|
185
|
+
full_name = Pathname.new(gem_dir).basename.to_s
|
|
186
|
+
|
|
187
|
+
parts = full_name.split('-')
|
|
188
|
+
name = parts[0..-2].join('-')
|
|
189
|
+
revision = parts[-1]
|
|
190
|
+
output = "#{name} (#{revision})"
|
|
191
|
+
|
|
192
|
+
if dry_run
|
|
193
|
+
Carat.ui.info "Would have removed #{output}"
|
|
194
|
+
else
|
|
195
|
+
Carat.ui.info "Removing #{output}"
|
|
196
|
+
FileUtils.rm_rf(gem_dir)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
output
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
unless dry_run
|
|
203
|
+
stale_gem_bins.each { |bin| FileUtils.rm(bin) if File.exist?(bin) }
|
|
204
|
+
stale_gem_files.each { |file| FileUtils.rm(file) if File.exist?(file) }
|
|
205
|
+
stale_gemspec_files.each { |file| FileUtils.rm(file) if File.exist?(file) }
|
|
206
|
+
stale_git_cache_dirs.each { |dir| FileUtils.rm_rf(dir) if File.exist?(dir) }
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
output
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def setup_environment
|
|
213
|
+
begin
|
|
214
|
+
ENV["BUNDLE_BIN_PATH"] = Carat.rubygems.bin_path("carat", "carat", VERSION)
|
|
215
|
+
rescue Gem::GemNotFoundException
|
|
216
|
+
ENV["BUNDLE_BIN_PATH"] = File.expand_path("../../../bin/carat", __FILE__)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Set BUNDLE_GEMFILE
|
|
220
|
+
ENV["BUNDLE_GEMFILE"] = default_gemfile.to_s
|
|
221
|
+
|
|
222
|
+
SharedHelpers.set_bundle_environment
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
private
|
|
226
|
+
|
|
227
|
+
def prune_gem_cache(resolve, cache_path)
|
|
228
|
+
cached = Dir["#{cache_path}/*.gem"]
|
|
229
|
+
|
|
230
|
+
cached = cached.delete_if do |path|
|
|
231
|
+
spec = Carat.rubygems.spec_from_gem path
|
|
232
|
+
|
|
233
|
+
resolve.any? do |s|
|
|
234
|
+
s.name == spec.name && s.version == spec.version && !s.source.is_a?(Carat::Source::Git)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
if cached.any?
|
|
239
|
+
Carat.ui.info "Removing outdated .gem files from #{Carat.settings.app_cache_path}"
|
|
240
|
+
|
|
241
|
+
cached.each do |path|
|
|
242
|
+
Carat.ui.info " * #{File.basename(path)}"
|
|
243
|
+
File.delete(path)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def prune_git_and_path_cache(resolve, cache_path)
|
|
249
|
+
cached = Dir["#{cache_path}/*/.caratcache"]
|
|
250
|
+
|
|
251
|
+
cached = cached.delete_if do |path|
|
|
252
|
+
name = File.basename(File.dirname(path))
|
|
253
|
+
|
|
254
|
+
resolve.any? do |s|
|
|
255
|
+
source = s.source
|
|
256
|
+
source.respond_to?(:app_cache_dirname) && source.app_cache_dirname == name
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
if cached.any?
|
|
261
|
+
Carat.ui.info "Removing outdated git and path gems from #{Carat.settings.app_cache_path}"
|
|
262
|
+
|
|
263
|
+
cached.each do |path|
|
|
264
|
+
path = File.dirname(path)
|
|
265
|
+
Carat.ui.info " * #{File.basename(path)}"
|
|
266
|
+
FileUtils.rm_rf(path)
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def setup_manpath
|
|
272
|
+
# Store original MANPATH for restoration later in with_clean_env()
|
|
273
|
+
ENV['BUNDLE_ORIG_MANPATH'] = ENV['MANPATH']
|
|
274
|
+
|
|
275
|
+
# Add man/ subdirectories from activated bundles to MANPATH for man(1)
|
|
276
|
+
manuals = $LOAD_PATH.map do |path|
|
|
277
|
+
man_subdir = path.sub(/lib$/, 'man')
|
|
278
|
+
man_subdir unless Dir[man_subdir + '/man?/'].empty?
|
|
279
|
+
end.compact
|
|
280
|
+
|
|
281
|
+
unless manuals.empty?
|
|
282
|
+
ENV['MANPATH'] = manuals.concat(
|
|
283
|
+
ENV['MANPATH'].to_s.split(File::PATH_SEPARATOR)
|
|
284
|
+
).uniq.join(File::PATH_SEPARATOR)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
end
|
|
289
|
+
end
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
|
|
3
|
+
module Carat
|
|
4
|
+
class Settings
|
|
5
|
+
BOOL_KEYS = %w(frozen cache_all no_prune disable_local_branch_check gem.mit gem.coc).freeze
|
|
6
|
+
|
|
7
|
+
def initialize(root = nil)
|
|
8
|
+
@root = root
|
|
9
|
+
@local_config = load_config(local_config_file)
|
|
10
|
+
@global_config = load_config(global_config_file)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def [](name)
|
|
14
|
+
key = key_for(name)
|
|
15
|
+
value = (@local_config[key] || ENV[key] || @global_config[key])
|
|
16
|
+
|
|
17
|
+
if !value.nil? && is_bool(name)
|
|
18
|
+
to_bool(value)
|
|
19
|
+
else
|
|
20
|
+
value
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def []=(key, value)
|
|
25
|
+
local_config_file or raise GemfileNotFound, "Could not locate Gemfile"
|
|
26
|
+
set_key(key, value, @local_config, local_config_file)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
alias :set_local :[]=
|
|
30
|
+
|
|
31
|
+
def delete(key)
|
|
32
|
+
@local_config.delete(key_for(key))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def set_global(key, value)
|
|
36
|
+
set_key(key, value, @global_config, global_config_file)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def all
|
|
40
|
+
env_keys = ENV.keys.select { |k| k =~ /BUNDLE_.*/ }
|
|
41
|
+
|
|
42
|
+
keys = @global_config.keys | @local_config.keys | env_keys
|
|
43
|
+
|
|
44
|
+
keys.map do |key|
|
|
45
|
+
key.sub(/^BUNDLE_/, '').gsub(/__/, ".").downcase
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def local_overrides
|
|
50
|
+
repos = {}
|
|
51
|
+
all.each do |k|
|
|
52
|
+
if k =~ /^local\./
|
|
53
|
+
repos[$'] = self[k]
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
repos
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def gem_mirrors
|
|
60
|
+
all.inject({}) do |h, k|
|
|
61
|
+
if k =~ /^mirror\./
|
|
62
|
+
uri = normalize_uri($')
|
|
63
|
+
h[uri] = normalize_uri(self[k])
|
|
64
|
+
end
|
|
65
|
+
h
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def locations(key)
|
|
70
|
+
key = key_for(key)
|
|
71
|
+
locations = {}
|
|
72
|
+
locations[:local] = @local_config[key] if @local_config.key?(key)
|
|
73
|
+
locations[:env] = ENV[key] if ENV[key]
|
|
74
|
+
locations[:global] = @global_config[key] if @global_config.key?(key)
|
|
75
|
+
locations
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def pretty_values_for(exposed_key)
|
|
79
|
+
key = key_for(exposed_key)
|
|
80
|
+
|
|
81
|
+
locations = []
|
|
82
|
+
if @local_config.key?(key)
|
|
83
|
+
locations << "Set for your local app (#{local_config_file}): #{@local_config[key].inspect}"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
if value = ENV[key]
|
|
87
|
+
locations << "Set via #{key}: #{value.inspect}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
if @global_config.key?(key)
|
|
91
|
+
locations << "Set for the current user (#{global_config_file}): #{@global_config[key].inspect}"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
return ["You have not configured a value for `#{exposed_key}`"] if locations.empty?
|
|
95
|
+
locations
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def without=(array)
|
|
99
|
+
self[:without] = (array.empty? ? nil : array.join(":")) if array
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def without
|
|
103
|
+
self[:without] ? self[:without].split(":").map { |w| w.to_sym } : []
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# @local_config["BUNDLE_PATH"] should be prioritized over ENV["BUNDLE_PATH"]
|
|
107
|
+
def path
|
|
108
|
+
key = key_for(:path)
|
|
109
|
+
path = ENV[key] || @global_config[key]
|
|
110
|
+
return path if path && !@local_config.key?(key)
|
|
111
|
+
|
|
112
|
+
if path = self[:path]
|
|
113
|
+
"#{path}/#{Carat.ruby_scope}"
|
|
114
|
+
else
|
|
115
|
+
Carat.rubygems.gem_dir
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def allow_sudo?
|
|
120
|
+
!@local_config.key?(key_for(:path))
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def ignore_config?
|
|
124
|
+
ENV['BUNDLE_IGNORE_CONFIG']
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def app_cache_path
|
|
128
|
+
@app_cache_path ||= begin
|
|
129
|
+
path = self[:cache_path] || "vendor/cache"
|
|
130
|
+
raise InvalidOption, "Cache path must be relative to the bundle path" if path.start_with?("/")
|
|
131
|
+
path
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
def key_for(key)
|
|
137
|
+
if key.is_a?(String) && /https?:/ =~ key
|
|
138
|
+
key = normalize_uri(key).to_s
|
|
139
|
+
end
|
|
140
|
+
key = key.to_s.gsub(".", "__").upcase
|
|
141
|
+
"BUNDLE_#{key}"
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def is_bool(key)
|
|
145
|
+
BOOL_KEYS.include?(key.to_s)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def to_bool(value)
|
|
149
|
+
!(value.nil? || value == '' || value =~ /^(false|f|no|n|0)$/i || value == false)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def set_key(key, value, hash, file)
|
|
153
|
+
key = key_for(key)
|
|
154
|
+
|
|
155
|
+
unless hash[key] == value
|
|
156
|
+
hash[key] = value
|
|
157
|
+
hash.delete(key) if value.nil?
|
|
158
|
+
FileUtils.mkdir_p(file.dirname)
|
|
159
|
+
require 'carat/psyched_yaml'
|
|
160
|
+
File.open(file, "w") { |f| f.puts YAML.dump(hash) }
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
value
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def global_config_file
|
|
167
|
+
file = ENV["BUNDLE_CONFIG"] || File.join(Carat.rubygems.user_home, ".carat/config")
|
|
168
|
+
Pathname.new(file)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def local_config_file
|
|
172
|
+
Pathname.new(@root).join("config") if @root
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def load_config(config_file)
|
|
176
|
+
valid_file = config_file && config_file.exist? && !config_file.size.zero?
|
|
177
|
+
if !ignore_config? && valid_file
|
|
178
|
+
config_regex = /^(BUNDLE_.+): (['"]?)(.*(?:\n(?!BUNDLE).+)?)\2$/
|
|
179
|
+
config_pairs = config_file.read.scan(config_regex).map do |m|
|
|
180
|
+
key, _, value = m
|
|
181
|
+
[convert_to_backward_compatible_key(key), value.gsub(/\s+/, " ").tr('"', "'")]
|
|
182
|
+
end
|
|
183
|
+
Hash[config_pairs]
|
|
184
|
+
else
|
|
185
|
+
{}
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def convert_to_backward_compatible_key(key)
|
|
190
|
+
key = "#{key}/" if key =~ /https?:/i && key !~ %r[/\Z]
|
|
191
|
+
key = key.gsub(".", "__") if key.include?(".")
|
|
192
|
+
key
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# TODO: duplicates Rubygems#normalize_uri
|
|
196
|
+
# TODO: is this the correct place to validate mirror URIs?
|
|
197
|
+
def normalize_uri(uri)
|
|
198
|
+
uri = uri.to_s
|
|
199
|
+
uri = "#{uri}/" unless uri =~ %r[/\Z]
|
|
200
|
+
uri = URI(uri)
|
|
201
|
+
unless uri.absolute?
|
|
202
|
+
raise ArgumentError, "Gem sources must be absolute. You provided '#{uri}'."
|
|
203
|
+
end
|
|
204
|
+
uri
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
end
|
|
208
|
+
end
|