r10k 1.5.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +15 -0
  2. data/.travis.yml +0 -1
  3. data/CHANGELOG.mkd +63 -0
  4. data/Gemfile +2 -2
  5. data/README.mkd +1 -10
  6. data/doc/dynamic-environments/configuration.mkd +24 -6
  7. data/doc/dynamic-environments/quickstart.mkd +1 -1
  8. data/integration/Gemfile +1 -1
  9. data/integration/configs/pe/centos-5-64mda +25 -0
  10. data/integration/configs/pe/centos-6-64mda +1 -1
  11. data/integration/configs/pe/centos-7-64mda +1 -1
  12. data/integration/configs/pe/debian-6-64mda +1 -1
  13. data/integration/configs/pe/debian-7-64mda +1 -1
  14. data/integration/configs/pe/redhat-6-64mda +1 -1
  15. data/integration/configs/pe/redhat-7-64mda +1 -1
  16. data/integration/configs/pe/sles-11-64mda +1 -1
  17. data/integration/configs/pe/sles-12-64mda +25 -0
  18. data/integration/configs/pe/ubuntu-1004-64mda +1 -1
  19. data/integration/configs/pe/ubuntu-1204-64mda +1 -1
  20. data/integration/configs/pe/ubuntu-1404-64mda +1 -1
  21. data/integration/files/pre-suite/git_config.pp.erb +19 -0
  22. data/integration/pre-suite/01_git_config.rb +5 -17
  23. data/integration/pre-suite/02_pe_r10k.rb +0 -2
  24. data/integration/scripts/README.mkd +86 -0
  25. data/integration/scripts/setup_r10k_env_centos5.sh +23 -0
  26. data/integration/scripts/setup_r10k_env_centos6.sh +23 -0
  27. data/integration/scripts/setup_r10k_env_rhel7.sh +23 -0
  28. data/integration/scripts/setup_r10k_env_sles11.sh +23 -0
  29. data/integration/scripts/setup_r10k_env_sles12.sh +23 -0
  30. data/integration/scripts/setup_r10k_env_ubuntu1004.sh +23 -0
  31. data/integration/scripts/setup_r10k_env_ubuntu1204.sh +23 -0
  32. data/integration/scripts/setup_r10k_env_ubuntu1404.sh +23 -0
  33. data/integration/tests/basic_functionality/negative/neg_invalid_git_provider.rb +44 -0
  34. data/integration/tests/basic_functionality/rugged_git_provider_with_ssh.rb +106 -0
  35. data/integration/tests/basic_functionality/rugged_git_provider_without_ssh.rb +107 -0
  36. data/integration/tests/git_source/git_source_git.rb +1 -1
  37. data/integration/tests/git_source/git_source_ssh.rb +1 -1
  38. data/integration/tests/git_source/negative/neg_git_unauthorized_https.rb +1 -1
  39. data/integration/tests/git_source/negative/neg_git_unauthorized_ssh.rb +1 -1
  40. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_basedir.rb +1 -1
  41. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_git_module.rb +8 -2
  42. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_git_module_ref.rb +1 -1
  43. data/integration/tests/user_scenario/basic_workflow/negative/neg_bad_git_remote.rb +1 -1
  44. data/integration/tests/user_scenario/basic_workflow/negative/neg_branch_name_collision.rb +1 -1
  45. data/integration/tests/user_scenario/basic_workflow/negative/neg_disk_full.rb +5 -1
  46. data/integration/tests/user_scenario/basic_workflow/negative/neg_duplicate_module_names.rb +3 -3
  47. data/integration/tests/user_scenario/basic_workflow/negative/neg_invalid_puppet_file.rb +1 -1
  48. data/integration/tests/user_scenario/basic_workflow/negative/neg_read_only.rb +1 -1
  49. data/integration/tests/user_scenario/basic_workflow/single_env_10000_files.rb +4 -0
  50. data/integration/tests/user_scenario/basic_workflow/single_env_large_files.rb +4 -0
  51. data/integration/tests/user_scenario/complex_workflow/multi_env_unamanaged.rb +77 -0
  52. data/integration/tests/user_scenario/complex_workflow/single_env_git_module_update.rb +99 -0
  53. data/lib/r10k/action/deploy/display.rb +0 -1
  54. data/lib/r10k/action/runner.rb +20 -0
  55. data/lib/r10k/cli.rb +0 -3
  56. data/lib/r10k/cli/deploy.rb +0 -3
  57. data/lib/r10k/deployment.rb +1 -7
  58. data/lib/r10k/deployment/config.rb +15 -1
  59. data/lib/r10k/deployment/config/loader.rb +0 -11
  60. data/lib/r10k/environment/git.rb +0 -9
  61. data/lib/r10k/environment/svn.rb +0 -9
  62. data/lib/r10k/errors.rb +0 -3
  63. data/lib/r10k/feature.rb +24 -3
  64. data/lib/r10k/forge/module_release.rb +142 -0
  65. data/lib/r10k/git.rb +32 -11
  66. data/lib/r10k/module/forge.rb +25 -54
  67. data/lib/r10k/module_repository/forge.rb +2 -5
  68. data/lib/r10k/puppetfile.rb +1 -1
  69. data/lib/r10k/util/license.rb +20 -0
  70. data/lib/r10k/version.rb +1 -1
  71. data/lib/shared/puppet_forge/connection.rb +62 -0
  72. data/lib/shared/puppet_forge/error.rb +28 -0
  73. data/lib/shared/puppet_forge/tar.rb +10 -0
  74. data/lib/shared/puppet_forge/tar/mini.rb +81 -0
  75. data/lib/shared/puppet_forge/unpacker.rb +68 -0
  76. data/lib/shared/puppet_forge/v3.rb +13 -0
  77. data/lib/shared/puppet_forge/v3/module.rb +66 -0
  78. data/lib/shared/puppet_forge/v3/module_release.rb +73 -0
  79. data/lib/shared/puppet_forge/version.rb +3 -0
  80. data/r10k.gemspec +2 -2
  81. data/r10k.yaml.example +80 -5
  82. data/spec/spec_helper.rb +0 -12
  83. data/spec/unit/action/runner_spec.rb +53 -0
  84. data/spec/unit/deployment/config/loader_spec.rb +5 -19
  85. data/spec/unit/deployment/config_spec.rb +8 -0
  86. data/spec/unit/deployment_spec.rb +1 -1
  87. data/spec/unit/forge/module_release_spec.rb +130 -0
  88. data/spec/unit/git_spec.rb +5 -5
  89. data/spec/unit/module/forge_spec.rb +66 -116
  90. data/spec/unit/module_repository/forge_spec.rb +35 -5
  91. data/spec/unit/module_spec.rb +10 -10
  92. data/spec/unit/puppet_forge/connection_spec.rb +41 -0
  93. data/spec/unit/puppet_forge/tar/mini_spec.rb +87 -0
  94. data/spec/unit/puppet_forge/tar_spec.rb +9 -0
  95. data/spec/unit/puppet_forge/unpacker_spec.rb +59 -0
  96. data/spec/unit/puppet_forge/v3/module_release_spec.rb +68 -0
  97. data/spec/unit/puppet_forge/v3/module_spec.rb +67 -0
  98. metadata +48 -112
  99. data/lib/r10k/cli/environment.rb +0 -28
  100. data/lib/r10k/cli/environment/deploy.rb +0 -26
  101. data/lib/r10k/cli/environment/list.rb +0 -23
  102. data/lib/r10k/cli/environment/stale.rb +0 -24
  103. data/lib/r10k/cli/module.rb +0 -29
  104. data/lib/r10k/cli/module/deploy.rb +0 -27
  105. data/lib/r10k/cli/module/list.rb +0 -24
  106. data/lib/r10k/cli/synchronize.rb +0 -27
  107. data/lib/r10k/deployment/basedir.rb +0 -4
  108. data/lib/r10k/deployment/environment.rb +0 -20
  109. data/lib/r10k/deployment/source.rb +0 -37
  110. data/lib/r10k/git/commit.rb +0 -22
  111. data/lib/r10k/git/head.rb +0 -36
  112. data/lib/r10k/git/ref.rb +0 -66
  113. data/lib/r10k/git/remote_head.rb +0 -19
  114. data/lib/r10k/git/repository.rb +0 -158
  115. data/lib/r10k/git/tag.rb +0 -29
  116. data/lib/r10k/git/working_dir.rb +0 -186
  117. data/lib/r10k/registry.rb +0 -4
  118. data/lib/r10k/semver.rb +0 -128
  119. data/lib/r10k/task.rb +0 -12
  120. data/lib/r10k/task/deployment.rb +0 -164
  121. data/lib/r10k/task/environment.rb +0 -31
  122. data/lib/r10k/task/module.rb +0 -19
  123. data/lib/r10k/task/puppetfile.rb +0 -102
  124. data/lib/r10k/task_runner.rb +0 -72
  125. data/lib/r10k/util/monkey_patches.rb +0 -11
  126. data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/and_the_expected_version_is_latest/can_fetch_all_versions_of_a_given_module.yml +0 -187
  127. data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/and_the_expected_version_is_latest/can_fetch_the_latest_version_of_a_given_module.yml +0 -187
  128. data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/and_the_expected_version_is_latest/ignores_deleted_releases.yml +0 -190
  129. data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/it_handles_errors_from_forgeapi_puppetlabs_com/raises_an_error_for_a_non-existant_module.yml +0 -34
  130. data/spec/fixtures/vcr/cassettes/R10K_Module_Forge/and_the_expected_version_is_latest/sets_the_expected_version_based_on_the_latest_forge_version.yml +0 -103
  131. data/spec/shared-examples/git-ref.rb +0 -49
  132. data/spec/unit/deployment/environment_spec.rb +0 -25
  133. data/spec/unit/git/commit_spec.rb +0 -34
  134. data/spec/unit/git/head_spec.rb +0 -22
  135. data/spec/unit/git/ref_spec.rb +0 -45
  136. data/spec/unit/git/repository_spec.rb +0 -34
  137. data/spec/unit/git/tag_spec.rb +0 -32
  138. data/spec/unit/git/working_dir_spec.rb +0 -122
  139. data/spec/unit/util/monkey_patches_spec.rb +0 -20
