berkshelf 3.0.0.beta7 → 3.0.0.beta8

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +4 -1
  4. data/CONTRIBUTING.md +1 -1
  5. data/Gemfile +0 -1
  6. data/Guardfile +0 -8
  7. data/README.md +33 -13
  8. data/berkshelf.gemspec +3 -3
  9. data/features/commands/install.feature +16 -88
  10. data/features/commands/search.feature +15 -0
  11. data/features/commands/shelf/show.feature +2 -2
  12. data/features/commands/shelf/uninstall.feature +1 -1
  13. data/features/commands/show.feature +3 -3
  14. data/features/commands/update.feature +29 -1
  15. data/features/commands/upload.feature +172 -7
  16. data/features/commands/vendor.feature +32 -0
  17. data/features/json_formatter.feature +26 -24
  18. data/features/lifecycle.feature +285 -0
  19. data/features/lockfile.feature +9 -7
  20. data/features/step_definitions/chef_server_steps.rb +1 -0
  21. data/features/step_definitions/cli_steps.rb +2 -2
  22. data/features/step_definitions/filesystem_steps.rb +2 -4
  23. data/gem_graph.png +0 -0
  24. data/generator_files/chefignore +0 -2
  25. data/lib/berkshelf.rb +39 -14
  26. data/lib/berkshelf/berksfile.rb +161 -113
  27. data/lib/berkshelf/cached_cookbook.rb +2 -2
  28. data/lib/berkshelf/cli.rb +15 -3
  29. data/lib/berkshelf/commands/shelf.rb +3 -7
  30. data/lib/berkshelf/community_rest.rb +9 -9
  31. data/lib/berkshelf/config.rb +3 -3
  32. data/lib/berkshelf/cookbook_generator.rb +0 -8
  33. data/lib/berkshelf/cookbook_store.rb +1 -2
  34. data/lib/berkshelf/dependency.rb +25 -138
  35. data/lib/berkshelf/downloader.rb +41 -7
  36. data/lib/berkshelf/errors.rb +113 -214
  37. data/lib/berkshelf/formatters/base.rb +42 -0
  38. data/lib/berkshelf/formatters/human.rb +145 -0
  39. data/lib/berkshelf/formatters/json.rb +149 -133
  40. data/lib/berkshelf/formatters/null.rb +8 -18
  41. data/lib/berkshelf/init_generator.rb +1 -1
  42. data/lib/berkshelf/installer.rb +115 -104
  43. data/lib/berkshelf/location.rb +22 -121
  44. data/lib/berkshelf/locations/base.rb +75 -0
  45. data/lib/berkshelf/locations/git.rb +196 -0
  46. data/lib/berkshelf/locations/github.rb +8 -0
  47. data/lib/berkshelf/locations/path.rb +78 -0
  48. data/lib/berkshelf/lockfile.rb +452 -290
  49. data/lib/berkshelf/logger.rb +9 -3
  50. data/lib/berkshelf/mixin/logging.rb +4 -9
  51. data/lib/berkshelf/resolver.rb +12 -12
  52. data/lib/berkshelf/source.rb +13 -1
  53. data/lib/berkshelf/version.rb +1 -1
  54. data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +3 -7
  55. data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +3 -6
  56. data/spec/spec_helper.rb +5 -6
  57. data/spec/support/matchers/file_system_matchers.rb +4 -0
  58. data/spec/support/shared_examples/formatter.rb +11 -0
  59. data/spec/unit/berkshelf/berksfile_spec.rb +25 -28
  60. data/spec/unit/berkshelf/cli_spec.rb +19 -11
  61. data/spec/unit/berkshelf/dependency_spec.rb +4 -164
  62. data/spec/unit/berkshelf/formatters/base_spec.rb +35 -0
  63. data/spec/unit/berkshelf/formatters/human_spec.rb +7 -0
  64. data/spec/unit/berkshelf/formatters/json_spec.rb +7 -0
  65. data/spec/unit/berkshelf/formatters/null_spec.rb +7 -11
  66. data/spec/unit/berkshelf/location_spec.rb +16 -144
  67. data/spec/unit/berkshelf/locations/base_spec.rb +80 -0
  68. data/spec/unit/berkshelf/locations/git_spec.rb +249 -0
  69. data/spec/unit/berkshelf/locations/path_spec.rb +107 -0
  70. data/spec/unit/berkshelf/lockfile_parser_spec.rb +3 -3
  71. data/spec/unit/berkshelf/lockfile_spec.rb +55 -11
  72. data/spec/unit/berkshelf/logger_spec.rb +2 -2
  73. data/spec/unit/berkshelf/mixin/logging_spec.rb +5 -9
  74. data/spec/unit/berkshelf/source_spec.rb +32 -13
  75. data/spec/unit/berkshelf_spec.rb +6 -9
  76. metadata +33 -33
  77. data/.ruby-version +0 -1
  78. data/berkshelf-complete.sh +0 -75
  79. data/lib/berkshelf/formatters.rb +0 -110
  80. data/lib/berkshelf/formatters/human_readable.rb +0 -142
  81. data/lib/berkshelf/git.rb +0 -204
  82. data/lib/berkshelf/locations/git_location.rb +0 -135
  83. data/lib/berkshelf/locations/github_location.rb +0 -55
  84. data/lib/berkshelf/locations/mercurial_location.rb +0 -114
  85. data/lib/berkshelf/locations/path_location.rb +0 -88
  86. data/lib/berkshelf/mercurial.rb +0 -146
  87. data/lib/berkshelf/mixin.rb +0 -7
  88. data/spec/support/mercurial.rb +0 -123
  89. data/spec/unit/berkshelf/formatters_spec.rb +0 -114
  90. data/spec/unit/berkshelf/git_spec.rb +0 -312
  91. data/spec/unit/berkshelf/locations/git_location_spec.rb +0 -126
  92. data/spec/unit/berkshelf/locations/mercurial_location_spec.rb +0 -131
  93. data/spec/unit/berkshelf/locations/path_location_spec.rb +0 -25
  94. data/spec/unit/berkshelf/mercurial_spec.rb +0 -172
