stove 6.0.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/lib/stove/version.rb +1 -1
  3. metadata +10 -70
  4. data/.gitignore +0 -19
  5. data/.travis.yml +0 -20
  6. data/CHANGELOG.md +0 -161
  7. data/Gemfile +0 -5
  8. data/README.md +0 -129
  9. data/Rakefile +0 -24
  10. data/bin/stove +0 -5
  11. data/features/plugins/community.feature +0 -41
  12. data/features/plugins/git.feature +0 -40
  13. data/features/step_definitions/community_steps.rb +0 -23
  14. data/features/step_definitions/config_steps.rb +0 -7
  15. data/features/step_definitions/cookbook_steps.rb +0 -47
  16. data/features/step_definitions/cucumber_steps.rb +0 -12
  17. data/features/step_definitions/git_steps.rb +0 -67
  18. data/features/support/env.rb +0 -34
  19. data/features/support/stove.pem +0 -27
  20. data/features/support/stove/git.rb +0 -68
  21. data/spec/fixtures/integration_cookbook/attributes/default.rb +0 -1
  22. data/spec/fixtures/integration_cookbook/metadata.rb +0 -2
  23. data/spec/fixtures/integration_cookbook/recipes/default.rb +0 -1
  24. data/spec/integration/artifactory_spec.rb +0 -90
  25. data/spec/integration/cookbook_spec.rb +0 -43
  26. data/spec/spec_helper.rb +0 -28
  27. data/spec/support/generators.rb +0 -133
  28. data/spec/unit/artifactory_spec.rb +0 -131
  29. data/spec/unit/cookbook/metadata_spec.rb +0 -176
  30. data/spec/unit/error_spec.rb +0 -133
  31. data/stove.gemspec +0 -34
  32. data/templates/errors/abstract_method.erb +0 -5
  33. data/templates/errors/artifactory_key_validation_failed.erb +0 -11
  34. data/templates/errors/git_clean_validation_failed.erb +0 -1
  35. data/templates/errors/git_failed.erb +0 -5
  36. data/templates/errors/git_repository_validation_failed.erb +0 -3
  37. data/templates/errors/git_tagging_failed.erb +0 -5
  38. data/templates/errors/git_up_to_date_validation_failed.erb +0 -7
  39. data/templates/errors/metadata_not_found.erb +0 -1
  40. data/templates/errors/server_unavailable.erb +0 -1
  41. data/templates/errors/stove_error.erb +0 -1
  42. data/templates/errors/supermarket_already_exists.erb +0 -5
  43. data/templates/errors/supermarket_key_validation_failed.erb +0 -3
  44. data/templates/errors/supermarket_username_validation_failed.erb +0 -3