@@ -8,6 +8,8 @@ module R10K
8
8
  class Deployment
9
9
  class Config
10
10
 
11
+ include R10K::Logging
12
+
11
13
  attr_accessor :configfile
12
14
 
13
15
  def initialize(configfile)
@@ -41,7 +43,7 @@ class Config
41
43
  loader = R10K::Deployment::Config::Loader.new
42
44
  @configfile = loader.search
43
45
  if @configfile.nil?
44
- raise ConfigError, "No configuration file given, no config file found in parent directory, and no global config present"
46
+ raise ConfigError, "No configuration file given, no config file found in current directory, and no global config present"
45
47
  end
46
48
  end
47
49
  begin
@@ -61,10 +63,22 @@ class Config
61
63
 
62
64
  # Apply global configuration settings.
63
65
  def apply_config_settings
66
+ with_setting(:purgedirs) do |purgedirs|
67
+ logger.warn("The purgedirs key in r10k.yaml is deprecated. It is currently ignored.")
68
+ end
69
+
64
70
  with_setting(:cachedir) do |cachedir|
65
71
  R10K::Git::Cache.settings[:cache_root] = cachedir
66
72
  end
67
73
 
74
+ with_setting(:forge) do |forge_settings|
75
+ R10K::Util::SymbolizeKeys.symbolize_keys!(forge_settings)
76
+ proxy = forge_settings[:proxy]
77
+ if proxy
78
+ R10K::Forge::ModuleRelease.settings[:proxy] = proxy
79
+ end
80
+ end
81
+
68
82
  with_setting(:git) do |git_settings|