@@ -0,0 +1,42 @@
1
+ module Berkshelf
2
+ class BaseFormatter
3
+ class << self
4
+ #
5
+ # @macro formatter_method
6
+ # @method $1(*args)
7
+ # Create a formatter method for the declaration
8
+ #
9
+ def formatter_method(name)
10
+ class_eval <<-EOH, __FILE__, __LINE__ + 1
11
+ def #{name}(*args)
12
+ raise AbstractFunction,
13
+ "##{name} must be implemented on \#{self.class.name}!"
14
+ end
15
+ EOH
16
+ end
17
+ end
18
+
19
+ # UI methods
20
+ formatter_method :deprecation
21
+ formatter_method :error
22
+ formatter_method :msg
23
+ formatter_method :warn
24
+
25
+ # Object methods
26
+ formatter_method :fetch
27
+ formatter_method :install
28
+ formatter_method :list
29
+ formatter_method :outdated
30
+ formatter_method :package
31
+ formatter_method :search
32
+ formatter_method :show
33
+ formatter_method :skip
34
+ formatter_method :upload
35
+ formatter_method :use
36
+ formatter_method :vendor
37
+ formatter_method :version
38
+
39
+ # The cleanup hook is defined by subclasses and is called by the CLI.
40
+ def cleanup_hook; end
41
+ end
42
+ end
@@ -0,0 +1,145 @@
1
+ module Berkshelf
2
+ class HumanFormatter < BaseFormatter
3
+ # Output the version of Berkshelf
4
+ def version
5
+ Berkshelf.ui.info Berkshelf::VERSION
6
+ end
7
+
8
+ # @param [Berkshelf::Dependency] dependency
9
+ def fetch(dependency)
10
+ Berkshelf.ui.info "Fetching '#{dependency.name}' from #{dependency.location}"
11
+ end
12
+
13
+ # Output a Cookbook installation message using {Berkshelf.ui}
14
+ #
15
+ # @param [Source] source
16
+ # the source the dependency is being downloaded from
17
+ # @param [RemoteCookbook] cookbook
18
+ # the cookbook to be downloaded
19
+ def install(source, cookbook)
20
+ message = "Installing #{cookbook.name} (#{cookbook.version})"
21
+
22
+ unless source.default?
23
+ message << " from #{source}"
24
+ message << " ([#{cookbook.location_type}] #{cookbook.location_path})"
25
+ end
26
+
27
+ Berkshelf.ui.info(message)
28
+ end
29
+
30
+ # Output a Cookbook use message using {Berkshelf.ui}
31
+ #
32
+ # @param [Dependency] dependency
33
+ def use(dependency)
34
+ message = "Using #{dependency.name} (#{dependency.locked_version})"
35
+ message << " from #{dependency.location}" if dependency.location
36
+ Berkshelf.ui.info(message)
37
+ end
38
+
39
+ # Output a Cookbook upload message using {Berkshelf.ui}
40
+ #
41
+ # @param [Berkshelf::CachedCookbook] cookbook
42
+ # @param [Ridley::Connection] conn
43
+ def upload(cookbook, conn)
44
+ Berkshelf.ui.info "Uploading #{cookbook.cookbook_name} (#{cookbook.version}) to: '#{conn.server_url}'"
45
+ end
46
+
47
+ # Output a Cookbook skip message using {Berkshelf.ui}
48
+ #
49
+ # @param [Berkshelf::CachedCookbook] cookbook
50
+ # @param [Ridley::Connection] conn
51
+ def skip(cookbook, conn)
52
+ Berkshelf.ui.info "Skipping #{cookbook.cookbook_name} (#{cookbook.version}) (frozen)"
53
+ end
54
+
55
+ # Output a list of outdated cookbooks and the most recent version
56
+ # using {Berkshelf.ui}
57
+ #
58
+ # @param [Hash] hash
59
+ # the list of outdated cookbooks in the format
60
+ # { 'cookbook' => { 'api.berkshelf.com' => #<Cookbook> } }
61
+ def outdated(hash)
62
+ hash.keys.each do |name|
63
+ hash[name].each do |source, newest|
64
+ string = " * #{newest.name} (#{newest.version})"
65
+ unless source == Berksfile::DEFAULT_API_URL
66
+ string << " [#{source}]"
67
+ end
68
+ Berkshelf.ui.info string
69
+ end
70
+ end
71
+ end
72
+
73
+ # Output a Cookbook package message using {Berkshelf.ui}
74
+ #
75
+ # @param [String] destination
76
+ def package(destination)
77
+ Berkshelf.ui.info "Cookbook(s) packaged to #{destination}"
78
+ end
79
+
80
+ # Output a list of cookbooks using {Berkshelf.ui}
81
+ #
82
+ # @param [Array<Dependency>] list
83
+ def list(dependencies)
84
+ Berkshelf.ui.info "Cookbooks installed by your Berksfile:"
85
+ dependencies.each do |dependency|
86
+ out = " * #{dependency}"
87
+ out << " from #{dependency.location}" if dependency.location
88
+ Berkshelf.ui.info(out)
89
+ end
90
+ end
91
+
92
+ # Ouput Cookbook search results using {Berkshelf.ui}
93
+ #
94
+ # @param [Array<APIClient::RemoteCookbook>] results
95
+ def search(results)
96
+ results.sort_by(&:name).each do |remote_cookbook|
97
+ Berkshelf.ui.info "#{remote_cookbook.name} (#{remote_cookbook.version})"
98
+ end
99
+ end
100
+
101
+ # Output Cookbook info message using {Berkshelf.ui}
102
+ #
103
+ # @param [CachedCookbook] cookbook
104
+ def show(cookbook)
105
+ Berkshelf.ui.info(cookbook.pretty_print)
106
+ end
107
+
108
+ # Output Cookbook vendor info message using {Berkshelf.ui}
109
+ #
110
+ # @param [CachedCookbook] cookbook
111
+ # @param [String] destination
112
+ def vendor(cookbook, destination)
113
+ cookbook_destination = File.join(destination, cookbook.cookbook_name)
114
+ Berkshelf.ui.info "Vendoring #{cookbook.cookbook_name} (#{cookbook.version}) to #{cookbook_destination}"
115
+ end
116
+
117
+ # Output a generic message using {Berkshelf.ui}
118
+ #
119
+ # @param [String] message
120
+ def msg(message)
121
+ Berkshelf.ui.info message
122
+ end
123
+
124
+ # Output an error message using {Berkshelf.ui}
125
+ #
126
+ # @param [String] message
127
+ def error(message)
128
+ Berkshelf.ui.error message
129
+ end
130
+
131
+ # Output a warning message using {Berkshelf.ui}
132
+ #
133
+ # @param [String] message
134
+ def warn(message)
135
+ Berkshelf.ui.warn message
136
+ end
137
+
138
+ # Output a deprecation warning
139
+ #
140
+ # @param [String] message
141
+ def deprecation(message)
142
+ Berkshelf.ui.info "DEPRECATED: #{message}"
143
+ end
144
+ end
145
+ end
@@ -1,164 +1,180 @@
1
1
  module Berkshelf
