ra10ke 0.6.0 → 1.1.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.
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tempfile'
4
+
5
+ module Ra10ke
6
+ class GitRepo
7
+ attr_reader :url
8
+
9
+ REMOTE_REFS_CMD = 'git ls-remote --symref'
10
+ CLONE_CMD = 'git clone --no-tags'
11
+ CURRENT_BRANCH_CMD = 'git symbolic-ref --short HEAD'
12
+ SHOW_CMD = 'git show'
13
+
14
+ def initialize(url)
15
+ @url = url
16
+ end
17
+
18
+ # Get the current branch for a Git repo
19
+ # @param path [String] - The path to the repository to check
20
+ # @return [String] - The current active branch of the Git repo
21
+ def self.current_branch(path)
22
+ Dir.chdir(path) do
23
+ data, success = run_command(CURRENT_BRANCH_CMD)
24
+ return success ? data.strip : nil
25
+ end
26
+ end
27
+
28
+ # @return [Array] - the raw data from the git ls-remote command as lines array
29
+ # return empty array if url or command failed
30
+ def remote_refs
31
+ @remote_refs ||= begin
32
+ data, success = run_command("#{REMOTE_REFS_CMD} #{url}")
33
+ success ? data.lines : []
34
+ end
35
+ end
36
+
37
+ # @return [Boolean] true if the git url is valid
38
+ def valid_url?
39
+ !remote_refs.empty?
40
+ end
41
+
42
+ # @return [Boolean] - return true if the commit sha is valid
43
+ # @param url [String] - the git string either https or ssh url
44
+ # @param ref [String] - the sha id
45
+ def valid_commit?(sha)
46
+ return false if sha.nil? || sha.empty?
47
+ return true if valid_ref?(sha)
48
+
49
+ # cloning is a last resort if for some reason we cannot
50
+ # remotely get via ls-remote
51
+ Dir.mktmpdir do |dir|
52
+ run_command("#{CLONE_CMD} #{url} #{dir}", silent: true)
53
+ Dir.chdir(dir) do
54
+ _, status = run_command("#{SHOW_CMD} #{sha}", silent: true)
55
+ status
56
+ end
57
+ end
58
+ end
59
+
60
+ # @return [Boolean] - return true if the ref is valid
61
+ # @param url [String] - the git string either https or ssh url
62
+ # @param ref [String] - the ref object, branch name, tag name, or commit sha, defaults to HEAD
63
+ def valid_ref?(ref = 'HEAD')
64
+ return false if ref.nil?
65
+
66
+ found = all_refs.find do |data|
67
+ # we don't need to bother with these types
68
+ next if data[:type] == :pull || data[:type] == :merge_request
69
+
70
+ # is the name equal to the tag or branch? Is the commit sha equal?
71
+ data[:name].eql?(ref) || data[:sha].slice(0, 8).eql?(ref.slice(0, 8))
72
+ end
73
+ !found.nil?
74
+ end
75
+
76
+ # @return [Array] - an array of all the refs associated with the remote repository
77
+ # @param url [String] - the git string either https or ssh url
78
+ # @example
79
+ # [{:sha=>"0ec707e431367bbe2752966be8ab915b6f0da754", :ref=>"refs/heads/74110ac", :type=>:branch, :subtype=>nil, :name=>"74110ac"},
80
+ # :sha=>"07bb5d2d94db222dca5860eb29c184e8970f36f4", :ref=>"refs/pull/74/head", :type=>:pull, :subtype=>:head, :name=>"74"},
81
+ # :sha=>"156ca9a8ea69e056e86355b27d944e59d1b3a1e1", :ref=>"refs/heads/master", :type=>:branch, :subtype=>nil, :name=>"master"},
82
+ # :sha=>"fcc0532bbc5a5b65f3941738339e9cc7e3d767ce", :ref=>"refs/pull/249/head", :type=>:pull, :subtype=>:head, :name=>"249"},
83
+ # :sha=>"8d54891fa5df75890ee15d53080c2a81b4960f92", :ref=>"refs/pull/267/head", :type=>:pull, :subtype=>:head, :name=>"267"}]
84
+ def all_refs
85
+ @all_refs ||= begin
86
+ remote_refs.each_with_object([]) do |line, refs|
87
+ sha, ref = line.split("\t")
88
+ next refs if sha.eql?('ref: refs/heads/master')
89
+
90
+ _, type, name, subtype = ref.chomp.split('/')
91
+ next refs unless name
92
+
93
+ type = :tag if type.eql?('tags')
94
+ type = type.to_sym
95
+ subtype = subtype.to_sym if subtype
96
+ type = :branch if type.eql?(:heads)
97
+ refs << { sha: sha, ref: ref.chomp, type: type, subtype: subtype, name: name }
98
+ end
99
+ end
100
+ end
101
+
102
+ # useful for mocking easily
103
+ # @param cmd [String]
104
+ # @param silent [Boolean] set to true if you wish to send output to /dev/null, false by default
105
+ # @return [Array]
106
+ def self.run_command(cmd, silent: false)
107
+ out_args = silent ? '2>&1 > /dev/null' : '2>&1'
108
+ out = `#{cmd} #{out_args}`
109
+ [out, $CHILD_STATUS.success?]
110
+ end
111
+
112
+ def run_command(cmd, silent: false)
113
+ self.class.run_command(cmd, silent: silent)
114
+ end
115
+ end
116
+ end
@@ -12,6 +12,13 @@ module Ra10ke
12
12
  end