69
83
  R10K::Util::SymbolizeKeys.symbolize_keys!(git_settings)
70
84
  provider = git_settings[:provider]
@@ -11,7 +11,6 @@ module R10K
11
11
 
12
12
  CONFIG_FILE = 'r10k.yaml'
13
13
  DEFAULT_LOCATION = File.join('/etc/puppetlabs/r10k', CONFIG_FILE)
14
- OLD_DEFAULT_LOCATION = File.join('/etc', CONFIG_FILE)
15
14
 
16
15
  # Search for a deployment configuration file (r10k.yaml) in several locations
17
16
  def initialize
@@ -21,13 +20,6 @@ module R10K
21
20
 
22
21
  # @return [String] The path to the first valid configfile
23
22
  def search
24
-
25
- # If both default files are present, issue a warning.
26
- if (File.file? DEFAULT_LOCATION) && (File.file? OLD_DEFAULT_LOCATION)
27
- logger.warn "Both #{DEFAULT_LOCATION} and #{OLD_DEFAULT_LOCATION} configuration files exist."
28
- logger.warn "#{DEFAULT_LOCATION} will be used."
29
- end
30
-
31
23
  first = @loadpath.find {|filename| File.file? filename}
32
24
  end
33
25
 
@@ -41,9 +33,6 @@ module R10K
41
33
  # Add the AIO location for of r10k.yaml
