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,33 @@
|
|
|
1
|
+
module Carat
|
|
2
|
+
class CLI::Init
|
|
3
|
+
attr_reader :options
|
|
4
|
+
def initialize(options)
|
|
5
|
+
@options = options
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def run
|
|
9
|
+
if File.exist?("Gemfile")
|
|
10
|
+
Carat.ui.error "Gemfile already exists at #{Dir.pwd}/Gemfile"
|
|
11
|
+
exit 1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
if options[:gemspec]
|
|
15
|
+
gemspec = File.expand_path(options[:gemspec])
|
|
16
|
+
unless File.exist?(gemspec)
|
|
17
|
+
Carat.ui.error "Gem specification #{gemspec} doesn't exist"
|
|
18
|
+
exit 1
|
|
19
|
+
end
|
|
20
|
+
spec = Gem::Specification.load(gemspec)
|
|
21
|
+
puts "Writing new Gemfile to #{Dir.pwd}/Gemfile"
|
|
22
|
+
File.open('Gemfile', 'wb') do |file|
|
|
23
|
+
file << "# Generated from #{gemspec}\n"
|
|
24
|
+
file << spec.to_gemfile
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
puts "Writing new Gemfile to #{Dir.pwd}/Gemfile"
|
|
28
|
+
FileUtils.cp(File.expand_path('../../templates/Gemfile', __FILE__), 'Gemfile')
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Carat
|
|
2
|
+
class CLI::Inject
|
|
3
|
+
attr_reader :options, :name, :version, :gems
|
|
4
|
+
def initialize(options, name, version, gems)
|
|
5
|
+
@options = options
|
|
6
|
+
@name = name
|
|
7
|
+
@version = version
|
|
8
|
+
@gems = gems
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def run
|
|
12
|
+
# The required arguments allow Thor to give useful feedback when the arguments
|
|
13
|
+
# are incorrect. This adds those first two arguments onto the list as a whole.
|
|
14
|
+
gems.unshift(version).unshift(name)
|
|
15
|
+
|
|
16
|
+
# Build an array of Dependency objects out of the arguments
|
|
17
|
+
deps = []
|
|
18
|
+
gems.each_slice(2) do |gem_name, gem_version|
|
|
19
|
+
deps << Carat::Dependency.new(gem_name, gem_version)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
added = Injector.inject(deps)
|
|
23
|
+
|
|
24
|
+
if added.any?
|
|
25
|
+
Carat.ui.confirm "Added to Gemfile:"
|
|
26
|
+
Carat.ui.confirm added.map{ |g| " #{g}" }.join("\n")
|
|
27
|
+
else
|
|
28
|
+
Carat.ui.confirm "All injected gems were already present in the Gemfile"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
module Carat
|
|
2
|
+
class CLI::Install
|
|
3
|
+
attr_reader :options
|
|
4
|
+
def initialize(options)
|
|
5
|
+
@options = options
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def run
|
|
9
|
+
Carat.ui.level = "error" if options[:quiet]
|
|
10
|
+
|
|
11
|
+
warn_if_root
|
|
12
|
+
|
|
13
|
+
if options[:without]
|
|
14
|
+
options[:without] = options[:without].map{|g| g.tr(' ', ':') }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
ENV['RB_USER_INSTALL'] = '1' if Carat::FREEBSD
|
|
18
|
+
|
|
19
|
+
# Just disable color in deployment mode
|
|
20
|
+
Carat.ui.shell = Thor::Shell::Basic.new if options[:deployment]
|
|
21
|
+
|
|
22
|
+
if (options[:path] || options[:deployment]) && options[:system]
|
|
23
|
+
Carat.ui.error "You have specified both a path to install your gems to, \n" \
|
|
24
|
+
"as well as --system. Please choose."
|
|
25
|
+
exit 1
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if (options["trust-policy"])
|
|
29
|
+
unless (Carat.rubygems.security_policies.keys.include?(options["trust-policy"]))
|
|
30
|
+
Carat.ui.error "Rubygems doesn't know about trust policy '#{options["trust-policy"]}'. " \
|
|
31
|
+
"The known policies are: #{Carat.rubygems.security_policies.keys.join(', ')}."
|
|
32
|
+
exit 1
|
|
33
|
+
end
|
|
34
|
+
Carat.settings["trust-policy"] = options["trust-policy"]
|
|
35
|
+
else
|
|
36
|
+
Carat.settings["trust-policy"] = nil if Carat.settings["trust-policy"]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if options[:deployment] || options[:frozen]
|
|
40
|
+
unless Carat.default_lockfile.exist?
|
|
41
|
+
flag = options[:deployment] ? '--deployment' : '--frozen'
|
|
42
|
+
raise ProductionError, "The #{flag} flag requires a Gemfile.lock. Please make " \
|
|
43
|
+
"sure you have checked your Gemfile.lock into version control " \
|
|
44
|
+
"before deploying."
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if Carat.app_cache.exist?
|
|
48
|
+
options[:local] = true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
Carat.settings[:frozen] = '1'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# When install is called with --no-deployment, disable deployment mode
|
|
55
|
+
if options[:deployment] == false
|
|
56
|
+
Carat.settings.delete(:frozen)
|
|
57
|
+
options[:system] = true
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
Carat.settings[:path] = nil if options[:system]
|
|
61
|
+
Carat.settings[:path] = "vendor/bundle" if options[:deployment]
|
|
62
|
+
Carat.settings[:path] = options["path"] if options["path"]
|
|
63
|
+
Carat.settings[:path] ||= "bundle" if options["standalone"]
|
|
64
|
+
Carat.settings[:bin] = options["binstubs"] if options["binstubs"]
|
|
65
|
+
Carat.settings[:bin] = nil if options["binstubs"] && options["binstubs"].empty?
|
|
66
|
+
Carat.settings[:shebang] = options["shebang"] if options["shebang"]
|
|
67
|
+
Carat.settings[:jobs] = options["jobs"] if options["jobs"]
|
|
68
|
+
Carat.settings[:no_prune] = true if options["no-prune"]
|
|
69
|
+
Carat.settings[:no_install] = true if options["no-install"]
|
|
70
|
+
Carat.settings[:clean] = options["clean"] if options["clean"]
|
|
71
|
+
Carat.settings.without = options[:without]
|
|
72
|
+
Carat::Fetcher.disable_endpoint = options["full-index"]
|
|
73
|
+
Carat.settings[:disable_shared_gems] = Carat.settings[:path] ? '1' : nil
|
|
74
|
+
|
|
75
|
+
# rubygems plugins sometimes hook into the gem install process
|
|
76
|
+
Gem.load_env_plugins if Gem.respond_to?(:load_env_plugins)
|
|
77
|
+
|
|
78
|
+
definition = Carat.definition
|
|
79
|
+
definition.validate_ruby!
|
|
80
|
+
Installer.install(Carat.root, definition, options)
|
|
81
|
+
Carat.load.cache if Carat.app_cache.exist? && !options["no-cache"] && !Carat.settings[:frozen]
|
|
82
|
+
|
|
83
|
+
Carat.ui.confirm "Bundle complete! #{dependencies_count_for(definition)}, #{gems_installed_for(definition)}."
|
|
84
|
+
confirm_without_groups
|
|
85
|
+
|
|
86
|
+
if Carat.settings[:path]
|
|
87
|
+
absolute_path = File.expand_path(Carat.settings[:path])
|
|
88
|
+
relative_path = absolute_path.sub(File.expand_path('.'), '.')
|
|
89
|
+
Carat.ui.confirm "Bundled gems are installed into #{relative_path}."
|
|
90
|
+
else
|
|
91
|
+
Carat.ui.confirm "Use `carat show [gemname]` to see where a bundled gem is installed."
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
Installer.post_install_messages.to_a.each do |name, msg|
|
|
95
|
+
Carat.ui.confirm "Post-install message from #{name}:"
|
|
96
|
+
Carat.ui.info msg
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
Installer.ambiguous_gems.to_a.each do |name, installed_from_uri, *also_found_in_uris|
|
|
100
|
+
Carat.ui.error "Warning: the gem '#{name}' was found in multiple sources."
|
|
101
|
+
Carat.ui.error "Installed from: #{installed_from_uri}"
|
|
102
|
+
Carat.ui.error "Also found in:"
|
|
103
|
+
also_found_in_uris.each { |uri| Carat.ui.error " * #{uri}" }
|
|
104
|
+
Carat.ui.error "You should add a source requirement to restrict this gem to your preferred source."
|
|
105
|
+
Carat.ui.error "For example:"
|
|
106
|
+
Carat.ui.error " gem '#{name}', :source => '#{installed_from_uri}'"
|
|
107
|
+
Carat.ui.error "Then uninstall the gem '#{name}' (or delete all bundled gems) and then install again."
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
if Carat.settings[:clean] && Carat.settings[:path]
|
|
111
|
+
require "carat/cli/clean"
|
|
112
|
+
Carat::CLI::Clean.new(options).run
|
|
113
|
+
end
|
|
114
|
+
rescue GemNotFound, VersionConflict => e
|
|
115
|
+
if options[:local] && Carat.app_cache.exist?
|
|
116
|
+
Carat.ui.warn "Some gems seem to be missing from your #{Carat.settings.app_cache_path} directory."
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
unless Carat.definition.has_rubygems_remotes?
|
|
120
|
+
Carat.ui.warn <<-WARN, :wrap => true
|
|
121
|
+
Your Gemfile has no gem server sources. If you need gems that are \
|
|
122
|
+
not already on your machine, add a line like this to your Gemfile:
|
|
123
|
+
source 'https://rubygems.org'
|
|
124
|
+
WARN
|
|
125
|
+
end
|
|
126
|
+
raise e
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
private
|
|
130
|
+
|
|
131
|
+
def warn_if_root
|
|
132
|
+
return if Carat::WINDOWS || !Process.uid.zero?
|
|
133
|
+
Carat.ui.warn "Don't run Carat as root. Carat can ask for sudo " \
|
|
134
|
+
"if it is needed, and installing your bundle as root will break this " \
|
|
135
|
+
"application for all non-root users on this machine.", :wrap => true
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def confirm_without_groups
|
|
139
|
+
if Carat.settings.without.any?
|
|
140
|
+
require "carat/cli/common"
|
|
141
|
+
Carat.ui.confirm Carat::CLI::Common.without_groups_message
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def dependencies_count_for(definition)
|
|
146
|
+
count = definition.dependencies.count
|
|
147
|
+
"#{count} Gemfile #{count == 1 ? 'dependency' : 'dependencies'}"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def gems_installed_for(definition)
|
|
151
|
+
count = definition.specs.count
|
|
152
|
+
"#{count} #{count == 1 ? 'gem' : 'gems'} now installed"
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'carat/cli/common'
|
|
2
|
+
require 'shellwords'
|
|
3
|
+
|
|
4
|
+
module Carat
|
|
5
|
+
class CLI::Open
|
|
6
|
+
attr_reader :options, :name
|
|
7
|
+
def initialize(options, name)
|
|
8
|
+
@options = options
|
|
9
|
+
@name = name
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
editor = [ENV['CARAT_EDITOR'], ENV['VISUAL'], ENV['EDITOR']].find{|e| !e.nil? && !e.empty? }
|
|
14
|
+
return Carat.ui.info("To open a bundled gem, set $EDITOR or $CARAT_EDITOR") unless editor
|
|
15
|
+
path = Carat::CLI::Common.select_spec(name, :regex_match).full_gem_path
|
|
16
|
+
Dir.chdir(path) do
|
|
17
|
+
command = Shellwords.split(editor) + [path]
|
|
18
|
+
system(*command) || Carat.ui.info("Could not run '#{command.join(' ')}'")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require 'carat/cli/common'
|
|
2
|
+
|
|
3
|
+
module Carat
|
|
4
|
+
class CLI::Outdated
|
|
5
|
+
attr_reader :options, :gems
|
|
6
|
+
def initialize(options, gems)
|
|
7
|
+
@options = options
|
|
8
|
+
@gems = gems
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def run
|
|
12
|
+
sources = Array(options[:source])
|
|
13
|
+
|
|
14
|
+
gems.each do |gem_name|
|
|
15
|
+
Carat::CLI::Common.select_spec(gem_name)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Carat.definition.validate_ruby!
|
|
19
|
+
current_specs = Carat.ui.silence { Carat.load.specs }
|
|
20
|
+
current_dependencies = {}
|
|
21
|
+
Carat.ui.silence { Carat.load.dependencies.each { |dep| current_dependencies[dep.name] = dep } }
|
|
22
|
+
|
|
23
|
+
if gems.empty? && sources.empty?
|
|
24
|
+
# We're doing a full update
|
|
25
|
+
definition = Carat.definition(true)
|
|
26
|
+
else
|
|
27
|
+
definition = Carat.definition(:gems => gems, :sources => sources)
|
|
28
|
+
end
|
|
29
|
+
options["local"] ? definition.resolve_with_cache! : definition.resolve_remotely!
|
|
30
|
+
|
|
31
|
+
Carat.ui.info ""
|
|
32
|
+
|
|
33
|
+
out_count = 0
|
|
34
|
+
# Loop through the current specs
|
|
35
|
+
gemfile_specs, dependency_specs = current_specs.partition { |spec| current_dependencies.has_key? spec.name }
|
|
36
|
+
[gemfile_specs.sort_by(&:name), dependency_specs.sort_by(&:name)].flatten.each do |current_spec|
|
|
37
|
+
next if !gems.empty? && !gems.include?(current_spec.name)
|
|
38
|
+
|
|
39
|
+
dependency = current_dependencies[current_spec.name]
|
|
40
|
+
|
|
41
|
+
if options["strict"]
|
|
42
|
+
active_spec = definition.specs.detect { |spec| spec.name == current_spec.name }
|
|
43
|
+
else
|
|
44
|
+
active_spec = definition.index[current_spec.name].sort_by { |b| b.version }
|
|
45
|
+
if !current_spec.version.prerelease? && !options[:pre] && active_spec.size > 1
|
|
46
|
+
active_spec = active_spec.delete_if { |b| b.respond_to?(:version) && b.version.prerelease? }
|
|
47
|
+
end
|
|
48
|
+
active_spec = active_spec.last
|
|
49
|
+
end
|
|
50
|
+
next if active_spec.nil?
|
|
51
|
+
|
|
52
|
+
gem_outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version)
|
|
53
|
+
git_outdated = current_spec.git_version != active_spec.git_version
|
|
54
|
+
if gem_outdated || git_outdated
|
|
55
|
+
if out_count == 0
|
|
56
|
+
if options["pre"]
|
|
57
|
+
Carat.ui.info "Outdated gems included in the bundle (including pre-releases):"
|
|
58
|
+
else
|
|
59
|
+
Carat.ui.info "Outdated gems included in the bundle:"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
spec_version = "#{active_spec.version}#{active_spec.git_version}"
|
|
64
|
+
current_version = "#{current_spec.version}#{current_spec.git_version}"
|
|
65
|
+
dependency_version = %|Gemfile specifies "#{dependency.requirement}"| if dependency && dependency.specific?
|
|
66
|
+
Carat.ui.info " * #{active_spec.name} (#{spec_version} > #{current_version}) #{dependency_version}".rstrip
|
|
67
|
+
out_count += 1
|
|
68
|
+
end
|
|
69
|
+
Carat.ui.debug "from #{active_spec.loaded_from}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
if out_count.zero?
|
|
73
|
+
Carat.ui.info "Bundle up to date!\n"
|
|
74
|
+
else
|
|
75
|
+
exit 1
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Carat
|
|
2
|
+
class CLI::Package
|
|
3
|
+
attr_reader :options
|
|
4
|
+
|
|
5
|
+
def initialize(options)
|
|
6
|
+
@options = options
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def run
|
|
10
|
+
Carat.ui.level = "error" if options[:quiet]
|
|
11
|
+
Carat.settings[:path] = File.expand_path(options[:path]) if options[:path]
|
|
12
|
+
Carat.settings[:cache_all_platforms] = options["all-platforms"] if options.key?("all-platforms")
|
|
13
|
+
Carat.settings[:cache_path] = options["cache-path"] if options.key?("cache-path")
|
|
14
|
+
|
|
15
|
+
setup_cache_all
|
|
16
|
+
install
|
|
17
|
+
|
|
18
|
+
# TODO: move cache contents here now that all bundles are locked
|
|
19
|
+
custom_path = Pathname.new(options[:path]) if options[:path]
|
|
20
|
+
Carat.load.cache(custom_path)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def install
|
|
26
|
+
require 'carat/cli/install'
|
|
27
|
+
options = self.options.dup
|
|
28
|
+
if Carat.settings[:cache_all_platforms]
|
|
29
|
+
options["local"] = false
|
|
30
|
+
options["update"] = true
|
|
31
|
+
end
|
|
32
|
+
Carat::CLI::Install.new(options).run
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def setup_cache_all
|
|
36
|
+
Carat.settings[:cache_all] = options[:all] if options.key?("all")
|
|
37
|
+
|
|
38
|
+
if Carat.definition.has_local_dependencies? && !Carat.settings[:cache_all]
|
|
39
|
+
Carat.ui.warn "Your Gemfile contains path and git dependencies. If you want " \
|
|
40
|
+
"to package them as well, please pass the --all flag. This will be the default " \
|
|
41
|
+
"on Carat 2.0."
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Carat
|
|
2
|
+
class CLI::Platform
|
|
3
|
+
attr_reader :options
|
|
4
|
+
def initialize(options)
|
|
5
|
+
@options = options
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def run
|
|
9
|
+
platforms, ruby_version = Carat.ui.silence do
|
|
10
|
+
[ Carat.definition.platforms.map {|p| "* #{p}" },
|
|
11
|
+
Carat.definition.ruby_version ]
|
|
12
|
+
end
|
|
13
|
+
output = []
|
|
14
|
+
|
|
15
|
+
if options[:ruby]
|
|
16
|
+
if ruby_version
|
|
17
|
+
output << ruby_version
|
|
18
|
+
else
|
|
19
|
+
output << "No ruby version specified"
|
|
20
|
+
end
|
|
21
|
+
else
|
|
22
|
+
output << "Your platform is: #{RUBY_PLATFORM}"
|
|
23
|
+
output << "Your app has gems that work on these platforms:\n#{platforms.join("\n")}"
|
|
24
|
+
|
|
25
|
+
if ruby_version
|
|
26
|
+
output << "Your Gemfile specifies a Ruby version requirement:\n* #{ruby_version}"
|
|
27
|
+
|
|
28
|
+
begin
|
|
29
|
+
Carat.definition.validate_ruby!
|
|
30
|
+
output << "Your current platform satisfies the Ruby version requirement."
|
|
31
|
+
rescue RubyVersionMismatch => e
|
|
32
|
+
output << e.message
|
|
33
|
+
end
|
|
34
|
+
else
|
|
35
|
+
output << "Your Gemfile does not specify a Ruby version requirement."
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Carat.ui.info output.join("\n\n")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'carat/cli/common'
|
|
2
|
+
|
|
3
|
+
module Carat
|
|
4
|
+
class CLI::Show
|
|
5
|
+
attr_reader :options, :gem_name, :latest_specs
|
|
6
|
+
def initialize(options, gem_name)
|
|
7
|
+
@options = options
|
|
8
|
+
@gem_name = gem_name
|
|
9
|
+
@verbose = options[:verbose] || options[:outdated]
|
|
10
|
+
@latest_specs = fetch_latest_specs if @verbose
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def run
|
|
14
|
+
Carat.ui.silence do
|
|
15
|
+
Carat.definition.validate_ruby!
|
|
16
|
+
Carat.load.lock
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if gem_name
|
|
20
|
+
if gem_name == "carat"
|
|
21
|
+
path = File.expand_path("../../../..", __FILE__)
|
|
22
|
+
else
|
|
23
|
+
spec = Carat::CLI::Common.select_spec(gem_name, :regex_match)
|
|
24
|
+
return unless spec
|
|
25
|
+
path = spec.full_gem_path
|
|
26
|
+
if !File.directory?(path)
|
|
27
|
+
Carat.ui.warn "The gem #{gem_name} has been deleted. It was installed at:"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
return Carat.ui.info(path)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if options[:paths]
|
|
34
|
+
Carat.load.specs.sort_by { |s| s.name }.map do |s|
|
|
35
|
+
Carat.ui.info s.full_gem_path
|
|
36
|
+
end
|
|
37
|
+
else
|
|
38
|
+
Carat.ui.info "Gems included by the bundle:"
|
|
39
|
+
Carat.load.specs.sort_by { |s| s.name }.each do |s|
|
|
40
|
+
desc = " * #{s.name} (#{s.version}#{s.git_version})"
|
|
41
|
+
if @verbose
|
|
42
|
+
latest = latest_specs.find { |l| l.name == s.name }
|
|
43
|
+
Carat.ui.info <<-END.gsub(/^ +/, '')
|
|
44
|
+
#{desc}
|
|
45
|
+
\tSummary: #{s.summary || 'No description available.'}
|
|
46
|
+
\tHomepage: #{s.homepage || 'No website available.'}
|
|
47
|
+
\tStatus: #{outdated?(s, latest) ? "Outdated - #{s.version} < #{latest.version}" : "Up to date"}
|
|
48
|
+
END
|
|
49
|
+
else
|
|
50
|
+
Carat.ui.info desc
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def fetch_latest_specs
|
|
59
|
+
definition = Carat.definition(true)
|
|
60
|
+
if options[:outdated]
|
|
61
|
+
Carat.ui.info "Fetching remote specs for outdated check...\n\n"
|
|
62
|
+
Carat.ui.silence { definition.resolve_remotely! }
|
|
63
|
+
else
|
|
64
|
+
definition.resolve_with_cache!
|
|
65
|
+
end
|
|
66
|
+
definition.specs
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def outdated?(current, latest)
|
|
70
|
+
return false unless latest
|
|
71
|
+
Gem::Version.new(current.version) < Gem::Version.new(latest.version)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|