2
- module Formatters
3
- class JSON
4
- include AbstractFormatter
5
-
6
- register_formatter :json
2
+ class JsonFormatter < BaseFormatter
3
+ # Output the version of Berkshelf
4
+ def version
5
+ @output = { version: Berkshelf::VERSION }
6
+ end
7
7
 
8
- # Output the version of Berkshelf
9
- def version
10
- @output = { version: Berkshelf::VERSION }
11
- end
8
+ def initialize
9
+ @output = {
10
+ cookbooks: [],
11
+ errors: [],
12
+ messages: [],
13
+ warnings: [],
14
+ }
15
+ @cookbooks = Hash.new
12
16
 
13
- def initialize
14
- @output = {
15
- cookbooks: Array.new,
16
- errors: Array.new,
17
- messages: Array.new
18
- }
19
- @cookbooks = Hash.new
17
+ Berkshelf.ui.mute { super }
18
+ end
20
19
 
21
- Berkshelf.ui.mute { super }
20
+ def cleanup_hook
21
+ cookbooks.each do |name, details|
22
+ details[:name] = name
23
+ output[:cookbooks] << details
22
24
  end
23
25
 
24
- def cleanup_hook
25
- cookbooks.each do |name, details|
26
- details[:name] = name
27
- output[:cookbooks] << details
28
- end
29
-
30
- puts ::JSON.pretty_generate(output)
31
- end
26
+ puts ::JSON.pretty_generate(output)
27
+ end
32
28
 
