bourdain 1.2.13

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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/Gemfile +11 -0
  4. data/Rakefile +19 -0
  5. data/Readme.md +1 -0
  6. data/TODO.md +41 -0
  7. data/VERSION +1 -0
  8. data/bin/tony +54 -0
  9. data/bin/tony-bump +3 -0
  10. data/bin/tony-check +3 -0
  11. data/bin/tony-generate +3 -0
  12. data/bourdain.gemspec +25 -0
  13. data/install-or-upgrade.sh +4 -0
  14. data/lib/bourdain/helpers/config.rb +12 -0
  15. data/lib/bourdain/helpers/locals.rb +17 -0
  16. data/lib/bourdain/helpers/logger.rb +41 -0
  17. data/lib/bourdain/helpers/parser.rb +76 -0
  18. data/lib/bourdain/helpers/registry.rb +53 -0
  19. data/lib/bourdain/helpers.rb +32 -0
  20. data/lib/bourdain/metadata.rb +19 -0
  21. data/lib/bourdain/resources/checks/bourdain.rb +71 -0
  22. data/lib/bourdain/resources/checks/chef.rb +35 -0
  23. data/lib/bourdain/resources/checks/cookbooks.rb +97 -0
  24. data/lib/bourdain/resources/checks/hooks.rb +67 -0
  25. data/lib/bourdain/resources/checks/ssh_config.rb +61 -0
  26. data/lib/bourdain/resources/checks.rb +36 -0
  27. data/lib/bourdain/resources/commands/bump.rb +74 -0
  28. data/lib/bourdain/resources/commands/check.rb +103 -0
  29. data/lib/bourdain/resources/commands/generate.rb +33 -0
  30. data/lib/bourdain/resources/commands.rb +10 -0
  31. data/lib/bourdain/resources/generators/attribute.rb +43 -0
  32. data/lib/bourdain/resources/generators/cookbook.rb +125 -0
  33. data/lib/bourdain/resources/generators/recipe.rb +54 -0
  34. data/lib/bourdain/resources/generators.rb +22 -0
  35. data/lib/bourdain/resources.rb +104 -0
  36. data/lib/bourdain.rb +3 -0
  37. data/templates/chef/environment.json +8 -0
  38. data/templates/chef/role.json +9 -0
  39. data/templates/cookbook/Berksfile +3 -0
  40. data/templates/cookbook/Readme.md +1 -0
  41. data/templates/cookbook/VERSION +1 -0
  42. data/templates/cookbook/Vagrantfile +19 -0
  43. data/templates/cookbook/attributes/example.rb +24 -0
  44. data/templates/cookbook/busser_minitest.rb +7 -0
  45. data/templates/cookbook/gitignore +26 -0
  46. data/templates/cookbook/kitchen.yml +23 -0
  47. data/templates/cookbook/metadata.rb +10 -0
  48. data/templates/cookbook/pre-commit +80 -0
  49. data/templates/cookbook/recipes/example.rb +38 -0
  50. data/test.sh +12 -0
  51. metadata +165 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e3811bdc20aa707f202ca15513ada539a93c825d
