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.
Files changed (184) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +24 -0
  5. data/CHANGELOG.md +2006 -0
  6. data/CODE_OF_CONDUCT.md +40 -0
  7. data/CONTRIBUTING.md +23 -0
  8. data/DEVELOPMENT.md +119 -0
  9. data/ISSUES.md +96 -0
  10. data/LICENSE.md +23 -0
  11. data/README.md +32 -0
  12. data/Rakefile +308 -0
  13. data/bin/carat +21 -0
  14. data/bin/carat_ruby +56 -0
  15. data/carat.gemspec +32 -0
  16. data/lib/carat.rb +446 -0
  17. data/lib/carat/anonymizable_uri.rb +32 -0
  18. data/lib/carat/capistrano.rb +16 -0
  19. data/lib/carat/cli.rb +407 -0
  20. data/lib/carat/cli/binstubs.rb +38 -0
  21. data/lib/carat/cli/cache.rb +35 -0
  22. data/lib/carat/cli/check.rb +35 -0
  23. data/lib/carat/cli/clean.rb +26 -0
  24. data/lib/carat/cli/common.rb +56 -0
  25. data/lib/carat/cli/config.rb +84 -0
  26. data/lib/carat/cli/console.rb +38 -0
  27. data/lib/carat/cli/exec.rb +44 -0
  28. data/lib/carat/cli/gem.rb +195 -0
  29. data/lib/carat/cli/init.rb +33 -0
  30. data/lib/carat/cli/inject.rb +33 -0
  31. data/lib/carat/cli/install.rb +156 -0
  32. data/lib/carat/cli/open.rb +23 -0
  33. data/lib/carat/cli/outdated.rb +80 -0
  34. data/lib/carat/cli/package.rb +45 -0
  35. data/lib/carat/cli/platform.rb +43 -0
  36. data/lib/carat/cli/show.rb +74 -0
  37. data/lib/carat/cli/update.rb +73 -0
  38. data/lib/carat/cli/viz.rb +27 -0
  39. data/lib/carat/constants.rb +5 -0
  40. data/lib/carat/current_ruby.rb +183 -0
  41. data/lib/carat/definition.rb +628 -0
  42. data/lib/carat/dep_proxy.rb +43 -0
  43. data/lib/carat/dependency.rb +110 -0
  44. data/lib/carat/deployment.rb +59 -0
  45. data/lib/carat/deprecate.rb +15 -0
  46. data/lib/carat/dsl.rb +331 -0
  47. data/lib/carat/endpoint_specification.rb +76 -0
  48. data/lib/carat/env.rb +75 -0
  49. data/lib/carat/environment.rb +42 -0
  50. data/lib/carat/fetcher.rb +423 -0
  51. data/lib/carat/friendly_errors.rb +85 -0
  52. data/lib/carat/gem_helper.rb +180 -0
  53. data/lib/carat/gem_helpers.rb +26 -0
  54. data/lib/carat/gem_installer.rb +9 -0
  55. data/lib/carat/gem_path_manipulation.rb +8 -0
  56. data/lib/carat/gem_tasks.rb +2 -0
  57. data/lib/carat/graph.rb +169 -0
  58. data/lib/carat/index.rb +197 -0
  59. data/lib/carat/injector.rb +64 -0
  60. data/lib/carat/installer.rb +339 -0
  61. data/lib/carat/lazy_specification.rb +83 -0
  62. data/lib/carat/lockfile_parser.rb +167 -0
  63. data/lib/carat/match_platform.rb +13 -0
  64. data/lib/carat/psyched_yaml.rb +26 -0
  65. data/lib/carat/remote_specification.rb +57 -0
  66. data/lib/carat/resolver.rb +334 -0
  67. data/lib/carat/retry.rb +60 -0
  68. data/lib/carat/ruby_dsl.rb +11 -0
  69. data/lib/carat/ruby_version.rb +117 -0
  70. data/lib/carat/rubygems_ext.rb +170 -0
  71. data/lib/carat/rubygems_integration.rb +619 -0
  72. data/lib/carat/runtime.rb +289 -0
  73. data/lib/carat/settings.rb +208 -0
  74. data/lib/carat/setup.rb +24 -0
  75. data/lib/carat/shared_helpers.rb +149 -0
  76. data/lib/carat/similarity_detector.rb +63 -0
  77. data/lib/carat/source.rb +46 -0
  78. data/lib/carat/source/git.rb +294 -0
  79. data/lib/carat/source/git/git_proxy.rb +162 -0
  80. data/lib/carat/source/path.rb +226 -0
  81. data/lib/carat/source/path/installer.rb +43 -0
  82. data/lib/carat/source/rubygems.rb +381 -0
  83. data/lib/carat/source_list.rb +101 -0
  84. data/lib/carat/spec_set.rb +154 -0
  85. data/lib/carat/ssl_certs/.document +1 -0
  86. data/lib/carat/ssl_certs/AddTrustExternalCARoot-2048.pem +25 -0
  87. data/lib/carat/ssl_certs/AddTrustExternalCARoot.pem +32 -0
  88. data/lib/carat/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +14 -0
  89. data/lib/carat/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +23 -0
  90. data/lib/carat/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +28 -0
  91. data/lib/carat/ssl_certs/GeoTrustGlobalCA.pem +20 -0
  92. data/lib/carat/ssl_certs/certificate_manager.rb +66 -0
  93. data/lib/carat/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
  94. data/lib/carat/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +23 -0
  95. data/lib/carat/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +25 -0
  96. data/lib/carat/templates/Executable +16 -0
  97. data/lib/carat/templates/Executable.standalone +12 -0
  98. data/lib/carat/templates/Gemfile +4 -0
  99. data/lib/carat/templates/newgem/.travis.yml.tt +3 -0
  100. data/lib/carat/templates/newgem/CODE_OF_CONDUCT.md.tt +13 -0
  101. data/lib/carat/templates/newgem/Gemfile.tt +4 -0
  102. data/lib/carat/templates/newgem/LICENSE.txt.tt +21 -0
  103. data/lib/carat/templates/newgem/README.md.tt +39 -0
  104. data/lib/carat/templates/newgem/Rakefile.tt +25 -0
  105. data/lib/carat/templates/newgem/bin/console.tt +14 -0
  106. data/lib/carat/templates/newgem/bin/setup.tt +7 -0
  107. data/lib/carat/templates/newgem/exe/newgem.tt +3 -0
  108. data/lib/carat/templates/newgem/ext/newgem/extconf.rb.tt +3 -0
  109. data/lib/carat/templates/newgem/ext/newgem/newgem.c.tt +9 -0
  110. data/lib/carat/templates/newgem/ext/newgem/newgem.h.tt +6 -0
  111. data/lib/carat/templates/newgem/gitignore.tt +16 -0
  112. data/lib/carat/templates/newgem/lib/newgem.rb.tt +12 -0
  113. data/lib/carat/templates/newgem/lib/newgem/version.rb.tt +7 -0
  114. data/lib/carat/templates/newgem/newgem.gemspec.tt +43 -0
  115. data/lib/carat/templates/newgem/rspec.tt +2 -0
  116. data/lib/carat/templates/newgem/spec/newgem_spec.rb.tt +11 -0
  117. data/lib/carat/templates/newgem/spec/spec_helper.rb.tt +2 -0
  118. data/lib/carat/templates/newgem/test/minitest_helper.rb.tt +4 -0
  119. data/lib/carat/templates/newgem/test/test_newgem.rb.tt +11 -0
  120. data/lib/carat/ui.rb +7 -0
  121. data/lib/carat/ui/rg_proxy.rb +21 -0
  122. data/lib/carat/ui/shell.rb +103 -0
  123. data/lib/carat/ui/silent.rb +44 -0
  124. data/lib/carat/vendor/molinillo/lib/molinillo.rb +5 -0
  125. data/lib/carat/vendor/molinillo/lib/molinillo/dependency_graph.rb +266 -0
  126. data/lib/carat/vendor/molinillo/lib/molinillo/errors.rb +69 -0
  127. data/lib/carat/vendor/molinillo/lib/molinillo/gem_metadata.rb +3 -0
  128. data/lib/carat/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +90 -0
  129. data/lib/carat/vendor/molinillo/lib/molinillo/modules/ui.rb +63 -0
  130. data/lib/carat/vendor/molinillo/lib/molinillo/resolution.rb +415 -0
  131. data/lib/carat/vendor/molinillo/lib/molinillo/resolver.rb +43 -0
  132. data/lib/carat/vendor/molinillo/lib/molinillo/state.rb +43 -0
  133. data/lib/carat/vendor/net/http/faster.rb +26 -0
  134. data/lib/carat/vendor/net/http/persistent.rb +1230 -0
  135. data/lib/carat/vendor/net/http/persistent/ssl_reuse.rb +128 -0
  136. data/lib/carat/vendor/thor/lib/thor.rb +484 -0
  137. data/lib/carat/vendor/thor/lib/thor/actions.rb +319 -0
  138. data/lib/carat/vendor/thor/lib/thor/actions/create_file.rb +103 -0
  139. data/lib/carat/vendor/thor/lib/thor/actions/create_link.rb +59 -0
  140. data/lib/carat/vendor/thor/lib/thor/actions/directory.rb +118 -0
  141. data/lib/carat/vendor/thor/lib/thor/actions/empty_directory.rb +135 -0
  142. data/lib/carat/vendor/thor/lib/thor/actions/file_manipulation.rb +316 -0
  143. data/lib/carat/vendor/thor/lib/thor/actions/inject_into_file.rb +107 -0
  144. data/lib/carat/vendor/thor/lib/thor/base.rb +656 -0
  145. data/lib/carat/vendor/thor/lib/thor/command.rb +133 -0
  146. data/lib/carat/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +77 -0
  147. data/lib/carat/vendor/thor/lib/thor/core_ext/io_binary_read.rb +10 -0
  148. data/lib/carat/vendor/thor/lib/thor/core_ext/ordered_hash.rb +98 -0
  149. data/lib/carat/vendor/thor/lib/thor/error.rb +32 -0
  150. data/lib/carat/vendor/thor/lib/thor/group.rb +281 -0
  151. data/lib/carat/vendor/thor/lib/thor/invocation.rb +178 -0
  152. data/lib/carat/vendor/thor/lib/thor/line_editor.rb +17 -0
  153. data/lib/carat/vendor/thor/lib/thor/line_editor/basic.rb +35 -0
  154. data/lib/carat/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
  155. data/lib/carat/vendor/thor/lib/thor/parser.rb +4 -0
  156. data/lib/carat/vendor/thor/lib/thor/parser/argument.rb +73 -0
  157. data/lib/carat/vendor/thor/lib/thor/parser/arguments.rb +175 -0
  158. data/lib/carat/vendor/thor/lib/thor/parser/option.rb +125 -0
  159. data/lib/carat/vendor/thor/lib/thor/parser/options.rb +218 -0
  160. data/lib/carat/vendor/thor/lib/thor/rake_compat.rb +71 -0
  161. data/lib/carat/vendor/thor/lib/thor/runner.rb +322 -0
  162. data/lib/carat/vendor/thor/lib/thor/shell.rb +81 -0
  163. data/lib/carat/vendor/thor/lib/thor/shell/basic.rb +421 -0
  164. data/lib/carat/vendor/thor/lib/thor/shell/color.rb +149 -0
  165. data/lib/carat/vendor/thor/lib/thor/shell/html.rb +126 -0
  166. data/lib/carat/vendor/thor/lib/thor/util.rb +267 -0
  167. data/lib/carat/vendor/thor/lib/thor/version.rb +3 -0
  168. data/lib/carat/vendored_fileutils.rb +9 -0
  169. data/lib/carat/vendored_molinillo.rb +2 -0
  170. data/lib/carat/vendored_persistent.rb +11 -0
  171. data/lib/carat/vendored_thor.rb +3 -0
  172. data/lib/carat/version.rb +6 -0
  173. data/lib/carat/vlad.rb +11 -0
  174. data/lib/carat/worker.rb +73 -0
  175. data/man/carat-config.ronn +178 -0
  176. data/man/carat-exec.ronn +136 -0
  177. data/man/carat-install.ronn +383 -0
  178. data/man/carat-package.ronn +66 -0
  179. data/man/carat-platform.ronn +42 -0
  180. data/man/carat-update.ronn +188 -0
  181. data/man/carat.ronn +98 -0
  182. data/man/gemfile.5.ronn +473 -0
  183. data/man/index.txt +7 -0
  184. 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