33
- # @param [Berkshelf::Dependency] dependency
34
- def fetch(dependency)
35
- cookbooks[dependency] ||= {}
36
- cookbooks[dependency][:version] = dependency.locked_version.to_s
37
- cookbooks[dependency][:location] = dependency.location
38
- end
29
+ # @param [Berkshelf::Dependency] dependency
30
+ def fetch(dependency)
31
+ cookbooks[dependency] ||= {}
32
+ cookbooks[dependency][:version] = dependency.locked_version.to_s
33
+ cookbooks[dependency][:location] = dependency.location
34
+ end
39
35
 
40
- # Add a Cookbook installation entry to delayed output
41
- #
42
- # @param [Source] source
43
- # the source the dependency is being downloaded from
44
- # @param [RemoteCookbook] cookbook
45
- # the cookbook to be downloaded
46
- def install(source, cookbook)
47
- cookbooks[cookbook.name] ||= {}
48
- cookbooks[cookbook.name][:version] = cookbook.version
49
-
50
- unless source.default?
51
- cookbooks[cookbook.name][:api_source] = source.uri
52
- cookbooks[cookbook.name][:location_path] = cookbook.location_path
53
- end
36
+ # Add a Cookbook installation entry to delayed output
37
+ #
38
+ # @param [Source] source
39
+ # the source the dependency is being downloaded from
40
+ # @param [RemoteCookbook] cookbook
41
+ # the cookbook to be downloaded
42
+ def install(source, cookbook)
43
+ cookbooks[cookbook.name] ||= {}
44
+ cookbooks[cookbook.name][:version] = cookbook.version
45
+
46
+ unless source.default?
47
+ cookbooks[cookbook.name][:api_source] = source.uri
48
+ cookbooks[cookbook.name][:location_path] = cookbook.location_path
54
49
  end
50
+ end
55
51
 