42
34
  @loadpath << DEFAULT_LOCATION
43
35
 
44
- # Add the old default location last.
45
- @loadpath << OLD_DEFAULT_LOCATION
46
-
47
36
  @loadpath
48
37
  end
49
38
  end
@@ -55,13 +55,4 @@ class R10K::Environment::Git < R10K::Environment::Base
55
55
  extend Forwardable
56
56
 
57
57
  def_delegators :@repo, :status
58
-
59
- # @deprecated
60
- # @api private
61
- def sync_modules
62
- modules.each do |mod|
63
- logger.debug "Deploying module #{mod.name}"
64
- mod.sync
65
- end
66
- end
67
58
  end
@@ -77,13 +77,4 @@ class R10K::Environment::SVN < R10K::Environment::Base
77
77
  :insync
78
78
  end
79
79
  end
80
-
81
- # @deprecated
82
- # @api private
83
- def sync_modules
84
- modules.each do |mod|
85
- logger.debug "Deploying module #{mod.name}"
86
- mod.sync
87
- end
88
- end
89
80
  end
@@ -40,7 +40,4 @@ module R10K
40
40
  @options = options
41
41
  end
42
42
  end
43
-
44
- # @deprecated
45
- R10KError = Error
46
43
  end
@@ -1,7 +1,11 @@
1
+ require 'r10k/logging'
2
+
1
3
  module R10K
2
4
  # Detect whether a given feature is present or absent
3
5
  class Feature
4
6
 
7
+ include R10K::Logging
8
+
5
9
  # @attribute [r] name
6
10
  # @return [Symbol] The name of this feature
7
11
  attr_reader :name
@@ -15,21 +19,38 @@ module R10K
15
19
  def initialize(name, opts = {}, &block)
16
20
  @name = name
17
21
  @libraries = Array(opts.delete(:libraries))
18
- @block = block || lambda { true }
22
+ @block = block
19
23
  end
20
24
 
21
25
  # @return [true, false] Is this feature available?
22
26
  def available?
23
- @libraries.all? { |lib| library_available?(lib) } && !!@block.call
27
+ logger.debug1 { "Testing to see if feature #{@name} is available." }
28
+ rv = @libraries.all? { |lib| library_available?(lib) } && proc_available?
29
+ msg = rv ? "is" : "is not"
30
+ logger.debug1 { "Feature #{@name} #{msg} available." }
31
+ rv
24
32
  end
25
33
 
26
34
  private
27
35
 
28
36
  def library_available?(lib)
37
+ logger.debug2 { "Attempting to load library '#{lib}' for feature #{@name}" }
29
38
  require lib
30
39
  true
31
- rescue ScriptError
40
+ rescue ScriptError => e
41
+ logger.debug2 { "Error while loading library #{lib} for feature #{@name}: #{e.message}" }
32
42
  false
33
43
  end
44
+
45
+ def proc_available?
46
+ if @block
47
+ logger.debug2 { "Evaluating proc #{@block.inspect} to test for feature #{@name}" }
48
+ output = @block.call
49
+ logger.debug2 { "Proc #{@block.inspect} for feature #{@name} returned #{output.inspect}" }
50
+ !!output
51
+ else
52
+ true
53
+ end
54
+ end
34
55
  end
35
56
  end
