modulesync 0.6.1 → 0.7.2

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.
@@ -1,14 +1,25 @@
1
1
  require 'fileutils'
2
+ require 'pathname'
2
3
  require 'modulesync/cli'
3
4
  require 'modulesync/constants'
4
5
  require 'modulesync/git'
5
6
  require 'modulesync/hook'
6
7
  require 'modulesync/renderer'
8
+ require 'modulesync/settings'
7
9
  require 'modulesync/util'
8
10
 
9
11
  module ModuleSync
10
12
  include Constants
11
13
 
14
+ def self.config_defaults
15
+ {
16
+ :project_root => 'modules/',
17
+ :managed_modules_conf => 'managed_modules.yml',
18
+ :configs => '.',
19
+ :tag_pattern => '%s'
20
+ }
21
+ end
22
+
12
23
  def self.local_file(config_path, file)
13
24
  "#{config_path}/#{MODULE_FILES_DIR}/#{file}"
14
25
  end
@@ -18,8 +29,8 @@ module ModuleSync
18
29
  end
19
30
 
20
31
  def self.local_files(path)
21
- if File.exists?(path)
22
- local_files = Find.find(path).collect { |file| file if !File.directory?(file) }.compact
32
+ if File.exist?(path)
33
+ local_files = Find.find(path).collect { |file| file unless File.directory?(file) }.compact
23
34
  else
24
35
  puts "#{path} does not exist. Check that you are working in your module configs directory or that you have passed in the correct directory with -c."
25
36
  exit