56
- # Add a Cookbook use entry to delayed output
57
- #
58
- # @param [Dependency] dependency
59
- def use(dependency)
60
- cookbooks[dependency.name] ||= {}
61
- cookbooks[dependency.name][:version] = dependency.cached_cookbook.version
52
+ # Add a Cookbook use entry to delayed output
53
+ #
54
+ # @param [Dependency] dependency
55
+ def use(dependency)
56
+ cookbooks[dependency.name] ||= {}
57
+ cookbooks[dependency.name][:version] = dependency.cached_cookbook.version
62
58
 
63
- if dependency.location.is_a?(PathLocation)
64
- cookbooks[dependency.name][:metadata] = true if dependency.location.metadata?
65
- cookbooks[dependency.name][:location] = dependency.location.relative_path
66
- end
59
+ if dependency.location.is_a?(PathLocation)
60
+ cookbooks[dependency.name][:metadata] = true if dependency.location.metadata?
61
+ cookbooks[dependency.name][:location] = dependency.location.relative_path
67
62
  end
63
+ end
68
64
 
69
- # Add a Cookbook upload entry to delayed output
70
- #
71
- # @param [Berkshelf::CachedCookbook] cookbook
72
- # @param [Ridley::Connection] conn
73
- def upload(cookbook, conn)
74
- name = cookbook.cookbook_name
75
- cookbooks[name] ||= {}
76
- cookbooks[name][:version] = cookbook.version
77
- cookbooks[name][:uploaded_to] = conn.server_url
78
- end
65
+ # Add a Cookbook upload entry to delayed output
66
+ #
67
+ # @param [Berkshelf::CachedCookbook] cookbook
68
+ # @param [Ridley::Connection] conn
69
+ def upload(cookbook, conn)
70
+ name = cookbook.cookbook_name
71
+ cookbooks[name] ||= {}
72
+ cookbooks[name][:version] = cookbook.version
73
+ cookbooks[name][:uploaded_to] = conn.server_url
74
+ end
79
75
 
80
- # Add a Cookbook skip entry to delayed output
81
- #
82
- # @param [Berkshelf::CachedCookbook] cookbook
83
- # @param [Ridley::Connection] conn
84
- def skip(cookbook, conn)
85
- name = cookbook.cookbook_name
86
- cookbooks[name] ||= {}
87
- cookbooks[name][:version] = cookbook.version
88
- cookbooks[name][:skipped] = true
89
- end
76
+ # Add a Cookbook skip entry to delayed output
77
+ #
78
+ # @param [Berkshelf::CachedCookbook] cookbook
79
+ # @param [Ridley::Connection] conn
80
+ def skip(cookbook, conn)
81
+ name = cookbook.cookbook_name
82
+ cookbooks[name] ||= {}
83
+ cookbooks[name][:version] = cookbook.version
84
+ cookbooks[name][:skipped] = true
85
+ end
90
86
 
91
- # Output a list of outdated cookbooks and the most recent version
92
- # to delayed output
93
- #
94
- # @param [Hash] hash
95
- # the list of outdated cookbooks in the format
96
- # { 'cookbook' => { 'api.berkshelf.com' => #<Cookbook> } }
97
- def outdated(hash)
98
- hash.keys.each do |name|
99
- hash[name].each do |source, cookbook|
100
- cookbooks[name] ||= {}
101
- cookbooks[name][:version] = cookbook.version
102
- cookbooks[name][:sources] ||= {}
103
- cookbooks[name][:sources][source] = cookbook
104
- end
87
+ # Output a list of outdated cookbooks and the most recent version
88
+ # to delayed output
89
+ #
90
+ # @param [Hash] hash
91
+ # the list of outdated cookbooks in the format
92
+ # { 'cookbook' => { 'api.berkshelf.com' => #<Cookbook> } }
93
+ def outdated(hash)
94
+ hash.keys.each do |name|
95
+ hash[name].each do |source, cookbook|
96
+ cookbooks[name] ||= {}
97
+ cookbooks[name][:version] = cookbook.version
98
+ cookbooks[name][:sources] ||= {}
99
+ cookbooks[name][:sources][source] = cookbook
105
100
  end
106
101
  end
102
+ end
107
103
 