@@ -0,0 +1,142 @@
1
+ require 'shared/puppet_forge/v3/module_release'
2
+ require 'shared/puppet_forge/unpacker'
3
+ require 'r10k/logging'
4
+ require 'r10k/settings/mixin'
5
+ require 'fileutils'
6
+ require 'forwardable'
7
+ require 'tmpdir'
8
+
9
+ module R10K
10
+ module Forge
11
+ # Download, unpack, and install modules from the Puppet Forge
12
+ class ModuleRelease
13
+
14
+ include R10K::Settings::Mixin
15
+
16
+ def_setting_attr :proxy
17
+
18
+ include R10K::Logging
19
+
20
+ # @!attribute [r] forge_release
21
+ # @api private
22
+ # @return [PuppetForge::V3::ModuleRelease] The Forge V3 API module
23
+ # release object used for downloading and verifying the module
24
+ # release.
25
+ attr_reader :forge_release
26
+
27
+ extend Forwardable
28
+
29
+ def_delegators :@forge_release, :slug, :data
30
+
31
+ # @!attribute [rw] download_path
32
+ # @return [Pathname] Where the module tarball will be downloaded to.
33
+ attr_accessor :download_path
34
+
35
+ # @!attribute [rw] unpack_path
36
+ # @return [Pathname] Where the module will be unpacked to.
37
+ attr_accessor :unpack_path
38
+
39
+ # @param full_name [String] The hyphen separated name of the module
40
+ # @param version [String] The version of the module
41
+ def initialize(full_name, version)
42
+ @full_name = PuppetForge::V3.normalize_name(full_name)
43
+ @version = version
44
+
45
+ @forge_release = PuppetForge::V3::ModuleRelease.new(@full_name, @version)
46
+ @forge_release.conn.proxy(proxy)
47
+
48
+ @download_path = Pathname.new(Dir.mktmpdir) + (slug + '.tar.gz')
49
+ @unpack_path = Pathname.new(Dir.mktmpdir) + slug
50
+ end
51
+
52
+ # Download, unpack, and install this module release to the target directory.
53
+ #
54
+ # @example
55
+ # environment_path = Pathname.new('/etc/puppetlabs/puppet/environments/production')
56
+ # target_dir = environment_path + 'eight_hundred'
57
+ # mod = R10K::Forge::ModuleRelease.new('branan-eight_hundred', '8.0.0')
58
+ # mod.install(target_dir)
59
+ #
60
+ # @param target_dir [Pathname] The full path to where the module should be installed.
61
+ # @return [void]
62
+ def install(target_dir)
63
+ download
64
+ verify
65
+ unpack(target_dir)
66
+ ensure
67
+ cleanup
68
+ end
69
+
70
+ # Download the module release to {#download_path}
71
+ #
72
+ # @return [void]
73
+ def download
74
+ logger.debug1 "Downloading #{@forge_release.slug} from #{@forge_release.conn.url_prefix} to #{@download_path}"
75
+ @forge_release.download(download_path)
76
+ end
77
+
78
+ # Verify the module release downloaded to {#download_path} against the
79
+ # module release checksum given by the Puppet Forge
80
+ #
81
+ # @raise [PuppetForge::V3::ModuleRelease::ChecksumMismatch] The
82
+ # downloaded module release checksum doesn't match the expected Forge
83
+ # module release checksum.
84
+ # @return [void]
85
+ def verify
86
+ logger.debug1 "Verifying that #{download_path} matches checksum #{data['file_md5']}"
87
+ @forge_release.verify(download_path)
88
+ end
89
+
90
+ # Unpack the module release at {#download_path} into the given target_dir
91
+ #
92
+ # @param target_dir [Pathname] The final path where the module release
93
+ # should be unpacked/installed into.
94
+ # @return [void]
95
+ def unpack(target_dir)
96
+ logger.debug1 "Unpacking #{download_path} to #{target_dir} (with tmpdir #{unpack_path})"
97
+ file_lists = PuppetForge::Unpacker.unpack(download_path.to_s, target_dir.to_s, unpack_path.to_s)
98
+ logger.debug2 "Valid files unpacked: #{file_lists[:valid]}"
99
+ if !file_lists[:invalid].empty?
100
+ logger.warn "These files existed in the module's tar file, but are invalid filetypes and were not " +
101
+ "unpacked: #{file_lists[:invalid]}"
102
+ end
103
+ if !file_lists[:symlinks].empty?
104
+ raise R10K::Error, "Symlinks are unsupported and were not unpacked from the module tarball. " +
105
+ "#{@forge_release.slug} contained these ignored symlinks: #{file_lists[:symlinks]}"
106
+ end
107
+ end
108
+
109
+ # Remove all files created while downloading and unpacking the module.
110
+ def cleanup
111
+ cleanup_unpack_path
112
+ cleanup_download_path
113
+ end
114
+
115
+ # Remove the temporary directory used for unpacking the module.
116
+ def cleanup_unpack_path
117
+ if unpack_path.exist?
118
+ unpack_path.rmtree
119
+ end
120
+ end
121
+
122
+ # Remove the downloaded module release.
123
+ def cleanup_download_path
124
+ if download_path.exist?
125
+ download_path.delete
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ def proxy
132
+ [
133
+ settings[:proxy],
134
+ ENV['HTTPS_PROXY'],
135
+ ENV['https_proxy'],
136
+ ENV['HTTP_PROXY'],
137
+ ENV['http_proxy']
138
+ ].find { |value| value }
139
+ end
140
+ end
141
+ end
142
+ end
@@ -1,18 +1,38 @@
1
1
  require 'r10k/features'
