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
@@ -1,135 +0,0 @@
1
- module Berkshelf
2
- class GitLocation < Location::ScmLocation
3
- set_location_key :git
4
- set_valid_options :ref, :branch, :tag, :rel
5
-
6
- attr_accessor :uri
7
- attr_accessor :branch
8
- attr_accessor :rel
9
- attr_accessor :ref
10
- attr_reader :options
11
-
12
- alias_method :tag, :branch
13
-
14
- # @param [Dependency] dependency
15
- # @param [Hash] options
16
- #
17
- # @option options [String] :git
18
- # the Git URL to clone
19
- # @option options [String] :ref
20
- # the commit hash or an alias to a commit hash to clone
21
- # @option options [String] :branch
22
- # same as ref
23
- # @option options [String] :tag
24
- # same as tag
25
- # @option options [String] :rel
26
- # the path within the repository to find the cookbook
27
- def initialize(dependency, options = {})
28
- super
29
- @uri = options[:git]
30
- @ref = options[:ref]
31
- @branch = options[:branch] || options[:tag] || "master" unless ref
32
- @sha = ref
33
- @rel = options[:rel]
34
-
35
- Git.validate_uri!(@uri)
36
- end
37
-
38
- # @example
39
- # irb> location.checkout_info
40
- # { kind: "branch", rev: "master" }
41
- #
42
- # @return [Hash]
43
- def checkout_info
44
- if @sha
45
- kind, rev = "ref", @sha
46
- else
47
- kind, rev = "branch", branch
48
- end
49
-
50
- { kind: kind, rev: rev }
51
- end
52
-
53
- # @param [#to_s] destination
54
- #
55
- # @return [Berkshelf::CachedCookbook]
56
- def do_download
57
- destination = Berkshelf::CookbookStore.instance.storage_path
58
-
59
- if cached?(destination)
60
- @ref ||= Berkshelf::Git.rev_parse(revision_path(destination))
61
- return local_revision(destination)
62
- end
63
-
64
- repo_path = Berkshelf::Git.clone(uri)
65
-
66
- Berkshelf::Git.checkout(repo_path, ref || checkout_info[:rev])
67
- @ref = Berkshelf::Git.rev_parse(repo_path)
68
-
69
- tmp_path = rel ? File.join(repo_path, rel) : repo_path
70
- unless File.chef_cookbook?(tmp_path)
71
- msg = "Cookbook '#{dependency.name}' not found at #{to_s}"
72
- msg << " at path '#{rel}'" if rel
73
- raise CookbookNotFound, msg
74
- end
75
-
76
- cb_path = revision_path(destination)
77
- FileUtils.rm_rf(cb_path)
78
- FileUtils.mv(tmp_path, cb_path)
79
-
80
- cached = CachedCookbook.from_store_path(cb_path)
81
- validate_cached(cached)
82
-
83
- cached
84
- end
85
-
86
- def to_hash
87
- super.tap do |h|
88
- h[:value] = self.uri
89
- h[:branch] = self.branch if branch
90
- end
91
- end
92
-
93
- def ==(other)
94
- other.is_a?(GitLocation) &&
95
- other.uri == uri &&
96
- other.branch == branch &&
97
- other.ref == ref &&
98
- other.rel == rel
99
- end
100
-
101
- def to_s
102
- if rel
103
- "#{uri} (at #{branch || ref[0...7]}/#{rel})"
104
- else
105
- "#{uri} (at #{branch || ref[0...7]})"
106
- end
107
- end
108
-
109
- def to_lock
110
- out = " git: #{uri}\n"
111
- out << " branch: #{branch}\n" if branch
112
- out << " ref: #{ref}\n" if ref
113
- out << " rel: #{rel}\n" if rel
114
- out
115
- end
116
-
117
- private
118
-
119
- def cached?(destination)
120
- revision_path(destination) && File.exists?(revision_path(destination))
121
- end
122
-
123
- def local_revision(destination)
124
- path = revision_path(destination)
125
- cached = Berkshelf::CachedCookbook.from_store_path(path)
126
- validate_cached(cached)
127
- return cached
128
- end
129
-
130
- def revision_path(destination)
131
- return unless ref
132
- File.join(destination, "#{dependency.name}-#{ref}")
133
- end
134
- end
135
- end
@@ -1,55 +0,0 @@
1
- module Berkshelf
2
- class GithubLocation < GitLocation
3
- DEFAULT_PROTOCOL = :git
4
-
5
- set_location_key :github
6
- set_valid_options :protocol
7
-
8
- attr_accessor :protocol
9
- attr_accessor :repo_identifier
10
-
11
- # Wraps GitLocation allowing the short form GitHub repo identifier
12
- # to be used in place of the complete repo url.
13
- #
14
- # @see GitLocation#initialize for parameter documentation
15
- #
16
- # @option options [String] :github
17
- # the GitHub repo identifier to clone
18
- # @option options [#to_sym] :protocol
19
- # the protocol with which to communicate with GitHub
20
- def initialize(dependency, options = {})
21
- @repo_identifier = options.delete(:github)
22
- if repo_identifier.end_with?(".git")
23
- raise InvalidGitHubIdentifier.new(repo_identifier)
24
- end
25
- @protocol = (options.delete(:protocol) || DEFAULT_PROTOCOL).to_sym
26
- options[:git] = github_url
27
- super
28
- end
29
-
30
- # Returns the appropriate GitHub url given the specified protocol
31
- #
32
- # @raise [UnknownGitHubProtocol] if the specified protocol is not supported.
33
- #
34
- # @return [String]
35
- # GitHub url
36
- def github_url
37
- case protocol
38
- when :ssh
39
- "git@github.com:#{repo_identifier}.git"
40
- when :https
41
- "https://github.com/#{repo_identifier}.git"
42
- when :git
43
- "git://github.com/#{repo_identifier}.git"
44
- else
45
- raise UnknownGitHubProtocol.new(protocol)
46
- end
47
- end
48
-
49
- private
50
-
51
- def default_protocol?
52
- self.protocol == DEFAULT_PROTOCOL
53
- end
54
- end
55
- end
@@ -1,114 +0,0 @@
1
- module Berkshelf
2
- class MercurialLocation < Location::ScmLocation
3
- set_location_key :hg
4
- set_valid_options :rev, :branch, :tag, :rel
5
-
6
- attr_accessor :uri
7
- attr_accessor :rel
8
- attr_accessor :rev
9
- attr_reader :options
10
-
11
- alias_method :tag, :rev
12
- alias_method :branch, :rev
13
-
14
- # @param [Dependency] dependency
15
- # @param [Hash] options
16
- #
17
- # @option options [String] :hg
18
- # the URL to clone
19
- # @option options [String] :rev
20
- # the revision to checkout
21
- # @option options [String] :branch
22
- # same as rev
23
- # @option options [String] :tag
24
- # same as rev
25
- # @option options [String] :rel
26
- # the path within the repository to find the cookbook
27
- def initialize(dependency, options = {})
28
- super
29
- @uri = options[:hg]
30
- @rev = options[:rev] || options[:branch] || options[:tag] || 'default'
31
- @rel = options[:rel]
32
-
33
- Mercurial.validate_uri!(@uri)
34
- end
35
-
36
- # @return [Berkshelf::CachedCookbook]
37
- def do_download
38
- destination = Berkshelf::CookbookStore.instance.storage_path
39
-
40
- if cached?(destination)
41
- @rev ||= Berkshelf::Mercurial.rev_parse(revision_path(destination))
42
- return local_revision(destination)
43
- end
44
-
45
- repo_path = Berkshelf::Mercurial.clone(uri)
46
-
47
- Berkshelf::Mercurial.checkout(repo_path, rev || branch || tag) if rev || branch || tag
48
- @rev = Berkshelf::Mercurial.rev_parse(repo_path)
49
-
50
- tmp_path = rel ? File.join(repo_path, rel) : repo_path
51
- unless File.chef_cookbook?(tmp_path)
52
- msg = "Cookbook '#{dependency.name}' not found at #{to_s}"
53
- msg << " at path '#{rel}'" if rel
54
- raise CookbookNotFound, msg
55
- end
56
-
57
- cb_path = revision_path(destination)
58
- FileUtils.rm_rf(cb_path)
59
- FileUtils.mv(tmp_path, cb_path)
60
-
61
- cached = CachedCookbook.from_store_path(cb_path)
62
- validate_cached(cached)
63
-
64
- cached
65
- end
66
-
67
- def to_hash
68
- super.tap do |h|
69
- h[:value] = self.uri
70
- h[:branch] = self.branch if branch
71
- end
72
- end
73
-
74
- def ==(other)
75
- other.is_a?(MercurialLocation) &&
76
- other.uri == uri &&
77
- other.rev == rev &&
78
- other.rel == rel
79
- end
80
-
81
- def to_s
82
- if rel
83
- "#{uri} (at #{rev}/#{rel})"
84
- else
85
- "#{uri} (at #{rev})"
86
- end
87
- end
88
-
89
- def to_lock
90
- out = " hg: #{uri}\n"
91
- out << " rev: #{rev}\n" if rev
92
- out << " rel: #{rel}\n" if rel
93
- out
94
- end
95
-
96
- private
97
-
98
- def cached?(destination)
99
- revision_path(destination) && File.exists?(revision_path(destination))
100
- end
101
-
102
- def local_revision(destination)
103
- path = revision_path(destination)
104
- cached = Berkshelf::CachedCookbook.from_store_path(path)
105
- validate_cached(cached)
106
- return cached
107
- end
108
-
109
- def revision_path(destination)
110
- return unless rev
111
- File.join(destination, "#{dependency.name}-#{rev}")
112
- end
113
- end
114
- end
@@ -1,88 +0,0 @@
1
- module Berkshelf
2
- class PathLocation < Location::Base
3
- set_location_key :path
4
- set_valid_options :path, :metadata
5
-
6
- attr_accessor :path
7
-
8
- # @param [#to_s] dependency
9
- # @param [Solve::Constraint] version_constraint
10
- # @param [Hash] options
11
- #
12
- # @option options [#to_s] :path
13
- # a filepath to the cookbook on your local disk
14
- # @option options [Boolean] :metadata
15
- # true if this is a metadata source
16
- def initialize(dependency, options = {})
17
- super
18
- @path = options[:path].to_s
19
- @metadata = options[:metadata]
20
- end
21
-
22
- def do_download
23
- CachedCookbook.from_path(path, name: name)
24
- end
25
-
26
- # Returns true if the location is a metadata location. By default, no
27
- # locations are the metadata location.
28
- #
29
- # @return [Boolean]
30
- def metadata?
31
- !!@metadata
32
- end
33
-
34
- # Return this PathLocation's path relative to the given target.
35
- #
36
- # @param [#to_s] target
37
- # the path to a file or directory to be relative to
38
- #
39
- # @return [String]
40
- # the relative path relative to the target
41
- def relative_path(target = '.')
42
- my_path = Pathname.new(path).expand_path
43
- target_path = Pathname.new(target.to_s).expand_path
44
- target_path = target_path.dirname if target_path.file?
45
-
46
- new_path = my_path.relative_path_from(target_path).to_s
47
-
48
- return new_path if new_path.index('.') == 0
49
- "./#{new_path}"
50
- end
51
-
52
- #
53
- # The expanded path of this path on disk, relative to the berksfile.
54
- #
55
- # @return [String]
56
- #
57
- def expanded_path
58
- relative_path(dependency.berksfile.filepath)
59
- end
60
-
61
- # Valid if the path exists and is readable
62
- #
63
- # @return [Boolean]
64
- def valid?
65
- File.exist?(path) && File.readable?(path)
66
- end
67
-
68
- def to_hash
69
- super.merge(value: self.path)
70
- end
71
-
72
- def ==(other)
73
- other.is_a?(PathLocation) &&
74
- other.metadata? == metadata? &&
75
- other.expanded_path == expanded_path
76
- end
77
-
78
- def to_lock
79
- out = " path: #{relative_path(dependency.berksfile.filepath)}\n"
80
- out << " metadata: true\n" if metadata?
81
- out
82
- end
83
-
84
- def to_s
85
- "source at #{relative_path(dependency.berksfile.filepath)}"
86
- end
87
- end
88
- end
@@ -1,146 +0,0 @@
1
- require 'uri'
2
- require 'buff/shell_out'
3
-
4
- module Berkshelf
5
- class Mercurial
6
- HG_REGEXP = URI.regexp(%w(http https file ssh))
7
-
8
- HAS_QUOTE_RE = %r{\"}.freeze
9
- HAS_SPACE_RE = %r{\s}.freeze
10
-
11
- class << self
12
- include Buff::ShellOut
13
-
14
- # @overload hg(commands)
15
- # Shellout to the Mercurial executable on your system with the given commands.
16
- #
17
- # @param [Array<String>]
18
- #
19
- # @return [String]
20
- # the output of the execution of the Mercurial command
21
- def hg(*command)
22
- command.unshift(hg_cmd)
23
- command_str = command.map { |p| quote_cmd_arg(p) }.join(' ')
24
- response = shell_out(command_str)
25
-
26
- unless response.success?
27
- raise MercurialError.new(response.stderr.strip)
28
- end
29
-
30
- response.stdout.strip
31
- end
32
-
33
- # Clone a remote Mercurial repository to disk
34
- #
35
- # @param [String] uri
36
- # a Mercurial URI to clone
37
- # @param [#to_s] destination
38
- # a local path on disk to clone to
39
- #
40
- # @return [String]
41
- # the destination the URI was cloned to
42
- def clone(uri, destination = Dir.mktmpdir)
43
- hg('clone', uri, destination.to_s)
44
- destination
45
- end
46
-
47
- # Checkout the given revision in the given repository
48
- #
49
- # @param [String] repo_path
50
- # path to a mercurial repo on disk
51
- # @param [String] rev
52
- # revision to checkout
53
- def checkout(repo_path, rev)
54
- Dir.chdir repo_path do
55
- hg('update','--clean', '--rev', rev)
56
- end
57
- end
58
-
59
- # @param [String] repo_path
60
- def rev_parse(repo_path)
61
- Dir.chdir repo_path do
62
- hg('id', '-i')
63
- end
64
- end
65
-
66
- # Return an absolute path to the Mercurial executable on your system
67
- #
68
- # @return [String]
69
- # absolute path to mercurial executable
70
- #
71
- # @raise [MercurialNotFound] if executable is not found in system path
72
- def find_hg
73
- hg_path = nil
74
- ENV['PATH'].split(::File::PATH_SEPARATOR).each do |path|
75
- hg_path = detect_hg_path(path)
76
- break if hg_path
77
- end
78
-
79
- unless hg_path
80
- raise MercurialNotFound
81
- end
82
-
83
- return hg_path
84
- end
85
-
86
- # Determines if the given URI is a valid mercurial URI. A valid mercurial URI is a string
87
- # containing the location of a mercurial repository by either the HTTP protocol,
88
- # HTTPS protocol, or SSH protocol.
89
- #
90
- # @example Valid HTTP protocol URI
91
- # 'http://hghub.com/project'
92
- # @example Valid HTTPS URI
93
- # 'https://hghub.com/project'
94
- # @example Valid SSH protocol URI
95
- # 'ssh://user@hghub.com:22/path/to/repo'
96
- #
97
- # @param [String] uri
98
- #
99
- # @return [Boolean]
100
- def validate_uri(uri)
101
- unless uri.is_a?(String)
102
- return false
103
- end
104
-
105
- unless uri.slice(HG_REGEXP).nil?
106
- return true
107
- end
108
-
109
- false
110
- end
111
-
112
- # @raise [InvalidMercurialURI] if the given object is not a String containing a valid Mercurial URI
113
- #
114
- # @see validate_uri
115
- def validate_uri!(uri)
116
- unless validate_uri(uri)
117
- raise InvalidHgURI.new(uri)
118
- end
119
-
120
- true
121
- end
122
-
123
- private
124
-
125
- def hg_cmd
126
- @hg_cmd ||= find_hg
127
- end
128
-
129
- def quote_cmd_arg(arg)
130
- return arg if HAS_QUOTE_RE.match(arg)
131
- return arg unless HAS_SPACE_RE.match(arg)
132
- "\"#{arg}\""
133
- end
134
-
135
- def detect_hg_path(base_dir)
136
- %w(hg hg.exe hg.cmd).each do |hg_cmd|
137
- potential_path = File.join(base_dir, hg_cmd)
138
- if File.executable?(potential_path)
139
- return potential_path
140
- end
141
- end
142
- nil
143
- end
144
- end
145
- end
146
- end