13
13
  end
14
14
 
15
+ # @return [Array] - returns a array of hashes that contain modules from the Forge
16
+ def forge_modules(file = puppetfile)
17
+ modules(file).reject do |mod|
18
+ mod[:args].key?(:git)
19
+ end
20
+ end
21
+
15
22
  # @param puppetfile [String] - the absolute path to the puppetfile
16
23
  # @return [Array] - returns an array of module hashes that represent the puppetfile
17
24
  # @example
@@ -23,8 +30,8 @@ module Ra10ke
23
30
 
24
31
  all_lines = File.read(puppetfile).lines.map(&:strip_comment)
25
32
  # 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|
33
+ lines_without_comments = all_lines.reject { |line| line.match(/#.*\n/) }.join("\n")
34
+ lines_without_comments.split(/^mod/).map do |line|
28
35
  next nil if line =~ /^forge/
29
36
  next nil if line.empty?
30
37
 
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'ra10ke/monkey_patches'
4
- require 'tempfile'
5
4
  require 'table_print'
6
5
  require 'ra10ke/puppetfile_parser'
7
6
  require 'English'
7
+ require 'ra10ke/git_repo'
8
8
 
9
9
  module Ra10ke
10
10
  module Validate
@@ -13,7 +13,7 @@ module Ra10ke
13
13
  BAD_EMOJI = ENV['BAD_EMOJI'] || '😨'
14
14
 
15
15
  # Validate the git urls and refs
16
- def define_task_validate(*args)
16
+ def define_task_validate(*)
17
17
  desc 'Validate the git urls and branches, refs, or tags'
18
18
  task :validate do
19
19
  gitvalididation = Ra10ke::Validate::Validation.new(get_puppetfile.puppetfile_path)
@@ -32,7 +32,7 @@ module Ra10ke
32
32
 
33
33
  class Validation
34
34
  include Ra10ke::PuppetfileParser
35
-
35
+
36
36
  attr_reader :puppetfile
37
37
 
38
38
  def initialize(file)
@@ -41,70 +41,28 @@ module Ra10ke
41
41
  abort("Puppetfile does not exist at #{puppetfile}") unless File.readable?(puppetfile)
42
42
  end
43
43
 
44
- # @return [Boolean] - return true if the ref is valid
45
- # @param url [String] - the git string either https or ssh url
46
- # @param ref [String] - the ref object, branch name, tag name, or commit sha, defaults to HEAD
47
- def valid_ref?(url, ref = 'HEAD')
48
- raise ArgumentError unless ref
49
- found = all_refs(url).find do |sha, data |
50
- # we don't need to bother with these types
51
- next if data[:type] == :pull || data[:type] == :merge_request
52
- # is the name equal to the tag or branch? Is the commit sha equal?
53
- data[:name].eql?(ref) || sha.slice(0,8).eql?(ref.slice(0,8))
54
- end
55
- !found.nil?
56
- end
57
-
58
- # @return [Hash] - a hash of all the refs associated with the remote repository
59
- # @param url [String] - the git string either https or ssh url
60
- # @example
61
- # {"0ec707e431367bbe2752966be8ab915b6f0da754"=>{:ref=>"refs/heads/74110ac", :type=>:branch, :subtype=>nil, :name=>"74110ac"},
62
- # "07bb5d2d94db222dca5860eb29c184e8970f36f4"=>{:ref=>"refs/pull/74/head", :type=>:pull, :subtype=>:head, :name=>"74"},
63
- # "156ca9a8ea69e056e86355b27d944e59d1b3a1e1"=>{:ref=>"refs/heads/master", :type=>:branch, :subtype=>nil, :name=>"master"},
64
- # "fcc0532bbc5a5b65f3941738339e9cc7e3d767ce"=>{:ref=>"refs/pull/249/head", :type=>:pull, :subtype=>:head, :name=>"249"},
65
- # "8d54891fa5df75890ee15d53080c2a81b4960f92"=>{:ref=>"refs/pull/267/head", :type=>:pull, :subtype=>:head, :name=>"267"} }
66
- def all_refs(url)
67
- data = `git ls-remote --symref #{url}`
68
- raise "Error downloading #{url}" unless $CHILD_STATUS.success?
69
- data.lines.reduce({}) do |refs, line|
70
- sha, ref = line.split("\t")
71
- next refs if sha.eql?('ref: refs/heads/master')
72
- _, type, name, subtype = ref.chomp.split('/')
73
- next refs unless name
74
- type = :tag if type.eql?('tags')
75
- type = type.to_sym
76
- subtype = subtype.to_sym if subtype
77
- type = :branch if type.eql?(:heads)
78
- refs[sha] = {ref: ref.chomp, type: type, subtype: subtype, name: name }
79
- refs
80
- end
81
- end
82
-
83
- # @return [Boolean] - return true if the commit sha is valid
84
- # @param url [String] - the git string either https or ssh url
85
- # @param ref [String] - the sha id
86
- def valid_commit?(url, sha)
87
- return false if sha.nil? || sha.empty?
88
- return true if valid_ref?(url, sha)
89
- Dir.mktmpdir do |dir|
90
- `git clone --no-tags #{url} #{dir} 2>&1 > /dev/null`
91
- Dir.chdir(dir) do
92
- `git show #{sha} 2>&1 > /dev/null`
93
- $CHILD_STATUS.success?
94
- end
95
- end
96
- end
97
-
98
44
  # @return [Array[Hash]] array of module information and git status
99
45
  def all_modules
100
- begin
46
+ @all_modules ||= begin
47
+ r10k_branch = Ra10ke::GitRepo.current_branch(File.dirname(puppetfile))
101
48
  git_modules(puppetfile).map do |mod|
49
+ repo = Ra10ke::GitRepo.new(mod[:args][:git])
102
50
  ref = mod[:args][:ref] || mod[:args][:tag] || mod[:args][:branch]
103
- valid_ref = valid_ref?(mod[:args][:git], ref) || valid_commit?(mod[:args][:git], mod[:args][:ref])
51
+ # If using control_branch, try to guesstimate what the target branch should be
52
+ if ref == ':control_branch'
53
+ ref = ENV['CONTROL_BRANCH'] \
54
+ || r10k_branch \
55
+ || mod[:args][:default_branch_override] \
56
+ || ENV['CONTROL_BRANCH_FALLBACK'] \
57
+ || mod[:args][:default_branch] \
58
+ || 'main'
59
+ end
60
+ valid_ref = repo.valid_ref?(ref) || repo.valid_commit?(mod[:args][:ref])
104
61
  {
105
62
  name: mod[:name],
106
- url: mod[:args][:git],
63
+ url: repo.url,
107
64
  ref: ref,
65
+ valid_url?: repo.valid_url?,
108
66
  valid_ref?: valid_ref,
109
67
  status: valid_ref ? Ra10ke::Validate::GOOD_EMOJI : Ra10ke::Validate::BAD_EMOJI
110
68
  }
@@ -1,3 +1,3 @@
1
1
  module Ra10ke
2
- VERSION = "0.6.0"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/ra10ke.rb CHANGED
@@ -4,6 +4,8 @@ require 'ra10ke/version'
4
4
  require 'ra10ke/solve'
5
5
  require 'ra10ke/syntax'
6
6
  require 'ra10ke/dependencies'
7
+ require 'ra10ke/deprecation'
8
+ require 'ra10ke/duplicates'
7
9
  require 'ra10ke/install'
8
10
  require 'ra10ke/validate'
9
11
  require 'git'
@@ -14,6 +16,8 @@ module Ra10ke
14
16
  include Ra10ke::Solve
15
17
  include Ra10ke::Syntax
16
18
  include Ra10ke::Dependencies
19
+ include Ra10ke::Deprecation
20
+ include Ra10ke::Duplicates
17
21
  include Ra10ke::Install
18
22
  include Ra10ke::Validate
19
23
 
@@ -33,6 +37,8 @@ module Ra10ke
33
37
  define_task_solve_dependencies(*args)
34
38
  define_task_syntax(*args)
35
39
  define_task_dependencies(*args)
40
+ define_task_deprecation(*args)
41
+ define_task_duplicates(*args)
36
42
  define_task_install(*args)
37
43
  define_task_validate(*args)
38
44
  end
@@ -40,6 +46,8 @@ module Ra10ke
40
46
 
41
47
  def get_puppetfile
42
48
  R10K::Puppetfile.new(@basedir, @moduledir, @puppetfile_path, @puppetfile_name, @force)
49
+ rescue ArgumentError # R10k < 2.6.0
50
+ R10K::Puppetfile.new(@basedir, @moduledir, @puppetfile_path || File.join(@basedir, @puppetfile_name || 'Puppetfile'))
43
51
  end
44
52
  end
45
53
  end
data/ra10ke.gemspec CHANGED
@@ -5,8 +5,8 @@ require 'ra10ke/version'
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "ra10ke"
7
7
  spec.version = Ra10ke::VERSION
8
- spec.authors = ["Theo Chatzimichos"]
9
- spec.email = ["tampakrap@gmail.com"]
8
+ spec.authors = ["Theo Chatzimichos", "Vox Pupuli"]
9
+ spec.email = ["voxpupuli@groups.io"]
10
10
  spec.description = %q{R10K and Puppetfile rake tasks}
11
11
  spec.summary = %q{Syntax check for the Puppetfile, check for outdated installed puppet modules}
12
12
  spec.homepage = "https://github.com/voxpupuli/ra10ke"
@@ -14,14 +14,17 @@ Gem::Specification.new do |spec|
14
14
 
15
15
  spec.files = `git ls-files`.split($/)
16
16
  spec.require_paths = ["lib"]
17
- spec.required_ruby_version = '>= 2.1.0'
17
+ spec.required_ruby_version = '>= 2.4.0'
18
18
 
19
19
  spec.add_dependency "rake"
20
20
  spec.add_dependency "puppet_forge"
21
21
  spec.add_dependency "r10k"
22
22
  spec.add_dependency "git"
23
23
  spec.add_dependency "solve"
24
- spec.add_dependency 'semverse', '~> 2.0'
24
+ spec.add_dependency 'semverse', '>= 2.0'
25
25
  spec.add_dependency 'table_print', '~> 1.5.6'
26
26
  spec.add_development_dependency 'rspec', '~> 3.6'
27
+ spec.add_development_dependency 'pry'
28
+ spec.add_development_dependency 'simplecov'
27
29
  end
30
+
@@ -2,7 +2,9 @@
2
2
 
3
3
  forge 'http://forge.puppetlabs.com'
4
4
 
5
+ mod 'choria/choria', '0.26.2'
5
6
  mod 'puppetlabs/inifile', '2.2.0'
7
+ mod 'puppetlabs-ruby', '1.0.1'
6
8
  mod 'puppetlabs/stdlib', '4.24.0'
7
9
  mod 'puppetlabs/concat', '4.0.0'
8
10
  mod 'puppetlabs/ntp', '6.4.1'
@@ -40,4 +42,8 @@ mod 'dotfiles',
40
42
 
41
43
  mod 'splunk',
42
44
  git: 'https://github.com/cudgel/splunk.git',
43
- branch: 'prod'
45
+ branch: 'dev'
46
+
47
+ mod 'puppet',
48
+ git: 'https://github.com/voxpupuli/puppet-module.git',
49
+ branch: 'master'
@@ -7,4 +7,7 @@ mod 'gitlab',
7
7
  mod 'r10k',
8
8
  :git => 'https://github.com/acidprime/r10k',
9
9
  :tag => 'bad'
10
+
11
+ mod 'debug',
12
+ :git => 'https://github.com/nwops/typo'
10
13
 
@@ -0,0 +1,23 @@
1
+ mod 'puppet-hiera_master',
2
+ git: 'https://github.com/voxpupuli/puppet-hiera_master.git',
3
+ branch: master
4
+
5
+ mod 'puppet-hiera_control',
6
+ git: 'https://github.com/voxpupuli/puppet-hiera_control.git',
7
+ branch: :control_branch
8
+
9
+ mod 'puppet-hiera_controlwithdefault',
10
+ git: 'https://github.com/voxpupuli/puppet-hiera_control.git',
11
+ branch: :control_branch,
12
+ default_branch: 'master'
13
+
14
+ mod 'puppet-hiera_controlwithdefaultoverride',
15
+ git: 'https://github.com/voxpupuli/puppet-hiera_control.git',
16
+ branch: :control_branch,
17
+ default_branch_override: 'master',
18
+ default_branch: 'devel'
19
+
20
+ mod 'puppet-hiera_fakecontrol',
21
+ git: 'https://github.com/voxpupuli/puppet-hiera_fakecontrol.git',
22
+ branch: control_branch
23
+
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ forge 'http://forge.puppetlabs.com'
4
+
5
+ mod 'abstractit/puppet', '2.4.1'
6
+ mod 'puppet/gitlab', '4.0.1'
7
+ mod 'puppetlabs/inifile', '2.2.0'
8
+ mod 'puppetlabs/stdlib', '4.24.0'
9
+ mod 'puppetlabs/concat', '4.0.0'
10
+ mod 'puppetlabs/ntp', '6.4.1'
11
+ mod 'theforeman/puppet', '12.0.1'
12
+
13
+ # introduced for tomcat module collaboration with uws
14
+ mod 'puppet-archive', '3.1.1'
15
+
16
+ mod 'gitlab',
17
+ git: 'https://github.com/vshn/puppet-gitlab',
18
+ ref: '00397b86dfb3487d9df768cbd3698d362132b5bf' # master
19
+
20
+ mod 'r10k',
21
+ git: 'https://github.com/acidprime/r10k',
22
+ tag: 'v3.1.1'
23
+
24
+ mod 'gms',
25
+ git: 'https://github.com/npwalker/abrader-gms',
26
+ branch: 'gitlab_disable_ssl_verify_support'
27
+
28
+ mod 'pltraining-rbac',
29
+ git: 'https://github.com/puppetlabs/pltraining-rbac',
30
+ ref: '2f60e1789a721ce83f8df061e13f8bf81cd4e4ce'
31
+
32
+ mod 'puppet-acl',
33
+ git: 'https://github.com/dobbymoodge/puppet-acl.git',
34
+ branch: 'master'
35
+
36
+ mod 'deploy',
37
+ git: 'https://github.com/cudgel/deploy.git',
38
+ branch: 'master'
39
+
40
+ mod 'dotfiles',
41
+ git: 'https://github.com/cudgel/puppet-dotfiles.git',
42
+ branch: 'master'
43
+
44
+ mod 'splunk',
45
+ git: 'https://github.com/cudgel/splunk.git',
46
+ branch: 'dev'
47
+
48
+ mod 'puppet',
49
+ git: 'https://github.com/voxpupuli/puppet-module.git',
50
+ branch: 'master'
File without changes