4
+ data.tar.gz: 8b158824deaecb5e201fa0e46d2e2cab40e8d9b2
5
+ SHA512:
6
+ metadata.gz: 941638c93c4154d2911b1d4418d65ad65e7727abedc31fb4b4b469e85628e1bf0b900b9e6d69bb64112f21f8be5dedab58bee869cbb8d7a293366b1756b23089
7
+ data.tar.gz: b29f2437342970e19bd8f9b7ed53333663fef62096159d9a90474e12971476a2662e7697b5245d7b1928aa2077331b539d0b2a911d13a4718c111d129cf93db5
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ *~
2
+ *.log
3
+ *.out
4
+ *.pid
5
+ *.swp
6
+ *.gem
7
+ .DS_Store
8
+ Gemfile.lock
9
+ tmp
10
+ log
11
+ doc
12
+ .yarddoc
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'pry'
7
+ gem 'rake'
8
+ gem 'yard'
9
+ gem 'version'
10
+ gem 'rubygems-tasks'
11
+ end
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'rake'
4
+
5
+ require 'yard'
6
+ YARD::Rake::YardocTask.new do |t|
7
+ t.files = %w[ --readme Readme.md lib/**/*.rb - VERSION ]
8
+ end
9
+
10
+ require 'rake/version_task'
11
+ Rake::VersionTask.new
12
+
13
+ require 'rubygems/tasks'
14
+ Gem::Tasks.new({
15
+ sign: {}
16
+ }) do |tasks|
17
+ tasks.console.command = 'pry'
18
+ end
19
+ Gem::Tasks::Sign::Checksum.new sha2: true
data/Readme.md ADDED
@@ -0,0 +1 @@
1
+ # Bourdain
data/TODO.md ADDED
@@ -0,0 +1,41 @@
1
+ ~/.bourdain.json
2
+
3
+ Getting Smarter
4
+ Considers branch you're on
5
+ Considers version of branch on origin
6
+ Excludes changes in **/*.md
7
+
8
+ Default <options> are...
9
+ --help :: Show this message
10
+ --debug :: Enable debug logging
11
+ --jk :: Just explain what would happen
12
+
13
+ update [<options>]
14
+ Update the underlying Chef repo, cookbooks, and utilities
15
+ --pull :: Perform a git pull on resources (default: false)
16
+
17
+ generate user [<options>] <name>
18
+ Generate a new user data bag in the current repo
19
+ --shell <s> :: Choose a default shell (default: zsh)
20
+ --password <s> :: Provide a password for authentication
21
+ --ssh-key <s> :: Provide an SSH key for authentication %(default: intelligent)
22
+ --groups <s> :: Provide a comma-separated list of groups
23
+ --comment <s> :: Provide a comment (usually a full name)
24
+ --phone <s> :: Provide a phone or pager number
25
+ --email <s> :: Provide an email address
26
+
27
+ generate node [<options>] <name>
28
+ Generate a new node resource in the current repo
29
+ --environment <s> :: Provide an environment name
30
+ --run-list <s> :: Provide a run list string
31
+
32
+ generate file [<options>] <name> [<source>]
33
+ Generate a new file in the current cookbook
34
+ --namespace <s> :: Provide a namespace (default: default)
35
+
36
+ generate template [<options>] <name> [<source>]
37
+ Generate a new template in the current cookbook
38
+ --namespace <s> :: Provide a namespace (default: default)
39
+
40
+ generate data.?bag [<options>] [<namepace>] <name>
41
+ Generate a new data bag in the current cookbook
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.2.13
data/bin/tony ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+ require 'trollop'
3
+ require 'bourdain'
4
+
5
+ argv = ARGV.empty? ? [ '--help' ] : ARGV
6
+
7
+ commands = Bourdain::Registry.specs('command')
8
+ command_position = commands.map { |c| argv.index c[:name].to_s }.compact.shift
9
+ command_position = argv.length if command_position.nil?
10
+ argv_before_command = argv.slice(0, command_position)
11
+
12
+ Trollop::options(argv_before_command) do
13
+ version Bourdain::VERSION
14
+ banner Bourdain::ART + "\n\n" + <<-EOS.gsub(/^ /, '')
15
+ #{Bourdain::SUMMARY}
16
+
17
+ Usage: tony [<options>] <command>
18
+
19
+ Commands:
20
+ #{Bourdain::Registry.details('command') * "\n "}
21
+
22
+ Options:
23
+ EOS
24
+ end
25
+
26
+ command = argv.shift
27
+ Trollop::die 'No <command> provided' if command.nil?
28
+ Trollop::die 'Invalid <command> provided' if command_position.nil?
29
+
30
+ bin_dir = File.dirname(File.expand_path(__FILE__))
31
+ executable = File.join bin_dir, "tony-#{command}"
32
+ Trollop::die 'Invalid <command> provided' unless File.exists? executable
33
+
34
+ log = Bourdain::Logger.new
35
+
36
+ exec(executable, *argv) if File.exists? Bourdain::CONFIG
37
+
38
+ log.info <<-EOLOG.gsub(/^ /, '').strip
39
+ Hey, looks like you've never run Bourdain before.
40
+
41
+ Before I we can get started, you'll need to create a config file for Bourdain
42
+ at #{Bourdain::CONFIG}. It should look something like this:
43
+ EOLOG
44
+ puts
45
+ log.warn <<-EOLOG.gsub(/^ /, '').strip
46
+ {
47
+ "gitlab": {
48
+ "token": "your_gitlab_token"
49
+ }
50
+ }
51
+ EOLOG
52
+ puts
53
+ log.info 'You can find your GitLab token here: http://git.bluejeansnet.com/profile/account'
54
+ exit 1
data/bin/tony-bump ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'bourdain'
3
+ exit Bourdain::Commands::BumpCommand.new(ARGV).status
data/bin/tony-check ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'bourdain'
3
+ exit Bourdain::Commands::CheckCommand.new(ARGV).status
data/bin/tony-generate ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'bourdain'
3
+ exit Bourdain::Commands::GenerateCommand.new(ARGV).status
data/bourdain.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path(File.join('..', 'lib'), __FILE__)
3
+ require 'bourdain/metadata'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'bourdain'
7
+ s.version = Bourdain::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.author = Bourdain::AUTHOR
10
+ s.email = Bourdain::EMAIL
11
+ s.homepage = Bourdain::HOMEPAGE
12
+ s.summary = Bourdain::SUMMARY
13
+ s.description = Bourdain::SUMMARY + '.'
14
+
15
+ s.add_runtime_dependency 'pmap'
16
+ s.add_runtime_dependency 'gitlab'
17
+ s.add_runtime_dependency 'trollop'
18
+ s.add_runtime_dependency 'colorize'
19
+ s.add_runtime_dependency 'activesupport'
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- test/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File::basename(f) }
24
+ s.require_paths = %w[ lib ]
25
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env sh
2
+ rm -f *.gem
3
+ gem build *.gemspec
4
+ gem install *.gem
@@ -0,0 +1,12 @@
1
+ require 'json'
2
+
3
+ module Bourdain
4
+ module Helpers
5
+ class Config
6
+ attr_reader :items
7
+ def initialize path
8
+ @items = JSON::parse File.read(path), symbolize_names: true rescue {}
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ module Bourdain
2
+ module Helpers
3
+ class Locals
4
+ def initialize locals
5
+ locals.each do |name, value|
6
+ instance_variable_set "@#{name}", value
7
+ metaclass = class << self ; self ; end
8
+ metaclass.send(:define_method, name) do
9
+ instance_variable_get("@#{name}")
10
+ end
11
+ end
12
+ end
13
+
14
+ def bind ; binding end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ require 'logger'
2
+ require 'time'
3
+
4
+ require 'colorize'
5
+
6
+
7
+ module Bourdain
8
+ module Logger
9
+ SEVERITY_COLORS = {
10
+ 'DEBUG' => [ :blue, :default ],
11
+ 'INFO' => [ :green, :default ],
12
+ 'WARN' => [ :yellow, :default ],
13
+ 'ERROR' => [ :red, :default ],
14
+ 'FATAL' => [ :red, :black ]
15
+ }
16
+
17
+ def self.new level=::Logger::INFO, file=STDOUT
18
+ logger = ::Logger.new file
19
+ logger.level = level
20
+ logger.formatter = proc do |severity, datetime, _, msg|
21
+ if level == 1
22
+ msg.to_s.colorize(
23
+ color: SEVERITY_COLORS[severity.to_s][0],
24
+ background: SEVERITY_COLORS[severity.to_s][1]
25
+ ) + "\n"
26
+ else
27
+ "%s [%s] %s -- %s\n".colorize(
28
+ color: SEVERITY_COLORS[severity.to_s][0],
29
+ background: SEVERITY_COLORS[severity.to_s][1]
30
+ ) % [
31
+ severity,
32
+ datetime.iso8601(6),
33
+ File::basename(caller[4]),
34
+ msg
35
+ ]
36
+ end
37
+ end
38
+ return logger
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,76 @@
1
+ require 'json'
2
+
3
+ module Bourdain
4
+ module Helpers
5
+ class UsageParser
6
+ def self.parse spec
7
+ lines = spec.lines.map(&:strip)
8
+ desc = lines.shift
9
+ usage = lines.shift
10
+ name = usage.split(' ').first
11
+ args = lines.select { |l| l =~ /^--/ }
12
+ resources = lines.select { |l| l =~ /^</ }
13
+ resources = resources.map { |r| r.gsub(/\W/, '') }
14
+ {
15
+ name: name,
16
+ usage: usage,
17
+ desc: desc,
18
+ resources: resources,
19
+ opts: args.map { |a| parse_arg a }
20
+ }
21
+ end
22
+
23
+ private
24
+ def self.parse_arg arg_spec
25
+ matches = arg_spec.match(/^--(.*?)( \(.*?\))?( <.*?>)? :: (.*?)$/)
26
+
27
+ long = matches[1]
28
+ short = matches[2]
29
+ type = matches[3]
30
+ desc = matches[4]
31
+
32
+ short.gsub!(/[^a-z]/, '') unless short.nil?
33
+
34
+ type.gsub!(/[^a-z]/, '') unless type.nil?
35
+
36
+ type = case type
37
+ when 'i' ; :integer
38
+ when 'd' ; :double
39
+ when 'f' ; :float
40
+ when 's' ; :string
41
+ when 'o' ; :io
42
+ when nil ; nil
43
+ else raise "unkown type '#{type}'"
44
+ end
45
+
46
+ matches = desc.match(/(.*?)( \((default|required): .*?\))?$/)
47
+ unless matches.nil?
48
+ desc = matches[1]
49
+ opts = matches[2]
50
+ end
51
+
52
+ unless opts.nil?
53
+ if matches = opts.match(/default: (.*?)(,|\))/)
54
+ default = matches[1]
55
+ default = !!(default =~ /true/) unless default.nil?
56
+ end
57
+
58
+ if matches = opts.match(/required: (true|false)(,|\))/)
59
+ required = matches[1]
60
+ required = !!(required =~ /true/) unless required.nil?
61
+ end
62
+ end
63
+
64
+ long = long.gsub('-', '_').to_sym
65
+
66
+ token = { long: long, desc: desc, opts: {} }
67
+ token[:opts][:type] = type unless type.nil?
68
+ token[:opts][:short] = short unless short.nil?
69
+ token[:opts][:default] = default unless default.nil?
70
+ token[:opts][:required] = required unless required.nil?
71
+
72
+ return token
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,53 @@
1
+ require 'set'
2
+
3
+
4
+ module Bourdain
5
+ module Helpers
6
+ class Registry
7
+ attr_reader :name, :config
8
+
9
+ def initialize
10
+ @config = Hash.new { |default, key| default[key] = Set.new }
11
+ end
12
+
13
+ def register namespace, klass
14
+ @config[namespace].add(klass)
15
+ end
16
+
17
+ def namespace namespace
18
+ @config[namespace].to_a
19
+ end
20
+
21
+ def map namespace, &block
22
+ @config[namespace].map(&block)
23
+ end
24
+
25
+ def specs namespace
26
+ @config[namespace].map do |klass|
27
+ Bourdain::Helpers::UsageParser.parse klass.raw_usage
28
+ end
29
+ end
30
+
31
+ def klass namespace, name
32
+ @config[namespace].select do |klass|
33
+ Bourdain::Helpers::UsageParser.parse(klass.raw_usage)[:name] == name
34
+ end.shift
35
+ end
36
+
37
+ def spec namespace, name
38
+ specs(namespace).select do |spec|
39
+ spec[:name] == name
40
+ end.shift
41
+ end
42
+
43
+ def details namespace
44
+ specs = specs(namespace)
45
+ max_name_width = specs.sort_by { |s| s[:name].to_s.length }.last[:name].length
46
+ max_name_width += 2
47
+ specs.map do |spec|
48
+ "#{spec[:name].rjust(max_name_width)}: #{spec[:desc]}"
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,32 @@
1
+ require 'pathname'
2
+
3
+ CWD = Dir.pwd
4
+ PATH = File.expand_path(__FILE__)
5
+ DIR = File.dirname(PATH)
6
+ ROOT = File.expand_path(File.join(DIR, '..', '..'))
7
+ BASE = Pathname.new(ROOT).relative_path_from(Pathname.new(CWD)).to_s
8
+
9
+ def gem_path *dir
10
+ Pathname.new(File.join(BASE, *dir)).cleanpath.to_s
11
+ end
12
+
13
+ def apply_template file, opts
14
+ template_name, locals = opts[:template], opts[:locals]
15
+ locals = Bourdain::Helpers::Locals.new(locals).bind unless locals.nil?
16
+ template_path = gem_path('templates', *template_name)
17
+ template = ERB.new File.read(template_path)
18
+ contents = template.result(locals)
19
+ File.open(file, 'w') { |f| f.puts contents }
20
+ end
21
+
22
+ require_relative 'helpers/config'
23
+ require_relative 'helpers/locals'
24
+ require_relative 'helpers/logger'
25
+ require_relative 'helpers/parser'
26
+ require_relative 'helpers/registry'
27
+
28
+ module Bourdain
29
+ Config = Bourdain::Helpers::Config.new(CONFIG)
30
+ Registry = Bourdain::Helpers::Registry.new
31
+ GITLAB_HOST = 'git.bluejeansnet.com'
32
+ end
@@ -0,0 +1,19 @@
1
+ module Bourdain
2
+ CONFIG = File.join(ENV['HOME'], '.bourdain.json')
3
+ VERSION = File.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION')).strip
4
+ SUMMARY = 'Tools for badass chefs'
5
+ AUTHOR = 'Sean Clemmer'
6
+ EMAIL = 'sclemmer@bluejeans.com'
7
+ HOMEPAGE = 'http://wiki.bluejeansnet.com/operations/bourdain'
8
+ ART = <<-'EOART' % VERSION
9
+
10
+ __ __
11
+ /\ \ /\ \ __
12
+ \ \ \____ ___ __ __ _ __ \_\ \ __ /\_\ ___
13
+ \ \ '__`\ / __`\/\ \/\ \/\`'__\/'_` \ /'__`\ \/\ \ /' _ `\
14
+ \ \ \L\ \/\ \L\ \ \ \_\ \ \ \//\ \L\ \/\ \L\.\_\ \ \/\ \/\ \
15
+ \ \_,__/\ \____/\ \____/\ \_\\ \___,_\ \__/.\_\\ \_\ \_\ \_\
16
+ \/___/ \/___/ \/___/ \/_/ \/__,_ /\/__/\/_/ \/_/\/_/\/_/
17
+ v%s
18
+ EOART
19
+ end
@@ -0,0 +1,71 @@
1
+ module Bourdain
2
+ module Checks
3
+
4
+ class BourdainCheck < Check
5
+ usage :check, <<-END
6
+ Check the local copy of Bourdain
7
+ bourdain
8
+ END
9
+
10
+
11
+ def initialize cookbook_config
12
+ super []
13
+ return unless require_chef!
14
+ check_bourdain!
15
+ end
16
+
17
+
18
+
19
+ private
20
+ def check_bourdain!
21
+ # Ensure we have an up-to-date copy of Bourdain
22
+ bourdain = File.join('utils', 'bourdain')
23
+
24
+ ahead_of_remote = false
25
+ unless Dir.exists? bourdain
26
+ log.warn "Hm, I don't see a copy of Bourdain. I'll fix that for you..."
27
+ %x| git clone git@git.bluejeansnet.com:chef/bourdain.git #{bourdain} |
28
+ log.info "Your copy of Bourdain is now up-to-date."
29
+
30
+ else
31
+ if youre_dirty? bourdain
32
+ log.warn "Your copy of Bourdain is dirty."
33
+ elsif youre_ahead? bourdain
34
+ log.warn "Your copy of Bourdain is ahead of the remote."
35
+ ahead_of_remote = true
36
+ elsif youre_behind? bourdain
37
+ log.warn "Hey, looks like your copy of Bourdain is out-of-date. I'll fix that for you..."
38
+ Dir.chdir(bourdain) { %x| git pull | }
39
+ log.info "Your copy of Bourdain is now up-to-date."
40
+ else
41
+ log.info "Your copy of Bourdain looks up-to-date."
42
+ end
43
+ end
44
+
45
+ matches = File.read('Gemfile.lock').match(/bourdain \((.*?)\)$/)
46
+
47
+ if matches.nil?
48
+ log.warn "Couldn't find Kitchen hooks in your Gemfile lock. Something is amiss..."
49
+ error!
50
+
51
+ else
52
+ repo_version = matches[1].strip
53
+ local_version = File.read(File.join(bourdain, 'VERSION')).strip
54
+
55
+ if repo_version == local_version
56
+ log.info "Your Chef repo is bundled with the latest Bourdain."
57
+ elsif ahead_of_remote
58
+ # Don't worry about it, we've already warned them
59
+ elsif local_version < repo_version
60
+ log.error 'Your Chef repo is bundled with an older Bourdain. Try "bundle update".'
61
+ error!
62
+ end
63
+ end
64
+
65
+ # Remove pre-commit hook if installed
66
+ pre_commit_hook = File.join(*bourdain, '.git', 'hooks', 'pre-commit')
67
+ FileUtils.rm_rf pre_commit_hook
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,35 @@
1
+ module Bourdain
2
+ module Checks
3
+
4
+ class ChefCheck < Check
5
+ usage :check, <<-END
6
+ Check the underlying Kitchen
7
+ chef
8
+ END
9
+
10
+
11
+ def initialize cookbook_config
12
+ super []
13
+ return unless require_chef!
14
+ check_chef_repo!
15
+ end
16
+
17
+
18
+
19
+ private
20
+ def check_chef_repo!
21
+ # Check if we have an up-to-date copy of the Kitchen
22
+ if youre_dirty? '.'
23
+ log.warn "Your Kitchen is dirty."
24
+ elsif youre_ahead? '.'
25
+ log.warn "Your Kitchen is ahead of the remote."
26
+ elsif youre_behind? '.'
27
+ log.error "Looks like your Kitchen is behind the remote."
28
+ error!
29
+ else
30
+ log.info "Your Kitchen looks up-to-date."
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,97 @@
1
+ module Bourdain
2
+ module Checks
3
+
4
+ class CookbooksCheck < Check
5
+ usage :check, <<-END
6
+ Check all the underlying cookbooks
7
+ cookbooks
8
+ END
9
+
10
+
11
+ def initialize cookbook_config
12
+ super []
13
+ return unless require_chef!
14
+ check_gitlab_cookbooks! cookbook_config
15
+ check_local_cookbooks! cookbook_config
16
+ end
17
+
18
+
19
+
20
+ private
21
+ def check_cookbook_freshness cookbook
22
+ notifications = []
23
+ path = cookbook[:path]
24
+
25
+ if Dir.exists? path
26
+ if youre_dirty? path
27
+ notifications.push [ path, :warn, "Your cookbook %{path} is dirty." % cookbook ]
28
+ elsif youre_ahead? path
29
+ notifications.push [ path, :warn, "Your cookbook %{path} is ahead of %{repo}." % cookbook ]
30
+ elsif youre_behind? path
31
+ notifications.push [ path, :error, "Hey, looks like your cookbook %{path} is behind %{repo}. Try pulling." % cookbook ]
32
+ error!
33
+ else
34
+ notifications.push [ path, :info, "Your cookbook %{path} looks up-to-date." % cookbook ]
35
+ end
36
+ end
37
+
38
+ notifications
39
+ end
40
+
41
+ def check_cookbook_exists cookbook
42
+ unless Dir.exists? cookbook[:path]
43
+ log.warn "Populating cookbook %{path} with %{repo}" % cookbook
44
+ %x| git clone git@#{GITLAB_HOST}:#{cookbook[:repo]} #{cookbook[:path]} |
45
+ log.info "Your cookbook %{path} is now up-to-date." % cookbook
46
+ end
47
+ end
48
+
49
+ def log_notifications notifications
50
+ ns = notifications.map { |n| n.first rescue nil }.compact.select { |n| !n.empty? }
51
+ ns.sort_by(&:first).each do |n|
52
+ next if n.empty?
53
+ _, severity, message = n
54
+ log.send severity, message
55
+ end
56
+ end
57
+
58
+ def ensure_pre_commit_installed cookbook
59
+ pre_commit_hook = File.join(cookbook[:path], '.git', 'hooks', 'pre-commit')
60
+ apply_template pre_commit_hook, template: %w[ cookbook pre-commit ]
61
+ FileUtils.chmod 0755, pre_commit_hook
62
+ end
63
+
64
+
65
+
66
+ def check_gitlab_cookbooks! cookbook_configs
67
+ notifications = cookbook_configs.pmap do |cookbook|
68
+ check_cookbook_freshness cookbook
69
+ end
70
+ unless notifications.first.empty?
71
+ log_notifications notifications
72
+ end
73
+
74
+ cookbook_configs.sort_by { |cc| cc[:path] }.each do |cookbook|
75
+ check_cookbook_exists cookbook
76
+ end
77
+
78
+ cookbook_configs.each do |cookbook|
79
+ ensure_pre_commit_installed cookbook
80
+ end
81
+ end
82
+
83
+
84
+ def check_local_cookbooks! cookbook_configs
85
+ known_cookbook_paths = cookbook_configs.map { |cc| cc[:path].sub('forks/bjn_', 'forks/') }
86
+ local_cookbook_paths = Dir[File.join('{apps,bases,forks,libs,realms}', '*')]
87
+ unknown_cookbook_paths = local_cookbook_paths - known_cookbook_paths
88
+ unless unknown_cookbook_paths.empty?
89
+ log.warn "Head's up, I see some cookbooks aren't on GitLab:"
90
+ unknown_cookbook_paths.each do |cookbook_path|
91
+ log.warn " #{cookbook_path}"
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end