ra10ke 0.5.0 → 0.6.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ad7a9bc9ed535980433aee2a10afc3fe6b0060b9b85764fc692e1086bfabf46
4
- data.tar.gz: b1c37034b07281ffe040748f34339acfd4cb0f82a014c4512463e077c645778b
3
+ metadata.gz: 244a7664e31597a415668faaeb3cf43b3c0243cf6aed478183f91317230e68eb
4
+ data.tar.gz: d241ae0aafcb1031dc1d6ef86a69796f79bcfefefe39622b22d5b165be34c696
5
5
  SHA512:
6
- metadata.gz: 041f1c23f5cb71e8adbd419c9fd8a1b3662c536d5d5cbf7e2410db2c8d9f3c9e47673f257e29bb3a3ab900700f4bb219261e1d38d2b101983a828f33f1c2b5c6
7
- data.tar.gz: 9fc86d2fe74f4c866cf1a4de68fb0dae662a952a4d9f5402ae983a966e607bad1bbec5f4943bdc5b29ba039d9bf5e9e5867711de5bc89e7c40b20c2056b018e1
6
+ metadata.gz: a889ad1d1f59c4781b895e7abc1f05b0b24776f7976f6c01bb6e45f258239908413f39d5e95def2cc032475243cb27aa39087b937fe6dd3e0a35147b28a6c0bb
7
+ data.tar.gz: e4ee4b06d70659f4fc836b90eb73ce22b1fc28076076704da334db5e52ddcd5fe138a0cf95edf80a86afea4885d1fd7fe883621ee04c0fc975a3ac32047711f9
data/.gitignore CHANGED
@@ -1 +1,3 @@
1
1
  Gemfile.lock
2
+ pkg
3
+ .bundle
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.5.3
data/CHANGELOG.md CHANGED
@@ -1,6 +1,22 @@
1
1
  CHANGELOG
2
2
  =========
3
3
 