108
- # Output a list of cookbooks to delayed output
109
- #
110
- # @param [Array<Dependency>] dependencies
111
- def list(dependencies)
112
- dependencies.each do |dependency, cookbook|
113
- cookbooks[dependency.name] ||= {}
114
- cookbooks[dependency.name][:version] = dependency.locked_version.to_s
115
- if dependency.location
116
- cookbooks[dependency.name][:location] = dependency.location
117
- end
104
+ # Output a package message using
105
+ #
106
+ # @param [String] destination
107
+ def package(destination)
108
+ output[:messages] << "Cookbook(s) packaged to #{destination}"
109
+ end
110
+
111
+ # Output a list of cookbooks to delayed output
112
+ #
113
+ # @param [Array<Dependency>] dependencies
114
+ def list(dependencies)
115
+ dependencies.each do |dependency, cookbook|
116
+ cookbooks[dependency.name] ||= {}
117
+ cookbooks[dependency.name][:version] = dependency.locked_version.to_s
118
+ if dependency.location
119
+ cookbooks[dependency.name][:location] = dependency.location
118
120
  end
119
121
  end
122
+ end
120
123
 
121
- # Output Cookbook info entry to delayed output
122
- #
123
- # @param [CachedCookbook] cookbook
124
- def show(cookbook)
125
- cookbooks[cookbook.cookbook_name] = cookbook.pretty_hash
126
- end
124
+ # Output Cookbook info entry to delayed output
125
+ #
126
+ # @param [CachedCookbook] cookbook
127
+ def show(cookbook)
128
+ cookbooks[cookbook.cookbook_name] = cookbook.pretty_hash
129
+ end
127
130
 
128
- # Add a vendor message to delayed output
129
- #
130
- # @param [CachedCookbook] cookbook
131
- # @param [String] destination
132
- def vendor(cookbook, destination)
133
- cookbook_destination = File.join(destination, cookbook.cookbook_name)
134
- msg("Vendoring #{cookbook.cookbook_name} (#{cookbook.version}) to #{cookbook_destination}")
131
+ # Ouput Cookbook search results to delayed output
132
+ #
133
+ # @param [Array<APIClient::RemoteCookbook>] results
134
+ def search(results)
135
+ results.sort_by(&:name).each do |remote_cookbook|
136
+ cookbooks[remote_cookbook.name] ||= {}
137
+ cookbooks[remote_cookbook.name][:version] = remote_cookbook.version
135
138
  end
139
+ end
136
140
 
137
- # Add a generic message entry to delayed output
138
- #
139
- # @param [String] message
140
- def msg(message)
141
- output[:messages] << message
142
- end
141
+ # Add a vendor message to delayed output
142
+ #
143
+ # @param [CachedCookbook] cookbook
144
+ # @param [String] destination
145
+ def vendor(cookbook, destination)
146
+ cookbook_destination = File.join(destination, cookbook.cookbook_name)
147
+ msg("Vendoring #{cookbook.cookbook_name} (#{cookbook.version}) to #{cookbook_destination}")
148
+ end
143
149
 
144
- # Add an error message entry to delayed output
145
- #
146
- # @param [String] message
147
- def error(message)
148
- output[:errors] << message
149
- end
150
+ # Add a generic message entry to delayed output
151
+ #
152
+ # @param [String] message
153
+ def msg(message)
154
+ output[:messages] << message
155
+ end
150
156
 
151
- # Add a warning message entry to delayed output
152
- #
153
- # @param [String] message
154
- def warn(message)
155
- output[:warnings] << message
156
- end
157
+ # Add an error message entry to delayed output
158
+ #
159
+ # @param [String] message
160
+ def error(message)
161
+ output[:errors] << message
162
+ end
157
163
 
158
- private
164
+ # Add a warning message entry to delayed output
165
+ #
166
+ # @param [String] message
167
+ def warn(message)
168
+ output[:warnings] << message
169
+ end
159
170
 
160
- attr_reader :output
161
- attr_reader :cookbooks
171
+ def deprecation(message)
172
+ output[:warnings] << "DEPRECATED: #{message}"
162
173
  end
174
+
175
+ private
176
+
177
+ attr_reader :output
178
+ attr_reader :cookbooks
163
179
  end
164
180
  end