r10k 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -10,3 +10,6 @@ rvm:
10
10
  - "2.1.0"
11
11
  - "2.0.0"
12
12
  - "1.9.3"
13
+ - "jruby-19mode"
14
+ jdk:
15
+ - oraclejdk8
data/CHANGELOG.mkd CHANGED
@@ -1,6 +1,35 @@
1
1
  CHANGELOG
2
2
  =========
3
3
 
4
+ 2.2.0
5
+ -----
6
+
7
+ 2016/03/08
8
+
9
+ ### Notes
10
+
11
+ (RK-154) Per-repo config for Git sources
12
+
13
+ Git repository options, such as the SSH private key, can now be set indepdently for each repository
14
+ when using the Rugged provider. See [documentation](https://github.com/puppetlabs/r10k/blob/master/doc/git/providers.mkd#ssh-configuration-1)
15
+ for details.
16
+
17
+ (RK-220) Improved error message for unreadable SSH keys
18
+
19
+ r10k will now check to ensure that the configured SSH private key for a given repository is readable
20
+ before attempting to connect. This will result in a clearer error message in situations where the
21
+ key file is not readable.
22
+
23
+ (CODEMGMT-453) Support for running under JRuby 1.7 with shellgit provider
24
+
25
+ r10k should now run successfully under JRuby 1.7.x when using the "shellgit" provider.
26
+
27
+ (MAINT) Documentation fixes
28
+
29
+ Various errors and inconsistencies in the documentation have been fixed thanks to contributions
30
+ from [Paul Tobias](https://github.com/tobiaspal), [Rob Nelson](https://github.com/rnelson0), and
31
+ [David Danzilio](https://github.com/danzilio). Thanks!
32
+
4
33
  2.1.1
5
34
  -----
6
35
 
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :extra do
6
- gem 'rugged', '~> 0.21.4'
6
+ gem 'rugged', '~> 0.21.4', :platforms => :ruby
7
7
  end
8
8
 
9
9
  group :development do
data/README.mkd CHANGED
@@ -77,6 +77,7 @@ Puppetfile, and managing Git and SVN based dynamic environments. For more
77
77
  information see the topic specific documentation:
78
78
 
79
79
  * [Puppetfile Documentation](doc/puppetfile.mkd)
80
+ * [Updating your Puppetfile](doc/updating-your-puppetfile.mkd)
80
81
  * [Environment Deployment Documentation](doc/dynamic-environments.mkd)
81
82
  * [Quickstart](doc/dynamic-environments/quickstart.mkd)
82
83
  * [Common Patterns](doc/common-patterns.mkd)
@@ -68,6 +68,49 @@ git:
68
68
  See the [git provider documentation](../git/providers.mkd) for more information
69
69
  regarding Git providers.
70
70
 
71
+ #### username
72
+
73
+ The username setting is only used by the Rugged git provider.
74
+
75
+ The username option sets the username for SSH remotes when the SSH URL does not provide
76
+ a username. When used with a Git hosting service this is most sensibly set to 'git'.
77
+
78
+ The username defaults to the username of the currently logged in user.
79
+
80
+ ```yaml
81
+ git:
82
+ username: "git"
83
+ ```
84
+
85
+ #### private_key
86
+
87
+ The private_key setting is only used by the Rugged git provider.
88
+
89
+ The private_key option specifies the path to the default Git SSH private key for Git SSH remotes.
90
+ The private_key setting must be set if SSH remotes are used.
91
+
92
+ ```yaml
93
+ git:
94
+ private_key: "/etc/puppetlabs/r10k/ssh/id_rsa"
95
+ ```
96
+
97
+ #### repositories
98
+
99
+ The repositories option allows configuration to be set on a per-remote basis. Each entry is a map of
100
+ the repository URL and per-repository configuration for that repo.
101
+
102
+ ##### private_key
103
+
104
+ A repository specific private key to use for SSH connections for the given repository URL. This
105
+ overrides the global private_key setting.
106
+
107
+ ```yaml
108
+ git:
109
+ repositories:
110
+ "ssh://tessier-ashpool.freeside/protected-repo.git":
111
+ private_key: "/etc/puppetlabs/r10k/ssh/id_rsa-protected-repo-deploy-key"
112
+ ```
113
+
71
114
  ### forge
72
115
 
73
116
  The 'forge' setting is a hash that contains settings for downloading modules
@@ -109,7 +109,7 @@ Configure r10k by creating the following directory structure and file `/etc/pupp
109
109
 
110
110
  Populate the repository by cloning it locally and performing each of the following actions within it:
111
111
 
112
- Note that puppet defaults to the `production` environnment. You may wish to change your default git
112
+ Note that puppet defaults to the `production` environment. You may wish to change your default git
113
113
  branch from `master` to `production` in order to match this. Alternatively, you can set your agents'
114
114
  environment to `master`.
115
115
 
data/doc/faq.mkd CHANGED
@@ -99,7 +99,7 @@ environment to indicate which directories contain modules:
99
99
 
100
100
  ```
101
101
  # environment.conf
102
- modulepath: modules:external-modules
102
+ modulepath = modules:external-modules
103
103
  ```
104
104
 
105
105
  #### Move your local modules
@@ -111,7 +111,7 @@ directories contain modules.
111
111
 
112
112
  ```
113
113
  # environment.conf
114
- modulepath: internal-modules::modules
114
+ modulepath = internal-modules:modules
115
115
  ```
116
116
 
117
117
  #### What does the name mean?
@@ -40,9 +40,9 @@ greater to use this provider.
40
40
 
41
41
  ### SSH Configuration
42
42
 
43
- In order to use rugged with SSH based Git repositories, the 'private_key' option
44
- must be provided. An optional 'username' field can be provided when the Git
45
- remote URL does not provide a username.
43
+ Since the rugged provider does not read ~/.ssh if using SSH based Git
44
+ repositories, the 'private_key' option must be provided. An optional 'username'
45
+ field can be provided when the Git remote URL does not provide a username.
46
46
 
47
47
  ```yaml
48
48
  git:
@@ -50,6 +50,18 @@ git:
50
50
  username: 'git'
51
51
  ```
52
52
 
53
+ If you have per repository private keys you can add them with the repositories list.
54
+
55
+ ```yaml
56
+ git:
57
+ # default private key
58
+ private_key: '/root/.ssh/id_rsa'
59
+ repositories:
60
+ - remote: "git@github.com:my_org/private_repo"
61
+ # private key for this repo only
62
+ private_key: '/root/.ssh/private_repo_id'
63
+ ```
64
+
53
65
  #### Supported transports with Rugged
54
66
 
55
67
  Rugged compiles libgit2 and and the Ruby bindings when the gem is installed. You
@@ -72,7 +84,7 @@ irb(main):001:0> require('rugged')
72
84
  => true
73
85
  irb(main):002:0> Rugged.features
74
86
  => [:threads, :https, :ssh]
75
- irb(main):003:0>
87
+ irb(main):003:0>
76
88
  ```
77
89
  You will require the ':https' or ':ssh' features to use the respective protocols
78
90
  in your Puppetfile module references or in r10k.yaml. R10K 2.0.0 and later will
@@ -0,0 +1,38 @@
1
+ Updating Your Puppetfile
2
+ ========================
3
+
4
+ Over time, your Puppetfile may become stale and reference older versions of modules or miss dependencies for the modules. Your Puppetfile will require maintenance to keep it up to date.
5
+
6
+ Manual Updates
7
+ --------------
8
+
9
+ You can manually update your Puppetfile very easily. By visiting the module's homepage on the [Puppet Forge](https://forge.puppetlabs.com/), you can determine the new version of a module and update it:
10
+
11
+ # Original
12
+ mod 'puppetlabs/apache', '0.10.0'
13
+
14
+ # New
15
+ mod 'puppetlabs/apache', '1.0.0'
16
+
17
+ When using a module directly from a git/svn repo, the `:tag` or `:ref` should be updated:
18
+
19
+ # Original
20
+ mod 'apache',
21
+ :git => 'https://github.com/puppetlabs/puppetlabs-apache',
22
+ :tag => '0.10.0'
23
+
24
+ # Original
25
+ mod 'apache',
26
+ :git => 'https://github.com/puppetlabs/puppetlabs-apache',
27
+ :tag => '1.0.0'
28
+
29
+ Dependency tracking can be done on the Puppet Forge as well by looking at the Dependency tab (Ex: [puppetlabs/apache](https://forge.puppetlabs.com/puppetlabs/apache/dependencies) and visiting each module in turn, or examining `metadata.json` in non-forge modules.
30
+
31
+ Automatic Updates
32
+ -----------------
33
+
34
+ The manual update process is sufficient when updating a small number of modules for a specific effort. Automatic tooling is helpful when updating a lengthier number of modules and for scheduled updates. A number of tools have been provided by the Puppet user community to assist with this. You are encouraged to review each tool before using them, and use of these tools is at your own risk.
35
+
36
+ * [ra10ke](https://rubygems.org/gems/ra10ke) ([project page](https://github.com/tampakrap/ra10ke/)) - A set of rake tasks to scan the Puppetfile for out of date modules
37
+ * [puppetfile-updater](https://rubygems.org/gems/puppetfile-updater/) ([project page](https://github.com/camptocamp/puppetfile-updater)) - A set of rake tasks to scan the Puppetfile, find newer versions, update the Puppetfile, and commit the changes.
38
+ * [generate-puppetfile](https://rubygems.org/gems/generate-puppetfile) ([project page](https://github.com/rnelson0/puppet-generate-puppetfile)) - A command line tool to generate raw Puppetfiles, update existing Puppetfiles, and optionally generate a `.fixtures.yml` file.
data/lib/r10k/git.rb CHANGED
@@ -2,6 +2,7 @@ require 'r10k/features'
2
2
  require 'r10k/errors'
3
3
  require 'r10k/settings'
4
4
  require 'r10k/logging'
5
+ require 'r10k/util/platform'
5
6
 
6
7
  module R10K
7
8
  module Git
@@ -133,5 +134,10 @@ module R10K
133
134
 
134
135
  def_setting_attr :private_key
135
136
  def_setting_attr :username
137
+ def_setting_attr :repositories, {}
138
+
139
+ def self.get_repo_settings(remote)
140
+ self.settings[:repositories].find {|r| r[:remote] == remote }
141
+ end
136
142
  end
137
143
  end
@@ -26,12 +26,28 @@ class R10K::Git::Rugged::Credentials
26
26
 
27
27
  def get_ssh_key_credentials(url, username_from_url)
28
28
  user = get_git_username(url, username_from_url)
29
- private_key = R10K::Git.settings[:private_key]
30
29
 
31
- if private_key.nil?
30
+ per_repo_private_key = nil
31
+ if per_repo_settings = R10K::Git.get_repo_settings(url)
32
+ per_repo_private_key = per_repo_settings[:private_key]
33
+ end
34
+
35
+ global_private_key = R10K::Git.settings[:private_key]
36
+
37
+ if per_repo_private_key
38
+ private_key = per_repo_private_key
39
+ logger.debug2 "Using per-repository private key #{private_key} for URL #{url.inspect}"
40
+ elsif global_private_key
41
+ private_key = global_private_key
42
+ logger.debug2 "URL #{url.inspect} has no per-repository private key using '#{private_key}'."
43
+ else
32
44
  raise R10K::Git::GitError.new("Git remote #{url.inspect} uses the SSH protocol but no private key was given", :git_dir => @repository.path.to_s)
33
45
  end
34
46
 
47
+ if !File.readable?(private_key)
48
+ raise R10K::Git::GitError.new("Unable to use SSH key auth for #{url.inspect}: private key #{private_key.inspect} is missing or unreadable", :git_dir => @repository.path.to_s)
49
+ end
50
+
35
51
  Rugged::Credentials::SshKey.new(:username => user, :privatekey => private_key)
36
52
  end
37
53
 
@@ -42,6 +42,7 @@ module R10K
42
42
  with_setting(:provider) { |value| R10K::Git.provider = value }
43
43
  with_setting(:username) { |value| R10K::Git.settings[:username] = value }
44
44
  with_setting(:private_key) { |value| R10K::Git.settings[:private_key] = value }
45
+ with_setting(:repositories) { |value| R10K::Git.settings[:repositories] = value }
45
46
  end
46
47
  end
47
48
 
data/lib/r10k/settings.rb CHANGED
@@ -27,7 +27,22 @@ module R10K
27
27
  Definition.new(:private_key, {
28
28
  :desc => "The path to the SSH private key for Git SSH remotes.
29
29
  Only used by the 'rugged' Git provider.",
30
- })
30
+ }),
31
+
32
+ Definition.new(:repositories, {
33
+ :desc => "Repository specific configuration.",
34
+ :default => [],
35
+ :normalize => lambda do |repositories|
36
+ # The config file loading logic recursively converts hash keys that are strings to symbols,
37
+ # It doesn't understand hashes inside arrays though so we have to do this manually.
38
+ repositories.map do |repo|
39
+ repo.inject({}) do |retval, (key, value)|
40
+ retval[key.to_sym] = value
41
+ retval
42
+ end
43
+ end
44
+ end
45
+ }),
31
46
  ])
32
47
  end
33
48
 
@@ -39,6 +39,7 @@ module R10K
39
39
  def assign(newvalues)
40
40
  return if newvalues.nil?
41
41
 
42
+ # TODO: this results in inconsistency for hashes inside arrays.
42
43
  R10K::Util::SymbolizeKeys.symbolize_keys!(newvalues)
43
44
  @settings.each_pair do |name, setting|
44
45
  if newvalues.key?(name)
@@ -31,9 +31,9 @@ class R10K::Settings::Container
31
31
 
32
32
  if @settings[key]
33
33
  @settings[key]
34
- elsif @parent and (pkey = @parent[key])
35
- @settings[key] = pkey
36
- pkey
34
+ elsif @parent && (pkey = @parent[key])
35
+ @settings[key] = pkey.dup
36
+ @settings[key]
37
37
  end
38
38
  end
39
39
 
@@ -4,7 +4,10 @@ module R10K
4
4
  module Util
5
5
  module Platform
6
6
  def self.platform
7
- if self.windows?
7
+ # Test JRuby first to handle JRuby on Windows as well.
8
+ if self.jruby?
9
+ :jruby
10
+ elsif self.windows?
8
11
  :windows
9
12
  else
10
13
  :posix
@@ -15,8 +18,12 @@ module R10K
15
18
  RbConfig::CONFIG['host_os'] =~ /mswin|win32|dos|mingw|cygwin/i
16
19
  end
17
20
 
21
+ def self.jruby?
22
+ RUBY_PLATFORM == "java"
23
+ end
24
+
18
25
  def self.posix?
19
- !windows?
26
+ !windows? && !jruby?
20
27
  end
21
28
  end
22
29
  end
@@ -18,6 +18,8 @@ module R10K
18
18
  def self.runner
19
19
  if R10K::Util::Platform.windows?
20
20
  R10K::Util::Subprocess::Runner::Windows
21
+ elsif R10K::Util::Platform.jruby?
22
+ R10K::Util::Subprocess::Runner::JRuby
21
23
  else
22
24
  R10K::Util::Subprocess::Runner::POSIX
23
25
  end
@@ -5,6 +5,7 @@ class R10K::Util::Subprocess::Runner
5
5
 
6
6
  require 'r10k/util/subprocess/runner/windows'
7
7
  require 'r10k/util/subprocess/runner/posix'
8
+ require 'r10k/util/subprocess/runner/jruby'
8
9
 
9
10
  # @!attribute [rw] cwd
10
11
  # @return [String] The directory to be used as the cwd when executing
@@ -0,0 +1,23 @@
1
+ require 'open3'
2
+ require 'r10k/util/subprocess/runner'
3
+
4
+ # Run processes under JRuby.
5
+ #
6
+ # This implementation relies on Open3.capture3 to run commands and capture
7
+ # results. In contrast to the POSIX runner this cannot be used in an
8
+ # asynchronous manner as-is; implementing that will probably mean launching a
9
+ # thread and invoking #capture3 in that thread.
10
+ class R10K::Util::Subprocess::Runner::JRuby < R10K::Util::Subprocess::Runner
11
+
12
+ def initialize(argv)
13
+ @argv = argv
14
+ end
15
+
16
+ def run
17
+ spawn_opts = @cwd ? {:chdir => @cwd} : {}
18
+ stdout, stderr, status = Open3.capture3(*@argv, spawn_opts)
19
+ @result = R10K::Util::Subprocess::Result.new(@argv, stdout, stderr, status.exitstatus)
20
+ rescue Errno::ENOENT, Errno::EACCES => e
21
+ @result = R10K::Util::Subprocess::Result.new(@argv, '', e.message, 255)
22
+ end
23
+ end
data/lib/r10k/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module R10K
2
- VERSION = '2.1.1'
2
+ VERSION = '2.2.0'
3
3
  end
data/r10k.gemspec CHANGED
@@ -28,11 +28,7 @@ Gem::Specification.new do |s|
28
28
  s.add_dependency 'log4r', '1.1.10'
29
29
  s.add_dependency 'multi_json', '~> 1.10'
30
30
 
31
- s.add_dependency 'puppet_forge', '~> 2.1.1'
32
- s.add_dependency 'faraday', '~> 0.9.0'
33
- s.add_dependency 'faraday_middleware', '~> 0.9.0'
34
- s.add_dependency 'faraday_middleware-multi_json', '~> 0.0.6'
35
-
31
+ s.add_dependency 'puppet_forge', '~> 2.1.1'
36
32
  s.add_dependency 'semantic_puppet', '~> 0.1.0'
37
33
  s.add_dependency 'minitar'
38
34
 
@@ -1,7 +1,10 @@
1
1
  require 'spec_helper'
2
- require 'r10k/git/rugged/cache'
3
2
 
4
- describe R10K::Git::Rugged::Cache do
3
+ describe R10K::Git::Rugged::Cache, :unless => R10K::Util::Platform.jruby? do
4
+ before(:all) do
5
+ require 'r10k/git/rugged/cache'
6
+ end
7
+
5
8
  subject(:cache) { described_class.new('git://some/git/remote') }
6
9
 
7
10
  it "wraps a Rugged::BareRepository instance" do
@@ -1,8 +1,10 @@
1
1
  require 'spec_helper'
2
- require 'r10k/git/rugged/credentials'
3
- require 'rugged/credentials'
4
2
 
5
- describe R10K::Git::Rugged::Credentials do
3
+ describe R10K::Git::Rugged::Credentials, :unless => R10K::Util::Platform.jruby? do
4
+ before(:all) do
5
+ require 'r10k/git/rugged/credentials'
6
+ require 'rugged/credentials'
7
+ end
6
8
 
7
9
  let(:repo) { R10K::Git::Rugged::BareRepository.new("/some/nonexistent/path", "repo.git") }
8
10
 
@@ -33,7 +35,24 @@ describe R10K::Git::Rugged::Credentials do
33
35
  end
34
36
 
35
37
  describe "generating ssh key credentials" do
36
- after { R10K::Git.settings.reset! }
38
+ after(:each) { R10K::Git.settings.reset! }
39
+
40
+ it "prefers a per-repository SSH private key" do
41
+ allow(File).to receive(:readable?).with("/etc/puppetlabs/r10k/ssh/tessier-ashpool-id_rsa").and_return true
42
+ R10K::Git.settings[:repositories] = [{ remote: "ssh://git@tessier-ashpool.freeside/repo.git",
43
+ private_key: "/etc/puppetlabs/r10k/ssh/tessier-ashpool-id_rsa"}]
44
+ creds = subject.get_ssh_key_credentials("ssh://git@tessier-ashpool.freeside/repo.git", nil)
45
+ expect(creds).to be_a_kind_of(Rugged::Credentials::SshKey)
46
+ expect(creds.instance_variable_get(:@privatekey)).to eq("/etc/puppetlabs/r10k/ssh/tessier-ashpool-id_rsa")
47
+ end
48
+
49
+ it "falls back to the global SSH private key" do
50
+ allow(File).to receive(:readable?).with("/etc/puppetlabs/r10k/ssh/id_rsa").and_return true
51
+ R10K::Git.settings[:private_key] = "/etc/puppetlabs/r10k/ssh/id_rsa"
52
+ creds = subject.get_ssh_key_credentials("ssh://git@tessier-ashpool.freeside/repo.git", nil)
53
+ expect(creds).to be_a_kind_of(Rugged::Credentials::SshKey)
54
+ expect(creds.instance_variable_get(:@privatekey)).to eq("/etc/puppetlabs/r10k/ssh/id_rsa")
55
+ end
37
56
 
38
57
  it "raises an error if no key has been set" do
39
58
  R10K::Git.settings[:private_key] = nil
@@ -42,11 +61,20 @@ describe R10K::Git::Rugged::Credentials do
42
61
  }.to raise_error(R10K::Git::GitError, /no private key was given/)
43
62
  end
44
63
 
45
- it "generates the rugged sshkey credential type" do
64
+ it "raises an error if the private key is unreadable" do
46
65
  R10K::Git.settings[:private_key] = "/some/nonexistent/.ssh/key"
66
+ expect(File).to receive(:readable?).with("/some/nonexistent/.ssh/key").and_return false
67
+ expect {
68
+ subject.get_ssh_key_credentials("https://tessier-ashpool.freeside/repo.git", nil)
69
+ }.to raise_error(R10K::Git::GitError, /Unable to use SSH key auth for.*is missing or unreadable/)
70
+ end
71
+
72
+ it "generates the rugged sshkey credential type" do
73
+ allow(File).to receive(:readable?).with("/etc/puppetlabs/r10k/ssh/id_rsa").and_return true
74
+ R10K::Git.settings[:private_key] = "/etc/puppetlabs/r10k/ssh/id_rsa"
47
75
  creds = subject.get_ssh_key_credentials("https://tessier-ashpool.freeside/repo.git", nil)
48
76
  expect(creds).to be_a_kind_of(Rugged::Credentials::SshKey)
49
- expect(creds.instance_variable_get(:@privatekey)).to eq("/some/nonexistent/.ssh/key")
77
+ expect(creds.instance_variable_get(:@privatekey)).to eq("/etc/puppetlabs/r10k/ssh/id_rsa")
50
78
  end
51
79
  end
52
80
 
@@ -59,7 +87,8 @@ describe R10K::Git::Rugged::Credentials do
59
87
 
60
88
  describe "generating credentials" do
61
89
  it "creates ssh key credentials for the sshkey allowed type" do
62
- R10K::Git.settings[:private_key] = "/some/nonexistent/.ssh/key"
90
+ allow(File).to receive(:readable?).with("/etc/puppetlabs/r10k/ssh/id_rsa").and_return true
91
+ R10K::Git.settings[:private_key] = "/etc/puppetlabs/r10k/ssh/id_rsa"
63
92
  expect(subject.call("https://tessier-ashpool.freeside/repo.git", nil, [:ssh_key])).to be_a_kind_of(Rugged::Credentials::SshKey)
64
93
  end
65
94
 
@@ -11,10 +11,12 @@ describe R10K::Git do
11
11
  expect(described_class.default_name).to eq :shellgit
12
12
  end
13
13
 
14
- it 'returns rugged when the git executable is absent and the rugged library is present' do
15
- expect(R10K::Features).to receive(:available?).with(:shellgit).and_return false
16
- expect(R10K::Features).to receive(:available?).with(:rugged).and_return true
17
- expect(described_class.default_name).to eq :rugged
14
+ context 'under c-based rubies', :unless => R10K::Util::Platform.jruby? do
15
+ it 'returns rugged when the git executable is absent and the rugged library is present' do
16
+ expect(R10K::Features).to receive(:available?).with(:shellgit).and_return false
17
+ expect(R10K::Features).to receive(:available?).with(:rugged).and_return true
18
+ expect(described_class.default_name).to eq :rugged
19
+ end
18
20
  end
19
21
 
20
22
  it 'raises an error when the git executable and rugged library are absent' do
@@ -51,24 +53,50 @@ describe R10K::Git do
51
53
  }.to raise_error(R10K::Error, "Git provider 'shellgit' is not functional.")
52
54
  end
53
55
 
54
- it "sets the current provider if the provider exists and is functional" do
55
- expect(R10K::Features).to receive(:available?).with(:rugged).and_return true
56
- described_class.provider = :rugged
57
- expect(described_class.provider).to eq(R10K::Git::Rugged)
56
+ context 'under c-based rubies', :unless => R10K::Util::Platform.jruby? do
57
+ it "sets the current provider if the provider exists and is functional" do
58
+ expect(R10K::Features).to receive(:available?).with(:rugged).and_return true
59
+ described_class.provider = :rugged
60
+ expect(described_class.provider).to eq(R10K::Git::Rugged)
61
+ end
62
+ end
63
+
64
+ context 'under jruby', :if => R10K::Util::Platform.jruby? do
65
+ it "sets the current provider if the provider exists and is functional" do
66
+ expect(R10K::Features).to receive(:available?).with(:shellgit).and_return true
67
+ described_class.provider = :shellgit
68
+ expect(described_class.provider).to eq(R10K::Git::ShellGit)
69
+ end
58
70
  end
59
71
  end
60
72
 
61
73
  describe "retrieving the current provider" do
62
- it "uses the default if a provider has not been set" do
63
- expect(described_class).to receive(:default_name).and_return :rugged
64
- expect(described_class.provider).to eq(R10K::Git::Rugged)
74
+ context 'under c-based rubies', :unless => R10K::Util::Platform.jruby? do
75
+ it "uses the default if a provider has not been set" do
76
+ expect(described_class).to receive(:default_name).and_return :rugged
77
+ expect(described_class.provider).to eq(R10K::Git::Rugged)
78
+ end
79
+
80
+ it "uses an explicitly set provider" do
81
+ expect(R10K::Features).to receive(:available?).with(:rugged).and_return true
82
+ described_class.provider = :rugged
83
+ expect(described_class).to_not receive(:default)
84
+ expect(described_class.provider).to eq R10K::Git::Rugged
85
+ end
65
86
  end
66
87
 
67
- it "uses an explicitly set provider" do
68
- expect(R10K::Features).to receive(:available?).with(:rugged).and_return true
69
- described_class.provider = :rugged
70
- expect(described_class).to_not receive(:default)
71
- expect(described_class.provider).to eq R10K::Git::Rugged
88
+ context 'under jruby', :if => R10K::Util::Platform.jruby? do
89
+ it "uses the default if a provider has not been set" do
90
+ expect(described_class).to receive(:default_name).and_return :shellgit
91
+ expect(described_class.provider).to eq(R10K::Git::ShellGit)
92
+ end
93
+
94
+ it "uses an explicitly set provider" do
95
+ expect(R10K::Features).to receive(:available?).with(:shellgit).and_return true
96
+ described_class.provider = :shellgit
97
+ expect(described_class).to_not receive(:default)
98
+ expect(described_class.provider).to eq R10K::Git::ShellGit
99
+ end
72
100
  end
73
101
  end
74
102
  end
@@ -59,6 +59,13 @@ describe R10K::Settings::Container do
59
59
  expect(subject[:v]).to eq 'child'
60
60
  end
61
61
 
62
+ it 'duplicates and stores the parent object to avoid modifying the parent object' do
63
+ parent[:v] = {}
64
+ subject[:v][:hello] = "world"
65
+ expect(subject[:v]).to eq({hello: "world"})
66
+ expect(parent[:v]).to eq({})
67
+ end
68
+
62
69
  it 'falls back to the parent value if it does not have a value' do
63
70
  parent[:v] = 'parent'
64
71
  expect(subject[:v]).to eq 'parent'
@@ -149,7 +149,14 @@ describe R10K::Settings do
149
149
  describe "git settings" do
150
150
  it "passes settings through to the git settings" do
151
151
  output = subject.evaluate("git" => {"provider" => "shellgit", "username" => "git"})
152
- expect(output[:git]).to eq(:provider => :shellgit, :username => "git", :private_key => nil)
152
+ expect(output[:git]).to eq(:provider => :shellgit, :username => "git", :private_key => nil, :repositories => [])
153
+ end
154
+
155
+ it "handles keywords in repository settings" do
156
+ output = subject.evaluate("git" => {"provider" => "shellgit",
157
+ "username" => "git",
158
+ "repositories" => [ {"remote" => "foo"} ]})
159
+ expect(output[:git]).to eq(:provider => :shellgit, :username => "git", :private_key => nil, :repositories => [{remote: "foo"}])
153
160
  end
154
161
  end
155
162
 
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'r10k/util/subprocess/runner'
3
3
 
4
- describe R10K::Util::Subprocess::Runner::Windows do
4
+ describe R10K::Util::Subprocess::Runner::Windows, :if => R10K::Util::Platform.windows? do
5
5
  fixture_root = File.expand_path('spec/fixtures/unit/util/subprocess/runner', PROJECT_ROOT)
6
6
  it_behaves_like 'a subprocess runner', fixture_root
7
7
  end
metadata CHANGED
@@ -1,18 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: r10k
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.2.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Adrien Thebo
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-11-13 00:00:00.000000000 Z
12
+ date: 2016-03-09 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: colored
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - '='
18
20
  - !ruby/object:Gem::Version
@@ -20,6 +22,7 @@ dependencies:
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
27
  - - '='
25
28
  - !ruby/object:Gem::Version
@@ -27,6 +30,7 @@ dependencies:
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: cri
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
35
  - - ~>
32
36
  - !ruby/object:Gem::Version
@@ -34,6 +38,7 @@ dependencies:
34
38
  type: :runtime
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
43
  - - ~>
39
44
  - !ruby/object:Gem::Version
@@ -41,6 +46,7 @@ dependencies:
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: log4r
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
51
  - - '='
46
52
  - !ruby/object:Gem::Version
@@ -48,6 +54,7 @@ dependencies:
48
54
  type: :runtime
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
59
  - - '='
53
60
  - !ruby/object:Gem::Version
@@ -55,6 +62,7 @@ dependencies:
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: multi_json
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
67
  - - ~>
60
68
  - !ruby/object:Gem::Version
@@ -62,6 +70,7 @@ dependencies:
62
70
  type: :runtime
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
75
  - - ~>
67
76
  - !ruby/object:Gem::Version
@@ -69,6 +78,7 @@ dependencies:
69
78
  - !ruby/object:Gem::Dependency
70
79
  name: puppet_forge
71
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
72
82
  requirements:
73
83
  - - ~>
74
84
  - !ruby/object:Gem::Version
@@ -76,55 +86,15 @@ dependencies:
76
86
  type: :runtime
77
87
  prerelease: false
78
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
79
90
  requirements:
80
91
  - - ~>
81
92
  - !ruby/object:Gem::Version
82
93
  version: 2.1.1
83
- - !ruby/object:Gem::Dependency
84
- name: faraday
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ~>
88
- - !ruby/object:Gem::Version
89
- version: 0.9.0
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ~>
95
- - !ruby/object:Gem::Version
96
- version: 0.9.0
97
- - !ruby/object:Gem::Dependency
98
- name: faraday_middleware
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ~>
102
- - !ruby/object:Gem::Version
103
- version: 0.9.0
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ~>
109
- - !ruby/object:Gem::Version
110
- version: 0.9.0
111
- - !ruby/object:Gem::Dependency
112
- name: faraday_middleware-multi_json
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ~>
116
- - !ruby/object:Gem::Version
117
- version: 0.0.6
118
- type: :runtime
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ~>
123
- - !ruby/object:Gem::Version
124
- version: 0.0.6
125
94
  - !ruby/object:Gem::Dependency
126
95
  name: semantic_puppet
127
96
  requirement: !ruby/object:Gem::Requirement
97
+ none: false
128
98
  requirements:
129
99
  - - ~>
130
100
  - !ruby/object:Gem::Version
@@ -132,6 +102,7 @@ dependencies:
132
102
  type: :runtime
133
103
  prerelease: false
134
104
  version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
135
106
  requirements:
136
107
  - - ~>
137
108
  - !ruby/object:Gem::Version
@@ -139,6 +110,7 @@ dependencies:
139
110
  - !ruby/object:Gem::Dependency
140
111
  name: minitar
141
112
  requirement: !ruby/object:Gem::Requirement
113
+ none: false
142
114
  requirements:
143
115
  - - ! '>='
144
116
  - !ruby/object:Gem::Version
@@ -146,6 +118,7 @@ dependencies:
146
118
  type: :runtime
147
119
  prerelease: false
148
120
  version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
149
122
  requirements:
150
123
  - - ! '>='
151
124
  - !ruby/object:Gem::Version
@@ -153,6 +126,7 @@ dependencies:
153
126
  - !ruby/object:Gem::Dependency
154
127
  name: rspec
155
128
  requirement: !ruby/object:Gem::Requirement
129
+ none: false
156
130
  requirements:
157
131
  - - ~>
158
132
  - !ruby/object:Gem::Version
@@ -160,6 +134,7 @@ dependencies:
160
134
  type: :development
161
135
  prerelease: false
162
136
  version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
163
138
  requirements:
164
139
  - - ~>
165
140
  - !ruby/object:Gem::Version
@@ -167,6 +142,7 @@ dependencies:
167
142
  - !ruby/object:Gem::Dependency
168
143
  name: yard
169
144
  requirement: !ruby/object:Gem::Requirement
145
+ none: false
170
146
  requirements:
171
147
  - - ~>
172
148
  - !ruby/object:Gem::Version
@@ -174,6 +150,7 @@ dependencies:
174
150
  type: :development
175
151
  prerelease: false
176
152
  version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
177
154
  requirements:
178
155
  - - ~>
179
156
  - !ruby/object:Gem::Version
@@ -209,6 +186,7 @@ files:
209
186
  - doc/git/cloning-and-mirroring.mkd
210
187
  - doc/git/providers.mkd
211
188
  - doc/puppetfile.mkd
189
+ - doc/updating-your-puppetfile.mkd
212
190
  - integration/Gemfile
213
191
  - integration/README.mkd
214
192
  - integration/configs/README.mkd
@@ -391,8 +369,6 @@ files:
391
369
  - lib/r10k/module/local.rb
392
370
  - lib/r10k/module/metadata_file.rb
393
371
  - lib/r10k/module/svn.rb
394
- - lib/r10k/module_repository.rb
395
- - lib/r10k/module_repository/forge.rb
396
372
  - lib/r10k/puppetfile.rb
397
373
  - lib/r10k/settings.rb
398
374
  - lib/r10k/settings/collection.rb
@@ -420,6 +396,7 @@ files:
420
396
  - lib/r10k/util/subprocess.rb
421
397
  - lib/r10k/util/subprocess/result.rb
422
398
  - lib/r10k/util/subprocess/runner.rb
399
+ - lib/r10k/util/subprocess/runner/jruby.rb
423
400
  - lib/r10k/util/subprocess/runner/posix.rb
424
401
  - lib/r10k/util/subprocess/runner/pump.rb
425
402
  - lib/r10k/util/subprocess/runner/windows.rb
@@ -496,7 +473,6 @@ files:
496
473
  - spec/unit/module/git_spec.rb
497
474
  - spec/unit/module/metadata_file_spec.rb
498
475
  - spec/unit/module/svn_spec.rb
499
- - spec/unit/module_repository/forge_spec.rb
500
476
  - spec/unit/module_spec.rb
501
477
  - spec/unit/puppetfile_spec.rb
502
478
  - spec/unit/settings/collection_spec.rb
@@ -526,26 +502,26 @@ files:
526
502
  homepage: https://github.com/puppetlabs/r10k
527
503
  licenses:
528
504
  - Apache-2.0
529
- metadata: {}
530
505
  post_install_message:
531
506
  rdoc_options: []
532
507
  require_paths:
533
508
  - lib
534
509
  required_ruby_version: !ruby/object:Gem::Requirement
510
+ none: false
535
511
  requirements:
536
512
  - - ! '>='
537
513
  - !ruby/object:Gem::Version
538
514
  version: 1.9.3
539
515
  required_rubygems_version: !ruby/object:Gem::Requirement
516
+ none: false
540
517
  requirements:
541
518
  - - ! '>='
542
519
  - !ruby/object:Gem::Version
543
520
  version: '0'
544
521
  requirements: []
545
522
  rubyforge_project:
546
- rubygems_version: 2.4.8
523
+ rubygems_version: 1.8.29
547
524
  signing_key:
548
- specification_version: 4
525
+ specification_version: 3
549
526
  summary: Puppet environment and module deployment
550
527
  test_files: []
551
- has_rdoc:
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MTVkMmIxYThmNTlhNWYzZDA2OGM2ZTk4NWY1NGUwODcxNzViNDU2MA==
5
- data.tar.gz: !binary |-
6
- MjIwNDQ0NjhkNTgyNWUxMDgzN2U0OWQ4MDYzYjMxZTk4Y2ZmMmM1ZQ==
7
- SHA512:
8
- metadata.gz: !binary |-
9
- NTQ5YjcxZWI0OWI4MGRiMWUyNjkxODgyYTNhMmM1YjFhNTdkYjFhOTg2MTU5
10
- OTM0ZWJmNDBkYzA1NjhlMzVmODdjYWYxODAwY2UxYTA0YzIyYjQ1N2ZjNmY4
11
- N2JlMWViZGM0ZTRhOTU4M2IxMTUzZDQ4NzEzY2NmODE0MmQzY2U=
12
- data.tar.gz: !binary |-
13
- ZGFiMTA0NTE1NTBkODA2ZGVjOTcwZWMwMTlkMmI1NTdkMDRmY2FkMjYyMWRm
14
- YWQ3NDViNjU3Y2UyOTkzM2RkOGM3M2YxNjRjY2FjODU1ZmFjMmQ1YTNjNGNm
15
- MTYxZmVmMGFmMzMyYTI3OTg2ZTJjMzQ4Nzk3OWE0OTU3ODg1OGI=
@@ -1,8 +0,0 @@
1
- module R10K
2
-
3
- # Locations that can be queried for remote module metadata
4
- module ModuleRepository
5
-
6
- require 'r10k/module_repository/forge'
7
- end
8
- end
@@ -1,81 +0,0 @@
1
- require 'r10k/module_repository'
2
- require 'r10k/version'
3
- require 'r10k/logging'
4
- require 'r10k/errors'
5
-
6
- require 'faraday'
7
- require 'faraday_middleware/multi_json'
8
- require 'faraday_middleware'
9
-
10
- class R10K::ModuleRepository::Forge
11
-
12
- include R10K::Logging
13
-
14
- # @!attribute [r] forge
15
- # @return [String] The forge hostname to use for requests
16
- attr_reader :forge
17
-
18
- # @!attribute [r] :conn
19
- # @api private
20
- # @return [Faraday]
21
- attr_reader :conn
22
-
23
- def initialize(forge = 'forgeapi.puppetlabs.com')
24
- if forge =~ /forge\.puppetlabs\.com/
25
- logger.warn("#{forge} does not support the latest puppet forge API. Please update to \"forge 'https://forgeapi.puppetlabs.com'\"")
26
- forge = 'forgeapi.puppetlabs.com'
27
- end
28
- @forge = forge
29
- @conn = make_conn
30
- end
31
-
32
- # Query for all published versions of a module
33
- #
34
- # @example
35
- # forge = R10K::ModuleRepository::Forge.new
36
- # forge.versions('adrien/boolean')
37
- # #=> ["0.9.0-rc1", "0.9.0", "1.0.0", "1.0.1"]
38
- #
39
- # @param module_name [String] The fully qualified module name
40
- # @return [Array<String>] All published versions of the given module
41
- def versions(module_name)
42
- path = "/v3/modules/#{module_name.tr('/','-')}"
43
- response = @conn.get(path)
44
-
45
- if response.status != 200
46
- raise R10K::Error.new("Request to Puppet Forge '#{path}' failed. Status: #{response.status}")
47
- end
48
-
49
- releases = response.body['releases'].reject { |r| r['deleted_at'] }
50
- releases = releases.map do |version_info|
51
- version_info['version']
52
- end
53
- releases.reverse
54
- end
55
-
56
- # Query for the newest published version of a module
57
- #
58
- # @example
59
- # forge = R10K::ModuleRepository::Forge.new
60
- # forge.latest_version('adrien/boolean')
61
- # #=> "1.0.1"
62
- #
63
- # @param module_name [String] The fully qualified module name
64
- # @return [String] The latest published version of the given module
65
- def latest_version(module_name)
66
- versions(module_name).last
67
- end
68
-
69
- private
70
-
71
- def make_conn
72
- Faraday.new(:url => "https://#{@forge}") do |builder|
73
- builder.request(:multi_json)
74
- builder.response(:multi_json)
75
-
76
- # This needs to be _after_ request/response configuration for testing
77
- # purposes. Without this ordering the tests get badly mangled.
78
- builder.adapter(Faraday.default_adapter)
79
- end
80
- end
81
- end
@@ -1,83 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'faraday'
4
-
5
- require 'r10k/module_repository/forge'
6
-
7
- describe R10K::ModuleRepository::Forge do
8
-
9
- let(:faraday_stubs) { Faraday::Adapter::Test::Stubs.new }
10
-
11
- let(:conn) do
12
- Faraday.new { |builder| builder.adapter(:test, faraday_stubs) }
13
- end
14
-
15
- before do
16
- allow_any_instance_of(described_class).to receive(:make_conn).and_return conn
17
- end
18
-
19
- it "uses the official forge by default" do
20
- forge = described_class.new
21
- expect(forge.forge).to eq 'forgeapi.puppetlabs.com'
22
- end
23
-
24
- it "replaces old forge with forgeapi" do
25
- forge = described_class.new(forge='forge.puppetlabs.com')
26
- expect(forge.forge).to eq 'forgeapi.puppetlabs.com'
27
- end
28
-
29
- it "can use a private forge" do
30
- forge = described_class.new('forge.example.local')
31
- expect(forge.forge).to eq 'forge.example.local'
32
- end
33
-
34
- describe "and the expected version is :latest" do
35
- subject(:forge) { described_class.new }
36
-
37
- let(:boolean_body) do
38
- {"releases" => [
39
- {"version" => "1.0.1"},
40
- {"version" => "1.0.0"},
41
- {"version" => "0.9.0"}
42
- ]
43
- }
44
- end
45
-
46
- let(:spotty_body) do
47
- {"releases" => [
48
- {"version" => "0.4.0", "deleted_at" => "some point"},
49
- {"version" => "0.3.0"}
50
- ]
51
- }
52
- end
53
-
54
- before do
55
- faraday_stubs.get('/v3/modules/adrien-boolean') { [200, {}, boolean_body] }
56
- faraday_stubs.get('/v3/modules/r10ktesting-spotty') { [200, {}, spotty_body] }
57
- end
58
-
59
- it "can fetch all versions of a given module" do
60
- expect(forge.versions('adrien/boolean')).to eq ["0.9.0", "1.0.0", "1.0.1"]
61
- end
62
-
63
- it "can fetch the latest version of a given module" do
64
- expect(forge.latest_version('adrien/boolean')).to eq "1.0.1"
65
- end
66
-
67
- it "ignores deleted releases" do
68
- expect(forge.latest_version('r10ktesting/spotty')).to eq "0.3.0"
69
- end
70
- end
71
-
72
- describe "it handles errors from forgeapi.puppetlabs.com" do
73
- subject(:forge) { described_class.new }
74
-
75
- before do
76
- faraday_stubs.get('/v3/modules/dne-dne') { [404, {}, 'not found'] }
77
- end
78
-
79
- it "raises an error for a non-existant module" do
80
- expect { forge.versions('dne/dne') }.to raise_error(R10K::Error)
81
- end
82
- end
83
- end