2
2
  require 'r10k/errors'
3
3
  require 'r10k/settings'
4
+ require 'r10k/logging'
4
5
 
5
6
  module R10K
6
7
  module Git
7
8
  require 'r10k/git/shellgit'
8
9
  require 'r10k/git/rugged'
9
10
 
11
+ extend R10K::Logging
12
+
10
13
  # A list of Git providers, sorted by priority. Providers have features that
11
14
  # must be available for them to be used, and a module which is the namespace
12
15
  # containing the implementation.
13
16
  @providers = [
14
- [:shellgit, {:feature => :shellgit, :module => R10K::Git::ShellGit}],
15
- [:rugged, {:feature => :rugged, :module => R10K::Git::Rugged}],
17
+ [ :shellgit,
18
+ {
19
+ :feature => :shellgit,
20
+ :module => R10K::Git::ShellGit,
21
+ }
22
+ ],
23
+ [ :rugged,
24
+ {
25
+ :feature => :rugged,
26
+ :module => R10K::Git::Rugged,
27
+ :on_set => proc do
28
+ [:ssh, :https].each do |transport|
29
+ if !::Rugged.features.include?(transport)
30
+ logger.warn "Rugged has been compiled without support for #{transport}; Git repositories will not be reachable via #{transport}."
31
+ end
32
+ end
33
+ end
34
+ }
35
+ ],
16
36
  ]
17
37
 
18
38
  # Mark the current provider as invalid.
@@ -39,14 +59,13 @@ module R10K
39
59
  # Return the first available Git provider.
40
60
  #
41
61
  # @raise [R10K::Error] if no Git providers are functional.
42
- # @return [Module] The namespace of the first available Git implementation.
43
- # Implementation classes should be looked up against this returned Module.
44
- def self.default
45
- _, attrs = @providers.find { |(_, hash)| R10K::Features.available?(hash[:feature]) }
46
- if attrs.nil?
62
+ # @return [String] The name of the first available Git implementation.
63
+ def self.default_name
64
+ name, _ = @providers.find { |(_, hash)| R10K::Features.available?(hash[:feature]) }
65
+ if name.nil?
47
66
  raise R10K::Error, "No Git providers are functional."
48
67
  end
49
- attrs[:module]
68
+ name
50
69
  end
51
70
 
52
71
  # Manually set the Git provider by name.
@@ -65,6 +84,9 @@ module R10K
65
84
  @provider = NULL_PROVIDER
66
85
  raise R10K::Error, "Git provider '#{name}' is not functional."
67
86
  end
87
+ if attrs[:on_set]
88
+ attrs[:on_set].call
89
+ end
68
90
  @provider = attrs[:module]
69
91
  end
70
92
 
@@ -75,10 +97,9 @@ module R10K
75
97
  when NULL_PROVIDER
76
98
  raise R10K::Error, "No Git provider set."
77
99
  when UNSET_PROVIDER
78
- @provider = default
79
- else
80
- @provider
100
+ self.provider = default_name
81
101
  end
102
+ @provider
82
103
  end
83
104
 
84
105
  def self.cache
@@ -2,19 +2,19 @@ require 'r10k/module'
2
2
  require 'r10k/errors'
3
3
  require 'shared/puppet/module_tool/metadata'
4
4
  require 'r10k/module/metadata_file'
5
- require 'r10k/util/subprocess'
6
- require 'r10k/module_repository/forge'
5
+
6
+ require 'r10k/forge/module_release'
7
+ require 'shared/puppet_forge/v3/module'
7
8
 
8
9
  require 'pathname'
9
10
  require 'fileutils'
10
- require 'r10k/semver'
11
11
 
12
12
  class R10K::Module::Forge < R10K::Module::Base
13
13
 
14
14
  R10K::Module.register(self)
15
15
 