data/Rakefile DELETED
@@ -1,24 +0,0 @@
1
- require 'bundler/gem_tasks'
2
-
3
- require 'rspec/core/rake_task'
4
- RSpec::Core::RakeTask.new(:unit) do |t|
5
- t.rspec_opts = [].tap do |a|
6
- a.push('--color')
7
- a.push('--format progress')
8
- end.join(' ')
9
- end
10
-
11
- require 'cucumber/rake/task'
12
- Cucumber::Rake::Task.new(:acceptance) do |t|
13
- t.cucumber_opts = [].tap do |a|
14
- a.push('--color')
15
- a.push('--format progress')
16
- a.push('--strict')
17
- a.push('--tags ~@wip')
18
- end.join(' ')
19
- end
20
-
21
- desc 'Run all tests'
22
- task :test => [:unit, :acceptance]
23
-
24
- task :default => [:test]
data/bin/stove DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
4
- require 'stove'
5
- Stove::Cli.new(ARGV.dup).execute!
@@ -1,41 +0,0 @@
1
- Feature: Supermarket
2
- Background:
3
- * I have a cookbook named "bacon"
4
-
5
- Scenario: When the username does not exist
6
- * the Stove config at "username" is unset
7
- * I run `stove --no-git`
8
- * it should fail with "requires a username"
9
-
10
- Scenario: When the key does not exist
11
- * the Stove config at "key" is unset
12
- * I run `stove --no-git`
13
- * it should fail with "requires a private key"
14
-
15
- Scenario: With the default parameters
16
- * the supermarket has the cookbook:
17
- | bacon | 1.2.3 |
18
- * I successfully run `stove --no-git`
19
- * the supermarket will have the cookbooks:
20
- | bacon | 0.0.0 |
21
-
22
- Scenario: Yanking a cookbook
23
- * the supermarket has the cookbooks:
24
- | bacon | 1.2.3 |
25
- * I successfully run `stove yank -l debug`
26
- * the supermarket will not have the cookbooks:
27
- | bacon | 1.2.3 |
28
- * the output should contain "Successfully yanked bacon!"
29
-
30
- Scenario: Yanking a cookbook by name
31
- * the supermarket has the cookbooks:
32
- | eggs | 4.5.6 |
33
- * I successfully run `stove yank eggs`
34
- * the supermarket will not have the cookbooks:
35
- | eggs | 4.5.6 |
36
- * the output should not contain "Successfully yanked bacon!"
37
- * the output should contain "Successfully yanked eggs!"
38
-
39
- Scenario: Yanking a non-existent cookbook
40
- * I run `stove yank ham`
41
- * it should fail with "I could not find a cookbook named ham"
@@ -1,40 +0,0 @@
1
- Feature: git Plugin
2
- Background:
3
- * I have a cookbook named "bacon"
4
- * the supermarket has the cookbooks:
5
- | bacon | 1.0.0 |
6
-
7
- Scenario: When the directory is not a git repository
8
- * I run `stove`
9
- * it should fail with "does not appear to be a valid git repository"
10
-
11
- Scenario: When the directory is dirty
12
- * I have a cookbook named "bacon" with git support
13
- * I write to "new" with:
14
- """
15
- This is new content
16
- """
17
- * I run `stove`
18
- * it should fail with "has untracked files"
19
-
20
- Scenario: When the local is out of date with the remote
21
- * I have a cookbook named "bacon" with git support
22
- * the remote repository has additional commits
23
- * I run `stove -l debug`
24
- * it should fail with "out of sync with the remote repository"
25
-
26
- Scenario: When a git upload should be done
27
- * I have a cookbook named "bacon" with git support
28
- * I successfully run `stove`
29
- * the git remote should have the tag "v0.0.0"
30
-
31
- Scenario: When using signed tags
32
- * I have a cookbook named "bacon" with git support
33
- * a GPG key exists
34
- * I successfully run `stove --sign`
35
- * the git remote should have the signed tag "v0.0.0"
36
-
37
- Scenario: With the git plugin disabled
38
- * I have a cookbook named "bacon" with git support
39
- * I successfully run `stove --no-git`
40
- * the git remote should not have the tag "v0.0.0"
@@ -1,23 +0,0 @@
1
- Given /^the supermarket has the cookbooks?:$/ do |table|
2
- table.raw.each do |name, version|
3
- version ||= '0.0.0'
4
-
5
- CommunityZero::RSpec.store.add(CommunityZero::Cookbook.new(
6
- name: name,
7
- version: version,
8
- category: 'Other',
9
- ))
10
- end
11
- end
12
-
13
- Then /^the supermarket will( not)? have the cookbooks?:$/ do |negate, table|
14
- table.raw.each do |name, version|
15
- cookbook = CommunityZero::RSpec.store.find(name, version)
16
-
17
- if negate
18
- expect(cookbook).to be_nil
19
- else
20
- expect(cookbook).to_not be_nil
21
- end
22
- end
23
- end
@@ -1,7 +0,0 @@
1
- Given /^the Stove config at "(.+)" is "(.+)"/ do |variable, value|
2
- Stove::Config.__set__(variable, value)
3
- end
4
-
5
- Given /^the Stove config at "(.+)" is unset/ do |variable|
6
- Stove::Config.__unset__(variable)
7
- end
@@ -1,47 +0,0 @@
1
- Given /^I have a cookbook named "([\w\-]+)" at version "([\d\.]+)"$/ do |name, version|
2
- create_cookbook(name, version)
3
- end
4
-
5
- Given /^I have a cookbook named "([\w\-]+)"$/ do |name|
6
- create_cookbook(name, '0.0.0')
7
- end
8
-
9
- Given /^I have a cookbook named "([\w\-]+)" with git support$/ do |name|
10
- create_cookbook(name, '0.0.0', git: true)
11
- end
12
-
13
-
14
- #
15
- # Create a new cookbook with the given name and version.
16
- #
17
- # @param [String] name
18
- # @param [String] version (default: 0.0.0.0)
19
- # @param [Hash] options
20
- #
21
- def create_cookbook(name, version, options = {})
22
- create_dir(name)
23
- cd(name)
24
-
25
- write_file('CHANGELOG.md', <<-EOH.gsub(/^ {4}/, ''))
26
- #{name} Changelog
27
- =================
28
-
29
- v#{version} (#{Time.now.to_date})
30
- ----------------------------
31
- - This is an entry
32
- - This is another entry
33
- EOH
34
-
35
- write_file('README.md', <<-EOH.gsub(/^ {4}/, ''))
36
- This is the README for #{name}
37
- EOH
38
-
39
- write_file('metadata.rb', <<-EOH.gsub(/^ {4}/, ''))
40
- name '#{name}'
41
- version '#{version}'
42
- EOH
43
-
44
- if options[:git]
45
- git_init(current_dir)
46
- end
47
- end
@@ -1,12 +0,0 @@
1
- # These are steps that should really exist in cucumber, but they don't...
2
- When /^the environment variable "(.+)" is "(.+)"/ do |variable, value|
3
- set_env(variable, value)
4
- end
5
-
6
- When /^the environment variable "(.+)" is unset$/ do |variable|
7
- set_env(variable, nil)
8
- end
9
-
10
- Then /^it should (pass|fail) with "(.+)"$/ do |pass_fail, partial|
11
- self.__send__("assert_#{pass_fail}ing_with", partial)
12
- end
@@ -1,67 +0,0 @@
1
- Given /^the remote repository has additional commits/ do
2
- cmd = [
3
- 'cd "' + fake_git_remote + '"',
4
- 'touch myfile.txt',
5
- 'git add --force myfile.txt',
6
- 'git commit --message "Add new file"',
7
- ].join(' && ')
8
-
9
- %x|#{cmd}|
10
- end
11
-
12
- Given /^a GPG key exists/ do
13
- gpg_home = File.join(scratch_dir, '.gnupg')
14
- set_env('GNUPGHOME', gpg_home)
15
- Dir.mkdir(gpg_home)
16
- File.chmod(0700, gpg_home)
17
- batch_path = File.join(gpg_home, 'batch')
18
- File.write(batch_path, <<-EOH)
19
- %pubring #{File.join(gpg_home, 'keyring')}
20
- %secring #{File.join(gpg_home, 'keyring.sec')}
21
- Key-Type: DSA
22
- Key-Length: 832
23
- Subkey-Type: ELG-E
24
- Subkey-Length: 800
25
- Name-Real: Alan Smithee
26
- Name-Email: asmithee@example.com
27
- Expire-Date: 0
28
- %commit
29
- EOH
30
- gpg_wrapper = File.join(gpg_home, 'gpg_wrapper')
31
- File.write(gpg_wrapper, <<-EOH)
32
- #!/bin/sh
33
- gpg "--keyring=#{File.join(gpg_home, 'keyring')}" "--secret-keyring=#{File.join(gpg_home, 'keyring.sec')}" "$@"
34
- EOH
35
- File.chmod(0755, gpg_wrapper)
36
-
37
- cmd = [
38
- "cd \"#{current_dir}\"",
39
- "git config gpg.program #{gpg_wrapper}",
40
- 'git config user.signingkey asmithee@example.com',
41
- "gpg --quiet --batch --gen-key #{batch_path}",
42
- ].join(' && ')
43
-
44
- %x|#{cmd}|
45
- end
46
-
47
-
48
- Then /^the git remote should( not)? have the commit "(.+)"$/ do |negate, message|
49
- commits = git_commits(fake_git_remote)
50
-
51
- if negate
52
- expect(commits).to_not include(message)
53
- else
54
- expect(commits).to include(message)
55
- end
56
- end
57
-
58
- Then /^the git remote should( not)? have the( signed)? tag "(.+)"$/ do |negate, signed, tag|
59
- tags = git_tags(fake_git_remote)
60
-
61
- if negate
62
- expect(tags).to_not include(tag)
63
- else
64
- expect(tags).to include(tag)
65
- expect(git_tag_signature?(fake_git_remote, tag)).to be_truthy if signed
66
- end
67
- end
@@ -1,34 +0,0 @@
1
- require 'stove'
2
-
3
- require 'aruba'
4
- require 'aruba/cucumber'
5
- require 'aruba/in_process'
6
-
7
- Aruba::InProcess.main_class = Stove::Cli
8
- Aruba.process = Aruba::InProcess
9
-
10
- require 'community_zero/rspec'
11
- CommunityZero::RSpec.start
12
-
13
- require File.expand_path('../stove/git', __FILE__)
14
-
15
- World(Aruba::Api)
16
- World(Stove::Git)
17
-
18
- Before do
19
- CommunityZero::RSpec.reset!
20
-
21
- Stove::Config.endpoint = CommunityZero::RSpec.url
22
- Stove::Config.username = 'stove'
23
- Stove::Config.key = File.expand_path('../stove.pem', __FILE__)
24
- end
25
-
26
- Before do
27
- FileUtils.rm_rf(scratch_dir)
28
- FileUtils.mkdir_p(scratch_dir)
29
- end
30
-
31
- # The scratch directory
32
- def scratch_dir
33
- @scratch_dir ||= File.expand_path('tmp/aruba/scratch')
34
- end
@@ -1,27 +0,0 @@
1
- -----BEGIN RSA PRIVATE KEY-----
2
- MIIEpQIBAAKCAQEAzdbR5SpsMUlKrQle+6KhEuP9v+ZV0zRj2SMilk8jxlLDmuZ7
3
- j+32n+envYMuQTg+Bm2nzDqcyePGCd2jyWj+TszwxZ3IyqEEzOl93vEzUwKf9WWf
4
- sOdG3/O7i2eJMNOzCxfjqMmld7E74d3Tq+0P5McIC4awFrGWfd5DX1QmFlygvTVH
5
- Ke3Bmf6gEXyQRhrFDdc1sfLtBZnCC5wEzZ3hrTP/Yg3zFbJl4eoTEEbQ2MtjBa/e
6
- Nw/JmIBiLBbuzc9Sxjbf1QY5piVU/KWKbUT2bNFTvRtzT3sU75FS8MRGKnw4pNuh
7
- wzLxqcwLRw2TrS+KWYLbB9CD3xLDo0Pcv3S9ewIDAQABAoIBAQCIew2FA5HlRBFt
8
- li8Sbgya9+zCFrmFZtFlofRG8YZo82ubA4OeNUw3TmRcNeSvfdkybfa6ZYqcGpiu
9
- 5fS5kRI9sYlbnnkKUaVbMN4yun8rZSwmjBFMPK0zxOnvTuEaLOQkUNy0h69dI3jv
10
- FCRLdM37BTUCX3XWNj3wizTkumjena5tqIjvWC0YuTau74B2TQfzXcuwXRnwep6t
11
- AGjtYyUvee2R2xbgZwA4Y8350wDbNrRqcwYsD1MplfAbOf2aNSjPbltjf7qmc0md
12
- 2xtSf+rXCtb2T7xsIo6RWkZJ5BgxULRYt1tfDema1CtIPEqYAvwhDLKYylTef32W
13
- hwOtDfeBAoGBAPyr5j+ebwlVrl2gw4kFfV+YjmcLaJRKK8uJww4n0t6geK7rwZpU
14
- pmRXq8+K0IWhm6BJ9OfHhwA/BvFmOtfWE0Hl7C0aLE9K6Y/Y1cjUPhZ7lwKv/pP2
15
- wEsfF3FceBO+lFcrnjdZ5m7hUbdxBliLvfK3mSsiI8CcptGaTvy/g3qbAoGBANCM
16
- /Bajm32AeTghM3n0+UN5kB71quNnW4o6QxDjfHRAx9I8lVLaoKnAa1p/4hatAMwq
17
- E9K6ZFj8SpI9heIuPIB0IfYCXWh521RNn6cf6A4x7YSLy39m3+9Fjfj6f1g5Njyj
18
- h4EFCIuLhCFDSmMDS2p7P9TivEtO1p/W8p+SfwahAoGAMX3mUs3QyA5NYi+MPXmi
19
- zifOtOZqLKm+nFa2qz4nss3R9cleGcG8+eimUbfKEnLOTf5Oh1vw2J5/2KcCnaZk
20
- DUNhGJCI31s4FqINdhIEu1ioArHAdvEdR1mmuOC48H0jB1QW4JauaUefPwRXjt6I
21
- bVODIAzG3gKRNns4P4+vzEMCgYEAt3S+MWAc4SsJ93Flagww1cVzHXj4qfB7Gz6j
22
- TpD/Ivj1jqCSrv75xDordcH3bgEkKXV+WKp0qb7ODpUmWFBaEpmWYmW0K7q+UQuz
23
- vP2ZUhtjmGytR9aEeWRTPsmFCmPRrUghZEK8QJ0rT2N1ZWI5jmL7RNdr0kd5D8Sz
24
- S+I/8eECgYEA3TjKIBVeDSG7wbTgbFoRDWHK/guCWn8rRpxL6hca7I2afH0D9pR0
25
- J5eNG2kbkq0SwlJXdXU9ADh5NSAUwVs6+bBj+Md/GOHCkYgWRGp0FZGOSTKjsuIm
26
- dXwFj0w9pEyEneu6aa86Uac/hLK5A2vqtXRrhI2iUnRPXKadr4v0u6Y=
27
- -----END RSA PRIVATE KEY-----
@@ -1,68 +0,0 @@
1
- require 'fileutils'
2
-
3
- module Stove
4
- module Git
5
- def git_init(path = Dir.pwd)
6
- cmd = [
7
- 'git init .',
8
- 'git add --all',
9
- 'git commit --message "Initial commit"',
10
- 'git remote add origin file://' + fake_git_remote,
11
- 'git push --quiet --force origin master',
12
- ].join(' && ')
13
-
14
- Dir.chdir(path) do
15
- %x|#{cmd}|
16
- end
17
- end
18
-
19
- def fake_git_remote
20
- path = File.expand_path(File.join(remotes_path, 'remote.git'))
21
- return path if File.exists?(path)
22
-
23
- FileUtils.mkdir_p(path)
24
- cmd = [
25
- 'git init .',
26
- 'git config receive.denyCurrentBranch ignore',
27
- 'git config receive.denyNonFastforwards true',
28
- 'git config core.sharedrepository 1',
29
- ].join(' && ')
30
-
31
- Dir.chdir(path) do
32
- %x|#{cmd}|
33
- end
34
-
35
- path
36
- end
37
-
38
- def git_shas(path)
39
- Dir.chdir(path) do
40
- %x|git log --oneline|.split("\n").map { |line| line.split(/\s+/, 2).first.strip } rescue []
41
- end
42
- end
43
-
44
- def git_commits(path)
45
- Dir.chdir(path) do
46
- %x|git log --oneline|.split("\n").map { |line| line.split(/\s+/, 2).last.strip } rescue []
47
- end
48
- end
49
-
50
- def git_tags(path)
51
- Dir.chdir(path) do
52
- %x|git tag --list|.split("\n").map(&:strip) rescue []
53
- end
54
- end
55
-
56
- def git_tag_signature?(path, tag)
57
- Dir.chdir(path) do
58
- %x|git show --show-signature #{tag}|.include?('BEGIN PGP SIGNATURE') rescue false
59
- end
60
- end
61
-
62
- private
63
-
64
- def remotes_path
65
- @remotes_path ||= File.join(scratch_dir, 'remotes')
66
- end
67
- end
68
- end
@@ -1 +0,0 @@
1
- default['key'] = 'value'
@@ -1,2 +0,0 @@
1
- name 'stove_integration_test'
2
- version '1.0.0'
@@ -1 +0,0 @@
1
- log 'this is a test recipe'
@@ -1,90 +0,0 @@
1
- require 'spec_helper'
2
-
3
- # This integration test uses some environment variables to configure which
4
- # Artifactory server to talk to, as there is no ArtifactoryZero to test against.
5
- # If those aren't present, we skip the tests.
6
- #
7
- # $TEST_STOVE_ARTIFACTORY - URL to the Chef virtual repository.
8
- # $TEST_STOVE_ARTIFACTORY_REAL - URL to the non-virtual repository.
9
- # $TEST_STOVE_ARTIFACTORY_API_KEY - API key to use.
10
-
11
- describe 'artifactory integration test', artifactory_integration: true do
12
- include RSpecCommand
13
- let(:upload_url) { ENV['TEST_STOVE_ARTIFACTORY'] }
14
- let(:delete_url) { ENV['TEST_STOVE_ARTIFACTORY_REAL'] }
15
- let(:api_key) { ENV['TEST_STOVE_ARTIFACTORY_API_KEY'] }
16
- around do |ex|
17
- WebMock.disable!
18
- request(:delete, "#{delete_url}/stove_integration_test")
19
- begin
20
- ex.run
21
- ensure
22
- request(:delete, "#{delete_url}/stove_integration_test")
23
- WebMock.enable!
24
- end
25
- end
26
-
27
- def request(method, url)
28
- uri = URI(url)
29
- req = Net::HTTP.const_get(method.to_s.capitalize).new(uri)
30
- req['X-Jfrog-Art-Api'] = api_key
31
- Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
32
- http.request(req)
33
- end
34
- end
35
-
36
- let(:upload) { JSON.parse(request(:get, "#{upload_url}/api/v1/cookbooks/stove_integration_test/versions/1.0.0").body) }
37
-
38
- describe 'help output' do
39
- command 'stove --help'
40
- its(:stdout) { is_expected.to include('--artifactory ').and(include('--artifactory-key ')) }
41
- end
42
-
43
- describe 'uploading a cookbook' do
44
- context 'with no key' do
45
- fixture_file 'integration_cookbook'
46
- command(nil, allow_error: true) { "stove --no-git --artifactory #{upload_url}" }
47
-
48
- it 'fails to upload' do
49
- expect(subject.exitstatus).to_not eq 0
50
- expect(subject.stdout).to match /You did not specify and Artifactory API key/
51
- end
52
- end
53
-
54
- context 'with $ARTIFACTORY_API_KEY' do
55
- before { _environment['ARTIFACTORY_API_KEY'] = api_key }
56
- fixture_file 'integration_cookbook'
57
- command { "stove --no-git --artifactory #{upload_url}" }
58
-
59
- it 'uploads the cookbook' do
60
- expect(subject.stdout).to eq ''
61
- expect(upload['version']).to eq '1.0.0'
62
- end
63
- end
64
-
65
- context 'with --artifactory-key=@key' do
66
- fixture_file 'integration_cookbook'
67
- file('key') { api_key }
68
- command { "stove --no-git --artifactory #{upload_url} --artifactory-key=@key" }
69
-
70
- it 'uploads the cookbook' do
71
- expect(subject.stdout).to eq ''
72
- expect(upload['version']).to eq '1.0.0'
73
- end
74
- end
75
-
76
- context 'with --artifactory-key=key' do
77
- fixture_file 'integration_cookbook'
78
- file('key') { api_key }
79
- # Using allow_error here so the command isn't shown if things fail.
80
- command(nil, allow_error: true) { "stove --no-git --artifactory #{upload_url} --artifactory-key=#{api_key}" }
81
-
82
- it 'uploads the cookbook' do
83
- expect(subject.stdout).to eq ''
84
- expect(subject.exitstatus).to eq 0
85
- expect(upload['version']).to eq '1.0.0'
86
- end
87
- end
88
-
89
- end
90
- end