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
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.0.0-p353
@@ -1,75 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # Description
4
- # Add tab completion for berkshelf
5
- #
6
- # Configuration:
7
- # BERKSHELF_BERKSFILE (default is 'Berksfile')
8
- #
9
- # Notes:
10
- # Must be added to your ~/.bashrc, ~/.zshrc, etc
11
- #
12
- # Author:
13
- # Seth Vargo <sethvargo@gmail.com>
14
- #
15
- # License:
16
- # Apache 2.0
17
- #
18
-
19
- _bundler() {
20
- which bundle > /dev/null 2>&1 && [ -f "$(pwd)/Gemfile" ]
21
- }
22
-
23
- # Overwrite berks to use bundler if defined
24
- _berks() {
25
- [ _bundler ] && bundle exec berks $@ || berks $@
26
- }
27
-
28
- _berkshelf_commands() {
29
- local cachefile=~/.berkshelf/.commands
30
- [ ! -f $cachefile ] && $(_berks help | grep berks | cut -d " " -f 4 > $cachefile)
31
- cat $cachefile
32
- }
33
-
34
- _berkshelf_cookbooks() {
35
- local file=${BERKSHELF_BERKSFILE:-Berksfile}
36
- if [ -e $file ]; then
37
- # strip all quotes from cookbook name and remove trailing comma, if any
38
- grep -w '^cookbook' $file \
39
- | awk '{ print $2 }' \
40
- | sed 's/"//g' \
41
- | sed "s/'//g" \
42
- | sed 's/,$//'
43
- fi
44
- }
45
-
46
- _local_cookbooks() {
47
- [ -d cookbooks ] && ls -d cookbooks/*/ | cut -d "/" -f 2
48
- }
49
-
50
- _berkshelf() {
51
- # local curr prev commands
52
- COMPREPLY=()
53
- curr="${COMP_WORDS[COMP_CWORD]}"
54
- prev="${COMP_WORDS[COMP_CWORD-1]}"
55
-
56
- # List of commands to complete
57
- commands=`_berkshelf_commands`
58
-
59
- case "${prev}" in
60
- "open"|"outdated"|"show"|"update"|"upload")
61
- local berkshelf_cookbooks=`_berkshelf_cookbooks`
62
- local local_cookbooks=`_local_cookbooks`
63
- local cookbooks=`echo $berkshelf_cookbooks $local_cookbooks | sort -n | uniq`
64
- COMPREPLY=($(compgen -W "${cookbooks}" -- ${curr}))
65
- return 0
66
- ;;
67
- *)
68
- ;;
69
- esac
70
-
71
- COMPREPLY=($(compgen -W "${commands}" -- ${curr}))
72
- return 0
73
- }
74
-
75
- complete -F _berkshelf berks
@@ -1,110 +0,0 @@
1
- module Berkshelf
2
- module Formatters
3
- class << self
4
- @@formatters = Hash.new
5
-
6
- # Access the formatters map that links string symbols to Formatter
7
- # implementations
8
- #
9
- # @return [Hash]
10
- def formatters
11
- @@formatters
12
- end
13
-
14
- # @param [#to_sym] id
15
- # @param [Constant] klass
16
- #
17
- # @raise [Berkshelf::InternalError] if an ID that has already been registered is attempted
18
- # to be registered again
19
- #
20
- # @return [Hash]
21
- # a hash of registered formatters
22
- def register(id, klass)
23
- unless id.respond_to?(:to_sym)
24
- raise ArgumentError, "Invalid Formatter ID: must respond to #to_sym. You gave: #{id}"
25
- end
26
-
27
- id = id.to_sym
28
- if self.formatters.has_key?(id)
29
- raise Berkshelf::InternalError, "Formatter ID '#{id}' already registered"
30
- end
31
-
32
- self.formatters[id] = klass
33
- end
34
-
35
- # @param [#to_sym] id
36
- #
37
- # @return [~AbstractFormatter, nil]
38
- def get(id)
39
- unless id.respond_to?(:to_sym)
40
- raise ArgumentError, "Invalid Formatter ID: must respond to #to_sym. You gave: #{id}"
41
- end
42
-
43
- self.formatters.fetch(id.to_sym, nil)
44
- end
45
- alias_method :[], :get
46
- end
47
-
48
- # @abstract Include and override {#install} {#use} {#upload}
49
- # {#msg} {#error} to implement.
50
- #
51
- # Implement {#cleanup_hook} to run any steps required to run after the task is finished
52
- module AbstractFormatter
53
- module ClassMethods
54
- # @param [Symbol] id
55
- #
56
- # @raise [Berkshelf::InternalError] if an ID that has already been registered is attempted
57
- # to be registered again
58
- #
59
- # @return [Hash]
60
- # a hash of registered formatters
61
- def register_formatter(id)
62
- Formatters.register(id, self)
63
- end
64
- end
65
-
66
- class << self
67
- def included(base)
68
- base.send(:extend, ClassMethods)
69
- end
70
-
71
- private
72
-
73
- def formatter_methods(*args)
74
- args.each do |meth|
75
- define_method(meth.to_sym) do |*args|
76
- raise AbstractFunction, "##{meth} must be implemented on #{self.class}"
77
- end unless respond_to?(meth.to_sym)
78
- end
79
- end
80
- end
81
-
82
- formatter_methods :error,
83
- :warn,
84
- :fetch,
85
- :install,
86
- :list,
87
- :msg,
88
- :outdated,
89
- :package,
90
- :skip,
91
- :show,
92
- :upload,
93
- :use,
94
- :vendor,
95
- :version
96
-
97
- def cleanup_hook
98
- # run after the task is finished
99
- end
100
-
101
- private
102
-
103
- attr_reader :args
104
- end
105
- end
106
- end
107
-
108
- Dir["#{File.dirname(__FILE__)}/formatters/*.rb"].sort.each do |path|
109
- require_relative "formatters/#{File.basename(path, '.rb')}"
110
- end
@@ -1,142 +0,0 @@
1
- module Berkshelf
2
- module Formatters
3
- class HumanReadable
4
- include AbstractFormatter
5
-
6
- register_formatter :human
7
-
8
- # Output the version of Berkshelf
9
- def version
10
- Berkshelf.ui.info Berkshelf::VERSION
11
- end
12
-
13
- # @param [Berkshelf::Dependency] dependency
14
- def fetch(dependency)
15
- Berkshelf.ui.info "Fetching '#{dependency.name}' from #{dependency.location}"
16
- end
17
-
18
- # Output a Cookbook installation message using {Berkshelf.ui}
19
- #
20
- # @param [Source] source
21
- # the source the dependency is being downloaded from
22
- # @param [RemoteCookbook] cookbook
23
- # the cookbook to be downloaded
24
- def install(source, cookbook)
25
- message = "Installing #{cookbook.name} (#{cookbook.version})"
26
-
27
- unless source.default?
28
- message << " from #{source}"
29
- message << " ([#{cookbook.location_type}] #{cookbook.location_path})"
30
- end
31
-
32
- Berkshelf.ui.info(message)
33
- end
34
-
35
- # Output a Cookbook use message using {Berkshelf.ui}
36
- #
37
- # @param [Dependency] dependency
38
- def use(dependency)
39
- message = "Using #{dependency.name} (#{dependency.locked_version})"
40
- message << " from #{dependency.location}" if dependency.location
41
- Berkshelf.ui.info message
42
- end
43
-
44
- # Output a Cookbook upload message using {Berkshelf.ui}
45
- #
46
- # @param [Berkshelf::CachedCookbook] cookbook
47
- # @param [Ridley::Connection] conn
48
- def upload(cookbook, conn)
49
- Berkshelf.ui.info "Uploading #{cookbook.cookbook_name} (#{cookbook.version}) to: '#{conn.server_url}'"
50
- end
51
-
52
- # Output a Cookbook skip message using {Berkshelf.ui}
53
- #
54
- # @param [Berkshelf::CachedCookbook] cookbook
55
- # @param [Ridley::Connection] conn
56
- def skip(cookbook, conn)
57
- Berkshelf.ui.info "Skipping #{cookbook.cookbook_name} (#{cookbook.version}) (frozen)"
58
- end
59
-
60
- # Output a list of outdated cookbooks and the most recent version
61
- # using {Berkshelf.ui}
62
- #
63
- # @param [Hash] hash
64
- # the list of outdated cookbooks in the format
65
- # { 'cookbook' => { 'api.berkshelf.com' => #<Cookbook> } }
66
- def outdated(hash)
67
- hash.keys.each do |name|
68
- hash[name].each do |source, newest|
69
- string = " * #{newest.name} (#{newest.version})"
70
- unless source == Berksfile::DEFAULT_API_URL
71
- string << " [#{source}]"
72
- end
73
- Berkshelf.ui.info string
74
- end
75
- end
76
- end
77
-
78
- # Output a Cookbook package message using {Berkshelf.ui}
79
- #
80
- # @param [String] destination
81
- def package(destination)
82
- Berkshelf.ui.info "Cookbook(s) packaged to #{destination}"
83
- end
84
-
85
- # Output a list of cookbooks using {Berkshelf.ui}
86
- #
87
- # @param [Array<Dependency>] list
88
- def list(dependencies)
89
- Berkshelf.ui.info "Cookbooks installed by your Berksfile:"
90
- dependencies.each do |dependency|
91
- out = " * #{dependency}"
92
- out << " from #{dependency.location}" if dependency.location
93
- Berkshelf.ui.info(out)
94
- end
95
- end
96
-
97
- # Output Cookbook info message using {Berkshelf.ui}
98
- #
99
- # @param [CachedCookbook] cookbook
100
- def show(cookbook)
101
- Berkshelf.ui.info(cookbook.pretty_print)
102
- end
103
-
104
- # Output Cookbook vendor info message using {Berkshelf.ui}
105
- #
106
- # @param [CachedCookbook] cookbook
107
- # @param [String] destination
108
- def vendor(cookbook, destination)
109
- cookbook_destination = File.join(destination, cookbook.cookbook_name)
110
- Berkshelf.ui.info "Vendoring #{cookbook.cookbook_name} (#{cookbook.version}) to #{cookbook_destination}"
111
- end
112
-
113
- # Output a generic message using {Berkshelf.ui}
114
- #
115
- # @param [String] message
116
- def msg(message)
117
- Berkshelf.ui.info message
118
- end
119
-
120
- # Output an error message using {Berkshelf.ui}
121
- #
122
- # @param [String] message
123
- def error(message)
124
- Berkshelf.ui.error message
125
- end
126
-
127
- # Output a warning message using {Berkshelf.ui}
128
- #
129
- # @param [String] message
130
- def warn(message)
131
- Berkshelf.ui.warn message
132
- end
133
-
134
- # Output a deprecation warning
135
- #
136
- # @param [String] message
137
- def deprecation(message)
138
- Berkshelf.ui.info "DEPRECATED: #{message}"
139
- end
140
- end
141
- end
142
- end
data/lib/berkshelf/git.rb DELETED
@@ -1,204 +0,0 @@
1
- require 'uri'
2
- require 'buff/shell_out'
3
-
4
- module Berkshelf
5
- class Git
6
- GIT_REGEXP = URI.regexp(%w(http https ssh git+ssh git rsync))
7
- SCP_REGEXP = /^(.+@)?[\w\d\.-]+:.*$/
8
-
9
- HAS_QUOTE_RE = %r{\"}.freeze
10
- HAS_SPACE_RE = %r{\s}.freeze
11
-
12
- class << self
13
- include Buff::ShellOut
14
-
15
- # @overload git(commands)
16
- # Shellout to the Git executable on your system with the given commands.
17
- #
18
- # @param [Array<String>]
19
- #
20
- # @return [String]
21
- # the output of the execution of the Git command
22
- def git(*command)
23
- command.unshift(git_cmd)
24
- command_str = command.map { |p| quote_cmd_arg(p) }.join(' ')
25
- response = shell_out(command_str)
26
-
27
- unless response.success?
28
- raise GitError.new(response.stderr.strip)
29
- end
30
-
31
- response.stdout.strip
32
- end
33
-
34
- # Clone a remote Git repository to disk
35
- #
36
- # @param [String] uri
37
- # a Git URI to clone
38
- # @param [#to_s] destination
39
- # a local path on disk to clone to
40
- #
41
- # @return [String]
42
- # the destination the URI was cloned to
43
- def clone(uri, destination = Dir.mktmpdir)
44
- if File::ALT_SEPARATOR
45
- destination = destination.to_s.gsub(File::SEPARATOR, File::ALT_SEPARATOR)
46
- end
47
-
48
- git('clone', uri, destination.to_s)
49
-
50
- destination
51
- end
52
-
53
- # Checkout the given reference in the given repository
54
- #
55
- # @param [String] repo_path
56
- # path to a Git repo on disk
57
- # @param [String] ref
58
- # reference to checkout
59
- def checkout(repo_path, ref)
60
- Dir.chdir repo_path do
61
- git('checkout', '-qf', revision_from_ref(repo_path, ref))
62
- end
63
- end
64
-
65
- # @param [String] repo_path
66
- def rev_parse(repo_path)
67
- Dir.chdir repo_path do
68
- git('rev-parse', 'HEAD')
69
- end
70
- end
71
-
72
- # Return the sha revision for the given reference in the given repository
73
- #
74
- # @param [String] repo_path
75
- # path to a Git repo on disk
76
- # @param [String] ref
77
- # reference to show
78
- #
79
- # @return [String]
80
- # the sha revision for the given ref
81
- #
82
- # @raise [AmbiguousGitRef] if the ref could refer to more than one revision
83
- def show_ref(repo_path, ref)
84
- Dir.chdir repo_path do
85
- lines = git('show-ref', ref).lines.to_a
86
-
87
- raise AmbiguousGitRef, ref if lines.size > 1
88
-
89
- lines.first.chomp.split(/\s/).first
90
- end
91
- end
92
-
93
- # Return the sha revision for the given reference or revision in the given repository
94
- #
95
- # This method is useful when you have either a sha revision, tag, or branch and
96
- # you'd like to end up with a sha revision.
97
- #
98
- # @param [String] repo_path
99
- # path to a Git repo on disk
100
- # @param [String] ref
101
- # reference to show
102
- #
103
- # @return [String]
104
- # the sha revision for the given ref
105
- #
106
- # @raise [InvalidGitRef] if the ref could not be found
107
- def revision_from_ref(repo_path, ref)
108
- begin
109
- show_ref(repo_path, ref)
110
- rescue GitError
111
- begin
112
- git('rev-parse', ref)
113
- ref
114
- rescue GitError
115
- raise InvalidGitRef, ref
116
- end
117
- end
118
- end
119
-
120
- # Return an absolute path to the Git executable on your system
121
- #
122
- # @return [String]
123
- # absolute path to git executable
124
- #
125
- # @raise [GitNotFound] if executable is not found in system path
126
- def find_git
127
- git_path = nil
128
- ENV['PATH'].split(::File::PATH_SEPARATOR).each do |path|
129
- git_path = detect_git_path(path)
130
- break if git_path
131
- end
132
-
133
- unless git_path
134
- raise GitNotFound
135
- end
136
-
137
- return git_path
138
- end
139
-
140
- # Determines if the given URI is a valid Git URI. A valid Git URI is a string
141
- # containing the location of a Git repository by either the Git protocol,
142
- # SSH protocol, or HTTPS protocol.
143
- #
144
- # @example Valid Git protocol URI
145
- # 'git://github.com/reset/thor-foodcritic.git'
146
- # @example Valid HTTPS URI
147
- # 'https://github.com/reset/solve.git'
148
- # @example Valid SSH protocol URI
149
- # 'git@github.com:reset/solve.git'
150
- #
151
- # @param [String] uri
152
- #
153
- # @return [Boolean]
154
- def validate_uri(uri)
155
- unless uri.is_a?(String)
156
- return false
157
- end
158
-
159
- unless uri.slice(GIT_REGEXP).nil?
160
- return true
161
- end
162
-
163
- unless uri.slice(SCP_REGEXP).nil?
164
- return true
165
- end
166
-
167
- false
168
- end
169
-
170
- # @raise [InvalidGitURI] if the given object is not a String containing a valid Git URI
171
- #
172
- # @see validate_uri
173
- def validate_uri!(uri)
174
- unless validate_uri(uri)
175
- raise InvalidGitURI.new(uri)
176
- end
177
-
178
- true
179
- end
180
-
181
- private
182
-
183
- def git_cmd
184
- @git_cmd ||= find_git
185
- end
186
-
187
- def quote_cmd_arg(arg)
188
- return arg if HAS_QUOTE_RE.match(arg)
189
- return arg unless HAS_SPACE_RE.match(arg)
190
- "\"#{arg}\""
191
- end
192
-
193
- def detect_git_path(base_dir)
194
- %w(git git.exe git.cmd).each do |git_cmd|
195
- potential_path = File.join(base_dir, git_cmd)
196
- if File.executable?(potential_path)
197
- return potential_path
198
- end
199
- end
200
- nil
201
- end
202
- end
203
- end
204
- end