ra10ke 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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