@@ -30,65 +41,100 @@ module ModuleSync
30
41
  local_files.map { |file| file.sub(/#{path}/, '') }
31
42
  end
32
43
 
33
- def self.managed_modules(path, filter)
44
+ def self.managed_modules(path, filter, negative_filter)
34
45
  managed_modules = Util.parse_config(path)
35
46
  if managed_modules.empty?
36
47
  puts "No modules found at #{path}. Check that you specified the right configs directory containing managed_modules.yml."
37
48
  exit
38
49
  end
39
50
  managed_modules.select! { |m| m =~ Regexp.new(filter) } unless filter.nil?
51
+ managed_modules.select! { |m| m !~ Regexp.new(negative_filter) } unless negative_filter.nil?
40
52
  managed_modules
41
53
  end
42
54
 
43
- def self.run(args)
44
- cli = CLI.new
45
- cli.parse_opts(args)
46
- options = cli.options
47
- if options[:command] == 'update'
48
- defaults = Util.parse_config("#{options[:configs]}/#{CONF_FILE}")
49
-
50
- path = "#{options[:configs]}/#{MODULE_FILES_DIR}"
51
- local_files = self.local_files(path)
52
- module_files = self.module_files(local_files, path)
53
-
54
- managed_modules = self.managed_modules("#{options[:configs]}/managed_modules.yml", options[:filter])
55
-
56
- # managed_modules is either an array or a hash
57
- managed_modules.each do |puppet_module, opts|
58
- puts "Syncing #{puppet_module}"
59
- unless options[:offline]
60
- git_base = "#{options[:git_base]}#{options[:namespace]}"
61
- Git.pull(git_base, puppet_module, options[:branch], options[:project_root], opts || {})
62
- end
63
- module_configs = Util.parse_config("#{options[:project_root]}/#{puppet_module}/#{MODULE_CONF_FILE}")
64
- global_defaults = defaults[GLOBAL_DEFAULTS_KEY] || {}
65
- module_defaults = module_configs[GLOBAL_DEFAULTS_KEY] || {}
66
- files_to_manage = (module_files | defaults.keys | module_configs.keys) - [GLOBAL_DEFAULTS_KEY]
67
- files_to_delete = []
68
- files_to_manage.each do |file|
69
- file_configs = global_defaults.merge(defaults[file] || {}).merge(module_defaults).merge(module_configs[file] || {})
70
- file_configs[:puppet_module] = puppet_module
71
- if file_configs['unmanaged']
72
- puts "Not managing #{file} in #{puppet_module}"
73
- files_to_delete << file
74
- elsif file_configs['delete']
75
- Renderer.remove(module_file(options['project_root'], puppet_module, file))
76
- else
77
- erb = Renderer.build(local_file(options[:configs], file))
78
- template = Renderer.render(erb, file_configs)
79
- Renderer.sync(template, "#{options[:project_root]}/#{puppet_module}/#{file}")
80
- end
81
- end
82
- files_to_manage -= files_to_delete
83
- if options[:noop]
84
- Git.update_noop(puppet_module, options)
85
- elsif not options[:offline]
86
- Git.update(puppet_module, files_to_manage, options)
87
- end
55
+ def self.module_name(module_name, default_namespace)
56
+ return [default_namespace, module_name] unless module_name.include?('/')
57
+ ns, mod = module_name.split('/')
58
+ end
59
+
60
+ def self.hook(options)
61
+ hook = Hook.new(HOOK_FILE, options)
62
+
63
+ case options[:hook]
64
+ when 'activate'
65
+ hook.activate
66
+ when 'deactivate'
67
+ hook.deactivate
68
+ end
69
+ end
70
+
71
+ def self.manage_file(filename, settings, options)
72
+ module_name = settings.additional_settings[:puppet_module]
73
+ configs = settings.build_file_configs(filename)
74
+ if configs['delete']
75
+ Renderer.remove(module_file(options[:project_root], module_name, filename))
76
+ else
77
+ templatename = local_file(options[:configs], filename)
78
+ begin
79
+ erb = Renderer.build(templatename)
80
+ template = Renderer.render(erb, configs)
81
+ Renderer.sync(template, module_file(options[:project_root], module_name, filename))
82
+ rescue
83
+ STDERR.puts "Error while rendering #{filename}"
84
+ raise
88
85
  end
89
- elsif options[:command] == 'hook'
90
- Hook.hook(args[1], options)
91
86
  end
92
87
  end
93
88
 
89
+ def self.manage_module(puppet_module, module_files, module_options, defaults, options)
90
+ puts "Syncing #{puppet_module}"
91
+ namespace, module_name = self.module_name(puppet_module, options[:namespace])
92
+ unless options[:offline]
93
+ git_base = options[:git_base]
94
+ git_uri = "#{git_base}#{namespace}"
95
+ Git.pull(git_uri, module_name, options[:branch], options[:project_root], module_options || {})
96
+ end
97
+ module_configs = Util.parse_config("#{options[:project_root]}/#{module_name}/#{MODULE_CONF_FILE}")
98
+ settings = Settings.new(defaults[GLOBAL_DEFAULTS_KEY] || {},
99
+ defaults,
100
+ module_configs[GLOBAL_DEFAULTS_KEY] || {},
101
+ module_configs,
102
+ :puppet_module => module_name,
103
+ :git_base => git_base,
104
+ :namespace => namespace)
105
+ settings.unmanaged_files(module_files).each do |filename|
106
+ puts "Not managing #{filename} in #{module_name}"
107
+ end
108
+
109
+ files_to_manage = settings.managed_files(module_files)
110
+ files_to_manage.each { |filename| manage_file(filename, settings, options) }
111
+
112
+ if options[:noop]
113
+ Git.update_noop(module_name, options)
114
+ elsif !options[:offline]
115
+ Git.update(module_name, files_to_manage, options)
116
+ end
117
+ end
118
+
119
+ def self.update(options)
120
+ options = config_defaults.merge(options)
121
+ defaults = Util.parse_config("#{options[:configs]}/#{CONF_FILE}")
122
+
123
+ path = "#{options[:configs]}/#{MODULE_FILES_DIR}"
124
+ local_files = self.local_files(path)
125
+ module_files = self.module_files(local_files, path)
126
+
127
+ managed_modules = self.managed_modules("#{options[:configs]}/managed_modules.yml", options[:filter], options[:negative_filter])
128
+
129
+ # managed_modules is either an array or a hash
130
+ managed_modules.each do |puppet_module, module_options|
131
+ begin
132
+ manage_module(puppet_module, module_files, module_options, defaults, options)
133
+ rescue
134
+ STDERR.puts "Error while updating #{puppet_module}"
135
+ raise unless options[:skip_broken]
136
+ puts "Skipping #{puppet_module} as update process failed"
137
+ end
138
+ end
139
+ end
94
140
  end
@@ -1,124 +1,64 @@
1
- require 'optparse'
1
+ require 'thor'
2
+ require 'modulesync'
2
3
  require 'modulesync/constants'
3
4
  require 'modulesync/util'
4
5
 
5
6
  module ModuleSync
6
7
  class CLI
7
- include Constants
8
+ class Hook < Thor
9
+ class_option :project_root, :aliases => '-c', :desc => 'Path used by git to clone modules into. Defaults to "modules"', :default => 'modules'
10
+ class_option :hook_args, :aliases => '-a', :desc => 'Arguments to pass to msync in the git hook'
8
11
 
9
- def defaults
10
- {
11
- :namespace => 'puppetlabs',
12
- :branch => 'master',
13
- :git_base => 'git@github.com:',
14
- :managed_modules_conf => 'managed_modules.yml',
15
- :configs => '.',
16
- :tag_pattern => '%s',
17
- :project_root => './modules',
18
- }
19
- end
12
+ desc 'activate', 'Activate the git hook.'
13
+ def activate
14
+ config = { :command => 'hook' }.merge(options)
15
+ config[:hook] = 'activate'
16
+ ModuleSync.hook(config)
17
+ end
20
18
 
21
- def commands_available
22
- [
23
- 'update',
24
- 'hook',
25
- ]
19
+ desc 'deactivate', 'Deactivate the git hook.'
20
+ def deactivate
21
+ config = { :command => 'hook' }.merge(options)
22
+ config[:hook] = 'deactivate'
23
+ ModuleSync.hook(config)
24
+ end
26
25
  end
27
26
 
28
- def fail(message)
29
- puts @options[:help]
30
- puts message
31
- exit
32
- end
27
+ class Base < Thor
28
+ include Constants
33
29
 
34
- def parse_opts(args)
35
- @options = defaults
36
- @options.merge!(Hash.transform_keys_to_symbols(Util.parse_config(MODULESYNC_CONF_FILE)))
37
- @options[:command] = args[0] if commands_available.include?(args[0])
38
- opt_parser = OptionParser.new do |opts|
39
- opts.banner = "Usage: msync update [-m <commit message>] [-c <directory> ] [--offline] [--noop] [--bump] [--changelog] [--tag] [--tag-pattern <tag_pattern>] [-p <project_root> [-n <namespace>] [-b <branch>] [-r <branch>] [-f <filter>] | hook activate|deactivate [-c <directory> ] [-n <namespace>] [-b <branch>]"
40
- opts.on('-m', '--message <msg>',
41
- 'Commit message to apply to updated modules') do |msg|
42
- @options[:message] = msg
43
- end
44
- opts.on('-n', '--namespace <url>',
45
- 'Remote github namespace (user or organization) to clone from and push to. Defaults to puppetlabs') do |namespace|
46
- @options[:namespace] = namespace
47
- end
48
- opts.on('-c', '--configs <directory>',
49
- 'The local directory or remote repository to define the list of managed modules, the file templates, and the default values for template variables.') do |configs|
50
- @options[:configs] = configs
51
- end
52
- opts.on('-b', '--branch <branch>',
53
- 'Branch name to make the changes in. Defaults to "master"') do |branch|
54
- @options[:branch] = branch
55
- end
56
- opts.on('-p', '--project-root <path>',
57
- 'Path used by git to clone modules into. Defaults to "modules"') do |project_root|
58
- @options[:project_root] = project_root
59
- end
60
- opts.on('-r', '--remote-branch <branch>',
61
- 'Remote branch name to push the changes to. Defaults to the branch name') do |branch|
62
- @options[:remote_branch] = branch
63
- end
64
- opts.on('-f', '--filter <filter>',
65
- 'A regular expression to filter repositories to update.') do |filter|
66
- @options[:filter] = filter
67
- end
68
- opts.on('--amend',
69
- 'Amend previous commit') do |msg|
70
- @options[:amend] = true
71
- end
72
- opts.on('--force',
73
- 'Force push amended commit') do |msg|
74
- @options[:force] = true
75
- end
76
- opts.on('--noop',
77
- 'No-op mode') do |msg|
78
- @options[:noop] = true
79
- end
80
- opts.on('--offline',
81
- 'Do not run git command. Helpful if you have existing repositories locally.') do |msg|
82
- @options[:offline] = true
83
- end
84
- opts.on('--bump',
85
- 'Bump module version to the next minor') do |msg|
86
- @options[:bump] = true
87
- end
88
- opts.on('--changelog',
89
- 'Update CHANGELOG.md if version was bumped') do |msg|
90
- @options[:changelog] = true
91
- end
92
- opts.on('--tag',
93
- 'Git tag with the current module version') do |msg|
94
- @options[:tag] = true
95
- end
96
- opts.on('--tag-pattern',
97
- 'The pattern to use when tagging releases.') do |pattern|
98
- @options[:tag_pattern] = pattern
99
- end
100
- @options[:help] = opts.help
101
- end.parse!
30
+ class_option :project_root, :aliases => '-c', :desc => 'Path used by git to clone modules into. Defaults to "modules"', :default => 'modules'
31
+ class_option :git_base, :desc => 'Specify the base part of a git URL to pull from', :default => 'git@github.com:'
32
+ class_option :namespace, :aliases => '-n', :desc => 'Remote github namespace (user or organization) to clone from and push to. Defaults to puppetlabs', :default => 'puppetlabs'
33
+ class_option :filter, :aliases => '-f', :desc => 'A regular expression to select repositories to update.'
34
+ class_option :negative_filter, :aliases => '-x', :desc => 'A regular expression to skip repositories.'
35
+ class_option :branch, :aliases => '-b', :desc => 'Branch name to make the changes in. Defaults to master.', :default => 'master'
102
36
 
103
- @options.fetch(:message) do
104
- if @options[:command] == 'update' && ! @options[:noop] && ! @options[:amend] && ! @options[:offline]
105
- fail("A commit message is required unless using noop or offline.")
106
- end
107
- end
37
+ desc 'update', 'Update the modules in managed_modules.yml'
38
+ option :message, :aliases => '-m', :desc => 'Commit message to apply to updated modules. Required unless running in noop mode.'
39
+ option :configs, :aliases => '-c', :desc => 'The local directory or remote repository to define the list of managed modules, the file templates, and the default values for template variables.'
40
+ option :remote_branch, :aliases => '-r', :desc => 'Remote branch name to push the changes to. Defaults to the branch name.'
41
+ option :skip_broken, :type => :boolean, :aliases => '-s', :desc => 'Process remaining modules if an error is found', :default => false
42
+ option :amend, :type => :boolean, :desc => 'Amend previous commit', :default => false
43
+ option :force, :type => :boolean, :desc => 'Force push amended commit', :default => false
44
+ option :noop, :type => :boolean, :desc => 'No-op mode', :default => false
45
+ option :offline, :type => :boolean, :desc => 'Do not run any Git commands. Allows the user to manage Git outside of ModuleSync.', :default => false
46
+ option :bump, :type => :boolean, :desc => 'Bump module version to the next minor', :default => false
47
+ option :changelog, :type => :boolean, :desc => 'Update CHANGELOG.md if version was bumped', :default => false
48
+ option :tag, :type => :boolean, :desc => 'Git tag with the current module version', :default => false
49
+ option :tag_pattern, :desc => 'The pattern to use when tagging releases.'
108
50
 
109
- @options.fetch(:command) do
110
- fail("A command is required.")
51
+ def update
52
+ config = { :command => 'update' }.merge(options)
53
+ config.merge!(Util.parse_config(MODULESYNC_CONF_FILE))
54
+ config = Util.symbolize_keys(config)
55
+ raise Thor::Error, 'No value provided for required option "--message"' unless config[:noop] || config[:message] || config[:offline]
56
+ config[:git_opts] = { 'amend' => config[:amend], 'force' => config[:force] }
57
+ ModuleSync.update(config)
111
58
  end
112
59
 
113
- if @options[:command] == 'hook' &&
114
- (! args.include?('activate') && ! args.include?('deactivate'))
115
- fail("You must activate or deactivate the hook.")
116
- end
117
-
118
- end
119
-
120
- def options
121
- @options
60
+ desc 'hook', 'Activate or deactivate a git hook.'
61
+ subcommand 'hook', ModuleSync::CLI::Hook
122
62
  end
123
63
  end
124
64
  end
@@ -1,10 +1,10 @@
1
1
  module ModuleSync
2
2
  module Constants
3
- MODULE_FILES_DIR = 'moduleroot/'
4
- CONF_FILE = 'config_defaults.yml'
5
- MODULE_CONF_FILE = '.sync.yml'
6
- MODULESYNC_CONF_FILE = 'modulesync.yml'
7
- HOOK_FILE = '.git/hooks/pre-push'
3
+ MODULE_FILES_DIR = 'moduleroot/'.freeze
4
+ CONF_FILE = 'config_defaults.yml'.freeze
5
+ MODULE_CONF_FILE = '.sync.yml'.freeze
6
+ MODULESYNC_CONF_FILE = 'modulesync.yml'.freeze
7
+ HOOK_FILE = '.git/hooks/pre-push'.freeze
8
8
  GLOBAL_DEFAULTS_KEY = :global
9
9
  end
10
10
  end
@@ -6,38 +6,41 @@ module ModuleSync
6
6
  include Constants
7
7
 
8
8
  def self.remote_branch_exists?(repo, branch)
9
- repo.branches.remote.collect { |b| b.name }.include?(branch)
9
+ repo.branches.remote.collect(&:name).include?(branch)
10
10
  end
11
11
 
12
12
  def self.local_branch_exists?(repo, branch)
13
- repo.branches.local.collect { |b| b.name }.include?(branch)
13
+ repo.branches.local.collect(&:name).include?(branch)
14
+ end
15
+
16
+ def self.remote_branch_differ?(repo, local_branch, remote_branch)
17
+ !remote_branch_exists?(repo, remote_branch) ||
18
+ repo.diff("#{local_branch}..origin/#{remote_branch}").any?
14
19
  end
15
20
 
16
21
  def self.switch_branch(repo, branch)
17
- unless repo.branch.name == branch
18
- if local_branch_exists?(repo, branch)
19
- puts "Switching to branch #{branch}"
20
- repo.checkout(branch)
21
- elsif remote_branch_exists?(repo, branch)
22
- puts "Creating local branch #{branch} from origin/#{branch}"
23
- repo.checkout("origin/#{branch}")
24
- repo.branch(branch).checkout
25
- else
26
- repo.checkout('origin/master')
27
- puts "Creating new branch #{branch}"
28
- repo.branch(branch).checkout
29
- end
22
+ return if repo.branch.name == branch
23
+
24
+ if local_branch_exists?(repo, branch)
25
+ puts "Switching to branch #{branch}"
26
+ repo.checkout(branch)
27
+ elsif remote_branch_exists?(repo, branch)
28
+ puts "Creating local branch #{branch} from origin/#{branch}"
29
+ repo.checkout("origin/#{branch}")
30
+ repo.branch(branch).checkout
31
+ else
32
+ repo.checkout('origin/master')
33
+ puts "Creating new branch #{branch}"
34
+ repo.branch(branch).checkout
30
35
  end
31
36
  end
32
37
 
33
38
  def self.pull(git_base, name, branch, project_root, opts)
34
- if ! Dir.exists?(project_root)
35
- Dir.mkdir(project_root)
36
- end
39
+ Dir.mkdir(project_root) unless Dir.exist?(project_root)
37
40
 
38
41
  # Repo needs to be cloned in the cwd
39
- if ! Dir.exists?("#{project_root}/#{name}") || ! Dir.exists?("#{project_root}/#{name}/.git")
40
- puts "Cloning repository fresh"
42
+ if !Dir.exist?("#{project_root}/#{name}") || !Dir.exist?("#{project_root}/#{name}/.git")
43
+ puts 'Cloning repository fresh'
41
44
  remote = opts[:remote] || (git_base.start_with?('file://') ? "#{git_base}/#{name}" : "#{git_base}/#{name}.git")
42
45
  local = "#{project_root}/#{name}"
43
46
  puts "Cloning from #{remote}"
@@ -52,20 +55,18 @@ module ModuleSync
52
55
  repo.fetch
53
56
  repo.reset_hard
54
57
  switch_branch(repo, branch)
55
- if remote_branch_exists?(repo, branch)
56
- repo.pull('origin', branch)
57
- end
58
+ repo.pull('origin', branch) if remote_branch_exists?(repo, branch)
58
59
  end
59
60
  end
60
61
  end
61
62
 
62
63
  def self.update_changelog(repo, version, message, module_root)
63
64
  changelog = "#{module_root}/CHANGELOG.md"
64
- if File.exists?(changelog)
65
+ if File.exist?(changelog)
65
66
  puts "Updating #{changelog} for version #{version}"
66
67
  changes = File.readlines(changelog)
67
68
  File.open(changelog, 'w') do |f|
68
- date = Time.now.strftime("%Y-%m-%d")
69
+ date = Time.now.strftime('%Y-%m-%d')
69
70
  f.puts "## #{date} - Release #{version}\n\n"
70
71
  f.puts "#{message}\n\n"
71
72
  # Add old lines again
@@ -73,15 +74,15 @@ module ModuleSync
73
74
  end
74
75
  repo.add('CHANGELOG.md')
75
76
  else
76
- puts "No CHANGELOG.md file found, not updating."
77
+ puts 'No CHANGELOG.md file found, not updating.'
77
78
  end
78
79
  end
79
80
 
80
- def self.bump(repo, m, message, module_root, changelog=false)
81
+ def self.bump(repo, m, message, module_root, changelog = false)
81
82
  new = m.bump!
82
83
  puts "Bumped to version #{new}"
83
84
  repo.add('metadata.json')
84
- self.update_changelog(repo, new, message, module_root) if changelog
85
+ update_changelog(repo, new, message, module_root) if changelog
85
86
  repo.commit("Release version #{new}")
86
87
  repo.push
87
88
  new
@@ -98,43 +99,40 @@ module ModuleSync
98
99
  def self.update(name, files, options)
99
100
  module_root = "#{options[:project_root]}/#{name}"
100
101
  message = options[:message]
101
- if options[:remote_branch]
102
- branch = "#{options[:branch]}:#{options[:remote_branch]}"
103
- else
104
- branch = options[:branch]
105
- end
106
102
  repo = ::Git.open(module_root)
107
103
  repo.branch(options[:branch]).checkout
108
104
  files.each do |file|
109
105
  if repo.status.deleted.include?(file)
110
106
  repo.remove(file)
111
- else
107
+ elsif File.exist?("#{module_root}/#{file}")
112
108
  repo.add(file)
113
109
  end
114
110
  end
115
111
  begin
116
112
  opts_commit = {}
117
113
  opts_push = {}
118
- if options[:amend]
119
- opts_commit = {:amend => true}
120
- end
121
- if options[:force]
122
- opts_push = {:force => true}
123
- end
114
+ opts_commit = { :amend => true } if options[:amend]
115
+ opts_push = { :force => true } if options[:force]
124
116
  if options[:pre_commit_script]
125
117
  script = "#{File.dirname(File.dirname(__FILE__))}/../contrib/#{options[:pre_commit_script]}"
126
- %x[#{script} #{module_root}]
118
+ `#{script} #{module_root}`
127
119
  end
128
120
  repo.commit(message, opts_commit)
129
- repo.push('origin', branch, opts_push)
121
+ if options[:remote_branch]
122
+ if remote_branch_differ?(repo, options[:branch], options[:remote_branch])
123
+ repo.push('origin', "#{options[:branch]}:#{options[:remote_branch]}", opts_push)
124
+ end
125
+ else
126
+ repo.push('origin', options[:branch], opts_push)
127
+ end
130
128
  # Only bump/tag if pushing didn't fail (i.e. there were changes)
131
129
  m = Blacksmith::Modulefile.new("#{module_root}/metadata.json")
132
130
  if options[:bump]
133
- new = self.bump(repo, m, message, module_root, options[:changelog])
134
- self.tag(repo, new, options[:tag_pattern]) if options[:tag]
131
+ new = bump(repo, m, message, module_root, options[:changelog])
132
+ tag(repo, new, options[:tag_pattern]) if options[:tag]
135
133
  end
136
134
  rescue ::Git::GitExecuteError => git_error
137
- if git_error.message.include? "nothing to commit, working directory clean"
135
+ if git_error.message =~ /working (directory|tree) clean/
138
136
  puts "There were no files to update in #{name}. Not committing."
139
137
  else
140
138
  puts git_error
@@ -148,12 +146,8 @@ module ModuleSync
148
146
  # https://github.com/schacon/ruby-git/issues/130
149
147
  def self.untracked_unignored_files(repo)
150
148
  ignore_path = "#{repo.dir.path}/.gitignore"
151
- if File.exists?(ignore_path)
152
- ignored = File.open(ignore_path).read.split
153
- else
154
- ignored = []
155
- end
156
- repo.status.untracked.keep_if{|f,_| !ignored.any?{|i| File.fnmatch(i, f)}}
149
+ ignored = File.exist?(ignore_path) ? File.open(ignore_path).read.split : []
150
+ repo.status.untracked.keep_if { |f, _| !ignored.any? { |i| File.fnmatch(i, f) } }
157
151
  end
158
152
 
159
153
  def self.update_noop(name, options)
@@ -162,13 +156,13 @@ module ModuleSync
162
156
  repo = ::Git.open("#{options[:project_root]}/#{name}")
163
157
  repo.branch(options[:branch]).checkout
164
158
 
165
- puts "Files changed: "
159
+ puts 'Files changed:'
166
160
  repo.diff('HEAD', '--').each do |diff|
167
161
  puts diff.patch
168
162
  end
169
163
 
170
- puts "Files added: "
171
- untracked_unignored_files(repo).each do |file,_|
164
+ puts 'Files added:'
165
+ untracked_unignored_files(repo).each do |file, _|
172
166
  puts file
173
167
  end
174
168