4
+ 0.6.0
5
+ -----
6
+
7
+ 2019-07-30
8
+
9
+ Closed Pull Requests:
10
+
11
+ * [#35](https://github.com/voxpupuli/ra10ke/pull/35) Adds new validate task for verifying the integrity of all modules specified in the Puppetfile
12
+ * [#33](https://github.com/voxpupuli/ra10ke/pull/33) Refactor tasks, Version tag handling fix, purge option
13
+ * [#32](https://github.com/voxpupuli/ra10ke/pull/32) Make it possible to configure the tasks in the rakefile
14
+
15
+ Many thanks to the following contributors for submitting PRs:
16
+
17
+ * [Corey Osman](https://github.com/logicminds)
18
+ * [Andreas Zuber](https://github.com/ZeroPointEnergy)
19
+
4
20
  0.5.0
5
21
  -----
6
22
 
data/README.md CHANGED
@@ -13,12 +13,35 @@ Add the following line to your `Gemfile`:
13
13
  gem 'ra10ke'
14
14
  ```
15
15
 
16
- Add the following line in your `Rakefile`:
16
+ Add the following lines in your `Rakefile`:
17
17
 
18
18
  ```ruby
19
19
  require 'ra10ke'
20
+ Ra10ke::RakeTask.new
20
21
  ```
21
22
 
23
+ ## Configuration
24
+
25
+ You can configure the tasks in a block:
26
+
27
+ ```ruby
28
+ Ra10ke::RakeTask.new do |t|
29
+ t.basedir = File.join(Dir.pwd, 'some_dir')
30
+ t.moduledir = File.join(Dir.pwd, 'some_dir/strange_module_dir')
31
+ end
32
+ ```
33
+
34
+ Available settings are:
35
+
36
+ | Setting | Documentation |
37
+ |-----------------|-----------------------------------------------------------------------------------------------|
38
+ | basedir | Base directory with the Puppetfile and modules directory (Default: Same directory as Rakefile)|
39
+ | moduledir | Directory to install the modules in (Default: 'modules' in basedir) |
40
+ | puppetfile_path | Directroy where the Puppetfile is (Default: basedir) |
41
+ | puppetfile_name | The Puppetfile name (Default: basedir/Puppetfile) |
42
+ | force | Overwrite locally changed files on install (Default: false) |
43
+ | purge | Purge unmanaged modules from the modulesdir (Default: false) |
44
+
22
45
  ## Rake tasks
23
46
 
24
47
  ### r10k:syntax
@@ -56,6 +79,41 @@ runs faster.
56
79
 
57
80
  Reads the Puppetfile in the current directory and installs them under the `path` provided as an argument.
58
81
 
82
+ ### r10k:validate[path]
83
+ The validate rake task will determine if the url is a valid url by connecting
84
+ to the repository and verififying it actually exists and can be accessed.
85
+ Additional if a branch, tag, or ref is specified in the Puppetfile the validate
86
+ task will also verify that that branch/tag/ref exists in the remote repository.
87
+
88
+ If you have ever deployed r10k to production only to find out a tag or branch is
89
+ missing this validate task will catch that issue.
90
+
91
+ A exit status of 0 is returned if there are no faults, while a 1 is returned if
92
+ any module has a bad status.
93
+
94
+ Status emojis can be customized by setting the following environment variables.
95
+
96
+ Example
97
+
98
+ * `GOOD_EMOJI='👍'`
99
+ * `BAD_EMOJI='😨'`
100
+
101
+
102
+ ```
103
+ NAME | URL | REF | STATUS
104
+ ---------|-----------------------------------------------|--------------------------------|-------
105
+ splunk | https://github.com/cudgel/splunk.git | prod | 👍
106
+ r10k | https://github.com/acidprime/r10k | v3.1.1 | 👍
107
+ gms | https://github.com/npwalker/abrader-gms | gitlab_disable_ssl_verify_s... | 👍
108
+ rbac | https://github.com/puppetlabs/pltraining-rbac | 2f60e1789a721ce83f8df061e13... | 👍
109
+ acl | https://github.com/dobbymoodge/puppet-acl.git | master | 👍
110
+ deploy | https://github.com/cudgel/deploy.git | master | 👍
111
+ dotfiles | https://github.com/cudgel/puppet-dotfiles.git | master | 👍
112
+ gitlab | https://github.com/vshn/puppet-gitlab | 00397b86dfb3487d9df768cbd36... | 👍
113
+
114
+ 👍👍 Puppetfile looks good.👍👍
115
+ ```
116
+
59
117
  #### Limitations
60
118
 
61
119
  * It works only with modules from the [Forge](https://forge.puppetlabs.com), and Git.
data/Rakefile CHANGED
@@ -3,8 +3,14 @@ require 'rake/clean'
3
3
  require 'rubygems'
4
4
  require 'bundler/gem_tasks'
5
5
  require 'fileutils'
6
+ require 'rspec/core'
7
+ require 'rspec/core/rake_task'
6
8
 
7
9
  CLEAN.include("pkg/", "tmp/")
8
10
  CLOBBER.include("Gemfile.lock")
9
11
 
10
- task :default => [:clean, :build]
12
+ task :default => [:spec]
13
+
14
+ RSpec::Core::RakeTask.new(:spec) do |spec|
15
+ spec.pattern = FileList['spec/**/*_spec.rb']
16
+ end
@@ -0,0 +1,71 @@
1
+ module Ra10ke::Dependencies
2
+ def define_task_dependencies(*_args)
3
+ desc "Print outdated forge modules"
4
+ task :dependencies do
5
+ require 'r10k/puppetfile'
6
+ require 'puppet_forge'
7
+
8
+ PuppetForge.user_agent = "ra10ke/#{Ra10ke::VERSION}"
9
+ puppetfile = get_puppetfile
10
+ puppetfile.load!
11
+ PuppetForge.host = puppetfile.forge if puppetfile.forge =~ /^http/
12
+
13
+ # ignore file allows for "don't tell me about this"
14
+ ignore_modules = []
15
+ if File.exist?('.r10kignore')
16
+ ignore_modules = File.readlines('.r10kignore').each {|l| l.chomp!}
17
+ end
18
+
19
+ puppetfile.modules.each do |puppet_module|
20
+ next if ignore_modules.include? puppet_module.title
21
+ if puppet_module.class == R10K::Module::Forge
22
+ module_name = puppet_module.title.gsub('/', '-')
23
+ forge_version = PuppetForge::Module.find(module_name).current_release.version
24
+ installed_version = puppet_module.expected_version
25
+ if installed_version != forge_version
26
+ puts "#{puppet_module.title} is OUTDATED: #{installed_version} vs #{forge_version}"
27
+ end
28
+ end
29
+
30
+ if puppet_module.class == R10K::Module::Git
31
+ # use helper; avoid `desired_ref`
32
+ # we do not want to deal with `:control_branch`
33
+ ref = puppet_module.version
34
+ next unless ref
35
+
36
+ remote = puppet_module.instance_variable_get(:@remote)
37
+ remote_refs = Git.ls_remote(remote)
38
+
39
+ # skip if ref is a branch
40
+ next if remote_refs['branches'].key?(ref)
41
+
42
+ if remote_refs['tags'].key?(ref)
43
+ # there are too many possible versioning conventions
44
+ # we have to be be opinionated here
45
+ # so semantic versioning (vX.Y.Z) it is for us
46
+ # as well as support for skipping the leading v letter
47
+ tags = remote_refs['tags'].keys
48
+ latest_tag = tags.map do |tag|
49
+ begin
50
+ Semverse::Version.new tag[/\Av?(.*)\Z/, 1]
51
+ rescue Semverse::InvalidVersionFormat
52
+ # ignore tags that do not comply to semver
53
+ nil
54
+ end
55
+ end.select { |tag| !tag.nil? }.sort.last.to_s.downcase
56
+ latest_ref = tags.detect { |tag| tag[/\Av?(.*)\Z/, 1] == latest_tag }
57
+ latest_ref = 'undef (tags do not match semantic versioning)' if latest_ref.nil?
58
+ elsif ref.match(/^[a-z0-9]{40}$/)
59
+ # for sha just assume head should be tracked
60
+ latest_ref = remote_refs['head'][:sha]
61
+ else
62
+ raise "Unable to determine ref type for #{puppet_module.title}"
63
+ end
64
+
65
+ puts "#{puppet_module.title} is OUTDATED: #{ref} vs #{latest_ref}" if ref != latest_ref
66
+ end
67
+ end
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,32 @@
1
+ module Ra10ke::Install
2
+ def define_task_install(*_args)
3
+ desc "Install modules specified in Puppetfile"
4
+ task :install do
5
+ require 'r10k/puppetfile'
6
+
7
+ puppetfile = get_puppetfile
8
+ puppetfile.load!
9
+
10
+ puts "Processing Puppetfile for fixtures"
11
+ puppetfile.modules.each do |mod|
12
+ if mod.status == :insync
13
+ puts "Skipping #{mod.name} (#{mod.version}) already in sync"
14
+ else
15
+ if mod.status == :absent
16
+ msg = "installed #{mod.name}"
17
+ else
18
+ msg = "updated #{mod.name} from #{mod.version} to"
19
+ end
20
+ mod.sync
21
+ if mod.status != :insync
22
+ puts "Failed to sync #{mod.name}".red
23
+ else
24
+ puts "Successfully #{msg} #{mod.version}".green
25
+ end
26
+ end
27
+ end
28
+
29
+ puppetfile.purge! if @purge
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class String
4
+ # colorization
5
+ def colorize(color_code)
6
+ "\e[#{color_code}m#{self}\e[0m"
7
+ end
8
+
9
+ def red
10
+ colorize(31)
11
+ end
12
+
13
+ def green
14
+ colorize(32)
15
+ end
16
+
17
+ def yellow
18
+ colorize(33)
19
+ end
20
+
21
+ # removes specified markes from string.
22
+ # @return [String] - the string with markers removed
23
+ def strip_comment(markers = ['#', "\n"])
24
+ re = Regexp.union(markers)
25
+ index = (self =~ re)
26
+ index.nil? ? rstrip : self[0, index].rstrip
27
+ end
28
+ end
@@ -0,0 +1,83 @@
1
+ # it might be desirable to parse the Puppetfile as a string instead of evaling it.
2
+ # this module allows you to do just that.
3
+ require 'ra10ke/monkey_patches'
4
+
5
+ module Ra10ke
6
+ module PuppetfileParser
7
+
8
+ # @return [Array] - returns a array of hashes that contain modules with a git source
9
+ def git_modules(file = puppetfile)
10
+ modules(file).find_all do |mod|
11
+ mod[:args].key?(:git)
12
+ end
13
+ end
14
+
15
+ # @param puppetfile [String] - the absolute path to the puppetfile
16
+ # @return [Array] - returns an array of module hashes that represent the puppetfile
17
+ # @example
18
+ # [{:namespace=>"puppetlabs", :name=>"stdlib", :args=>[]},
19
+ # {:namespace=>"petems", :name=>"swap_file", :args=>["'4.0.0'"]}]
20
+ def modules(puppetfile)
21
+ @modules ||= begin
22
+ return [] unless File.exist?(puppetfile)
23
+
24
+ all_lines = File.read(puppetfile).lines.map(&:strip_comment)
25
+ # remove comments from all the lines
26
+ lines_without_comments = all_lines.reject { |line| line.match(/#.*\n/) }.join("\n").delete("\n")
27
+ lines_without_comments.split('mod').map do |line|
28
+ next nil if line =~ /^forge/
29
+ next nil if line.empty?
30
+
31
+ parse_module_args(line)
32
+ end.compact.uniq
33
+ end
34
+ end
35
+
36
+ # @param data [String] - the string to parse the puppetfile args out of
37
+ # @return [Array] - an array of arguments in hash form
38
+ # @example
39
+ # {:namespace=>"puppetlabs", :name=>"stdlib", :args=>[]}
40
+ # {:namespace=>"petems", :name=>"swap_file", :args=>["'4.0.0'"]}
41
+ def parse_module_args(data)
42
+ return {} if data.empty?
43
+ args = data.split(',').map(&:strip)
44
+ # we can't guarantee that there will be a namespace when git is used
45
+ # remove quotes and dash and slash
46
+ namespace, name = args.shift.gsub(/'|"/, '').split(%r{-|/})
47
+ name ||= namespace
48
+ namespace = nil if namespace == name
49
+ {
50
+ namespace: namespace,
51
+ name: name,
52
+ args: process_args(args)
53
+ }
54
+ end
55
+
56
+ # @return [Array] - returns an array of hashes with the args in key value pairs
57
+ # @param [Array] - the arguments processed from each entry in the puppetfile
58
+ # @example
59
+ # [{:args=>[], :name=>"razor", :namespace=>"puppetlabs"},
60
+ # {:args=>[{:version=>"0.0.3"}], :name=>"ntp", :namespace=>"puppetlabs"},
61
+ # {:args=>[], :name=>"inifile", :namespace=>"puppetlabs"},
62
+ # {:args=>
63
+ # [{:git=>"https://github.com/nwops/reportslack.git"}, {:ref=>"1.0.20"}],
64
+ # :name=>"reportslack",
65
+ # :namespace=>"nwops"},
66
+ # {:args=>{:git=>"git://github.com/puppetlabs/puppetlabs-apt.git"},
67
+ # :name=>"apt",
68
+ # :namespace=>nil}
69
+ # ]
70
+ def process_args(args)
71
+ results = {}
72
+ args.each do |arg|
73
+ a = arg.gsub(/'|"/, '').split(/\A\:|\:\s|\=\>/).map(&:strip).reject(&:empty?)
74
+ if a.count < 2
75
+ results[:version] = a.first
76
+ else
77
+ results[a.first.to_sym] = a.last
78
+ end
79
+ end
80
+ results
81
+ end
82
+ end
83
+ end