16
16
  def self.implement?(name, args)
17
- !!(name.match %r[\w+/\w+])
17
+ !!(name.match %r[\w+[/-]\w+])
18
18
  end
19
19
 
20
20
  # @!attribute [r] metadata
@@ -22,18 +22,20 @@ class R10K::Module::Forge < R10K::Module::Base
22
22
  # @return [Puppet::ModuleTool::Metadata]
23
23
  attr_reader :metadata
24
24
 
25
+ # @!attribute [r] v3_module
26
+ # @api private
27
+ # @return [PuppetForge::V3::Module] The Puppet Forge module metadata
28
+ attr_reader :v3_module
29
+
25
30
  include R10K::Logging
26
31
 
27
- def initialize(title, dirname, args)
32
+ def initialize(title, dirname, expected_version)
28
33
  super
29
34
  @metadata_file = R10K::Module::MetadataFile.new(path + 'metadata.json')
30
35
  @metadata = @metadata_file.read
31
36
 
32
- if args.is_a? String
33
- @expected_version = R10K::SemVer.new(args)
34
- elsif args.is_a? Symbol and args == :latest
35
- @expected_version = args
36
- end
37
+ @expected_version = expected_version || current_version || :latest
38
+ @v3_module = PuppetForge::V3::Module.new(@title)
37
39
  end
38
40
 
39
41
  def sync(options = {})
@@ -55,17 +57,17 @@ class R10K::Module::Forge < R10K::Module::Base
55
57
  }
56
58
  end
57
59
 
58
- # @return [R10K::SemVer] The expected version that the module
60
+ # @return [String] The expected version that the module
59
61
  def expected_version
60
- if @expected_version.is_a?(Symbol) && @expected_version == :latest
61
- set_version_from_forge
62
+ if @expected_version == :latest
63
+ @expected_version = @v3_module.latest_version
62
64
  end
63
65
  @expected_version
64
66
  end
65
67
 
66
- # @return [R10K::SemVer] The version of the currently installed module
68
+ # @return [String] The version of the currently installed module
67
69
  def current_version
68
- @metadata.version
70
+ @metadata ? @metadata.version : nil
69
71
  end
70
72
 
71
73
  alias version current_version
@@ -113,26 +115,16 @@ class R10K::Module::Forge < R10K::Module::Base
113
115
  return :insync
114
116
  end
115
117
 
116
- private
117
-
118
118
  def install
119
- FileUtils.mkdir @dirname unless File.directory? @dirname
120
- cmd = []
121
- cmd << 'install'
122
- cmd << "--version=#{expected_version}" if expected_version
123
- cmd << "--force"
124
- cmd << title
125
- pmt cmd
119
+ parent_path = @path.parent
120
+ if !parent_path.exist?
121
+ parent_path.mkpath
122
+ end
123
+ module_release = R10K::Forge::ModuleRelease.new(@title, expected_version)
124
+ module_release.install(@path)
126
125
  end
127
126
 
128
- def upgrade
129
- cmd = []
130
- cmd << 'upgrade'
131
- cmd << "--version=#{expected_version}" if expected_version
132
- cmd << "--force"
133
- cmd << title
134
- pmt cmd
135
- end
127
+ alias upgrade install
136
128
 
137
129
  def uninstall
138
130
  FileUtils.rm_rf full_path
@@ -143,28 +135,7 @@ class R10K::Module::Forge < R10K::Module::Base
143
135
  install
144
136
  end
145
137
 
146
- # Wrap puppet module commands
147
- #
148
- # @param argv [Array<String>]
149
- #
150
- # @return [String] The stdout from the executed command
151
- def pmt(argv)
152
- argv = ['puppet', 'module', '--modulepath', @dirname, '--color', 'false'] + argv
153
-
154
- subproc = R10K::Util::Subprocess.new(argv)
155
- subproc.raise_on_fail = true
156
- subproc.logger = self.logger
157
-
158
- result = subproc.execute
159
-
160
- result.stdout
161
- end
162
-
163
- def set_version_from_forge
164
- repo = R10K::ModuleRepository::Forge.new
165
- expected = repo.latest_version(title)
166
- @expected_version = R10K::SemVer.new(expected)
167
- end
138
+ private
168
139
 
169
140
  # Override the base #parse_title to ensure we have a fully qualified name
170
141
  def parse_title(title)