omnibus 3.1.1 → 3.2.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +71 -0
  3. data/Gemfile +0 -7
  4. data/README.md +108 -36
  5. data/Rakefile +1 -5
  6. data/docs/omnibus-build-cache.md +5 -5
  7. data/features/commands/_deprecated.feature +21 -3
  8. data/features/step_definitions/generator_steps.rb +7 -7
  9. data/lib/omnibus.rb +232 -171
  10. data/lib/omnibus/build_version.rb +2 -2
  11. data/lib/omnibus/builder.rb +38 -19
  12. data/lib/omnibus/cleaner.rb +5 -5
  13. data/lib/omnibus/cleanroom.rb +141 -0
  14. data/lib/omnibus/cli.rb +6 -9
  15. data/lib/omnibus/cli/base.rb +2 -1
  16. data/lib/omnibus/cli/cache.rb +15 -21
  17. data/lib/omnibus/cli/deprecated.rb +40 -4
  18. data/lib/omnibus/cli/publish.rb +61 -0
  19. data/lib/omnibus/config.rb +350 -189
  20. data/lib/omnibus/digestable.rb +131 -0
  21. data/lib/omnibus/exceptions.rb +163 -83
  22. data/lib/omnibus/fetcher.rb +1 -1
  23. data/lib/omnibus/fetchers/net_fetcher.rb +19 -13
  24. data/lib/omnibus/fetchers/path_fetcher.rb +8 -1
  25. data/lib/omnibus/fetchers/s3_cache_fetcher.rb +16 -7
  26. data/lib/omnibus/generator.rb +2 -2
  27. data/lib/omnibus/generator_files/Gemfile.erb +4 -1
  28. data/lib/omnibus/generator_files/README.md.erb +10 -0
  29. data/lib/omnibus/generator_files/{omnibus.rb.example.erb → omnibus.rb.erb} +20 -11
  30. data/lib/omnibus/generator_files/package_scripts/makeselfinst.erb +1 -1
  31. data/lib/omnibus/generator_files/project.rb.erb +2 -2
  32. data/lib/omnibus/generator_files/windows_msi/localization-en-us.wxl.erb +3 -3
  33. data/lib/omnibus/git_cache.rb +192 -0
  34. data/lib/omnibus/health_check.rb +171 -116
  35. data/lib/omnibus/library.rb +4 -2
  36. data/lib/omnibus/logger.rb +60 -1
  37. data/lib/omnibus/null_argumentable.rb +51 -0
  38. data/lib/omnibus/ohai.rb +29 -8
  39. data/lib/omnibus/package.rb +240 -0
  40. data/lib/omnibus/packagers/base.rb +21 -42
  41. data/lib/omnibus/packagers/mac_dmg.rb +5 -5
  42. data/lib/omnibus/packagers/mac_pkg.rb +20 -19
  43. data/lib/omnibus/packagers/windows_msi.rb +7 -7
  44. data/lib/omnibus/project.rb +969 -486
  45. data/lib/omnibus/publisher.rb +76 -0
  46. data/lib/omnibus/publishers/artifactory_publisher.rb +168 -0
  47. data/lib/omnibus/publishers/null_publisher.rb +23 -0
  48. data/lib/omnibus/publishers/s3_publisher.rb +99 -0
  49. data/lib/omnibus/s3_cache.rb +150 -63
  50. data/lib/omnibus/software.rb +749 -321
  51. data/lib/omnibus/{sugar.rb → sugarable.rb} +11 -6
  52. data/lib/omnibus/version.rb +1 -1
  53. data/omnibus.gemspec +8 -8
  54. data/spec/data/complicated/config/projects/angrychef.rb +1 -1
  55. data/spec/data/complicated/config/projects/chef-windows.rb +1 -1
  56. data/spec/data/complicated/config/projects/chef.rb +1 -1
  57. data/spec/data/complicated/config/projects/chefdk-windows.rb +1 -1
  58. data/spec/data/complicated/config/projects/chefdk.rb +1 -1
  59. data/spec/data/complicated/config/software/cacerts.rb +1 -1
  60. data/spec/data/complicated/config/software/chef-client-msi.rb +1 -1
  61. data/spec/data/complicated/config/software/libgcc.rb +1 -1
  62. data/spec/data/complicated/config/software/libiconv.rb +0 -11
  63. data/spec/data/complicated/config/software/libpng.rb +2 -2
  64. data/spec/data/complicated/config/software/openssl.rb +1 -1
  65. data/spec/data/complicated/config/software/ruby.rb +1 -1
  66. data/spec/data/complicated/config/software/runit.rb +4 -4
  67. data/spec/data/projects/chefdk.rb +1 -1
  68. data/spec/data/projects/sample.rb +1 -1
  69. data/spec/data/software/erchef.rb +3 -1
  70. data/spec/functional/packagers/mac_spec.rb +25 -24
  71. data/spec/functional/packagers/windows_spec.rb +21 -20
  72. data/spec/spec_helper.rb +43 -4
  73. data/spec/unit/build_version_spec.rb +14 -16
  74. data/spec/unit/cleanroom_spec.rb +63 -0
  75. data/spec/unit/config_spec.rb +36 -30
  76. data/spec/unit/digestable_spec.rb +38 -0
  77. data/spec/unit/fetchers/net_fetcher_spec.rb +98 -87
  78. data/spec/unit/{install_path_cache_spec.rb → git_cache_spec.rb} +67 -56
  79. data/spec/unit/health_check_spec.rb +73 -0
  80. data/spec/unit/library_spec.rb +166 -159
  81. data/spec/unit/ohai_spec.rb +19 -0
  82. data/spec/unit/omnibus_spec.rb +43 -41
  83. data/spec/unit/package_spec.rb +178 -0
  84. data/spec/unit/packagers/base_spec.rb +17 -47
  85. data/spec/unit/packagers/mac_pkg_spec.rb +104 -126
  86. data/spec/unit/project_spec.rb +176 -25
  87. data/spec/unit/publisher_spec.rb +49 -0
  88. data/spec/unit/publishers/artifactory_publisher_spec.rb +80 -0
  89. data/spec/unit/publishers/s3_publisher_spec.rb +120 -0
  90. data/spec/unit/s3_cacher_spec.rb +84 -19
  91. data/spec/unit/software_spec.rb +397 -170
  92. data/spec/unit/sugarable_spec.rb +43 -0
  93. metadata +62 -50
  94. data/Guardfile +0 -10
  95. data/lib/omnibus/artifact.rb +0 -165
  96. data/lib/omnibus/cli/release.rb +0 -40
  97. data/lib/omnibus/generator_files/Vagrantfile.erb +0 -75
  98. data/lib/omnibus/install_path_cache.rb +0 -105
  99. data/lib/omnibus/overrides.rb +0 -88
  100. data/lib/omnibus/package_release.rb +0 -154
  101. data/lib/omnibus/software_s3_urls.rb +0 -50
  102. data/spec/unit/artifact_spec.rb +0 -91
  103. data/spec/unit/overrides_spec.rb +0 -102
  104. data/spec/unit/package_release_spec.rb +0 -180
  105. data/spec/unit/sugar_spec.rb +0 -17
@@ -95,7 +95,7 @@ module Omnibus
95
95
  # @return [Omnibus::Fetcher]
96
96
  def self.for(software)
97
97
  if software.source
98
- if software.source[:url] && Omnibus.config.use_s3_caching
98
+ if software.source[:url] && Config.use_s3_caching
99
99
  S3CacheFetcher.new(software)
100
100
  else
101
101
  without_caching_for(software)
@@ -27,16 +27,20 @@ module Omnibus
27
27
  attr_reader :project_file
28
28
  attr_reader :source
29
29
  attr_reader :source_uri
30
- attr_reader :source_dir
31
30
  attr_reader :project_dir
32
31
 
32
+ # Use 7-zip to extract 7z/zip for Windows
33
+ WIN_7Z_EXTENSIONS = %w(.7z .zip)
34
+
35
+ # tar probably has compression scheme linked in, otherwise for tarballs
36
+ TAR_EXTENSIONS = %w(.tar .tar.gz .tgz .bz2 .tar.xz .txz)
37
+
33
38
  def initialize(software)
34
39
  @name = software.name
35
40
  @checksum = software.checksum
36
41
  @source = software.source
37
42
  @project_file = software.project_file
38
43
  @source_uri = software.source_uri
39
- @source_dir = software.source_dir
40
44
  @project_dir = software.project_dir
41
45
  super
42
46
  end
@@ -179,7 +183,7 @@ module Omnibus
179
183
 
180
184
  def extract
181
185
  log.info(log_key) do
182
- "Extracting the source in '#{project_file}' to '#{source_dir}'"
186
+ "Extracting the source in '#{project_file}' to '#{Config.source_dir}'"
183
187
  end
184
188
 
185
189
  cmd = extract_cmd
@@ -197,16 +201,18 @@ module Omnibus
197
201
  end
198
202
 
199
203
  def extract_cmd
200
- if project_file.end_with?('.gz') || project_file.end_with?('.tgz')
201
- "gzip -dc #{project_file} | ( cd #{source_dir} && tar -xf - )"
202
- elsif project_file.end_with?('.bz2')
203
- "bzip2 -dc #{project_file} | ( cd #{source_dir} && tar -xf - )"
204
- elsif project_file.end_with?('.7z')
205
- "7z.exe x #{project_file} -o#{source_dir} -r -y"
206
- elsif project_file.end_with?('.zip')
207
- "unzip #{project_file} -d #{source_dir}"
208
- elsif project_file.end_with?('.xz') || project_file.end_with?('.txz')
209
- "xz -dc #{project_file} | ( cd #{source_dir} && tar -xf - )"
204
+ if Ohai['platform'] == 'windows' && project_file.end_with?(*WIN_7Z_EXTENSIONS)
205
+ "7z.exe x #{project_file} -o#{Config.source_dir} -r -y"
206
+ elsif Ohai['platform'] != 'windows' && project_file.end_with?('.7z')
207
+ "7z x #{project_file} -o#{Config.source_dir} -r -y"
208
+ elsif Ohai['platform'] != 'windows' && project_file.end_with?('.zip')
209
+ "unzip #{project_file} -d #{Config.source_dir}"
210
+ elsif project_file.end_with?(*TAR_EXTENSIONS)
211
+ compression_switch = 'z' if project_file.end_with?('gz')
212
+ compression_switch = 'j' if project_file.end_with?('bz2')
213
+ compression_switch = 'J' if project_file.end_with?('xz')
214
+ compression_switch = '' if project_file.end_with?('tar')
215
+ "tar #{compression_switch}xf #{project_file} -C#{Config.source_dir}"
210
216
  else
211
217
  # if we don't recognize the extension, simply copy over the file
212
218
  proc do
@@ -17,6 +17,9 @@
17
17
  module Omnibus
18
18
  # Fetcher implementation for projects on the filesystem
19
19
  class PathFetcher < Fetcher
20
+
21
+ include Digestable
22
+
20
23
  def initialize(software)
21
24
  @name = software.name
22
25
  @source = software.source
@@ -33,7 +36,7 @@ module Omnibus
33
36
  end
34
37
 
35
38
  def rsync
36
- if Ohai.platform == 'windows'
39
+ if Ohai['platform'] == 'windows'
37
40
  # Robocopy's return code is 1 if it succesfully copies over the
38
41
  # files and 0 if the files are already existing at the destination
39
42
  sync_cmd = "robocopy #{@source[:path]}\\ #{@project_dir}\\ /MIR /S"
@@ -53,6 +56,10 @@ module Omnibus
53
56
  rsync
54
57
  end
55
58
 
59
+ def version_for_cache
60
+ @version_for_cache ||= digest_directory(@project_dir, :sha256)
61
+ end
62
+
56
63
  def fetch_required?
57
64
  true
58
65
  end
@@ -16,13 +16,6 @@
16
16
 
17
17
  module Omnibus
18
18
  class S3CacheFetcher < NetFetcher
19
- include SoftwareS3URLs
20
-
21
- def initialize(software)
22
- @software = software
23
- super
24
- end
25
-
26
19
  def fetch
27
20
  log.info(log_key) do
28
21
  "S3 Cache enabled, '#{name}' will be fetched from S3 cache"
@@ -31,8 +24,24 @@ module Omnibus
31
24
  super
32
25
  end
33
26
 
27
+ #
28
+ # The source URI for the software definition that is being fetched.
29
+ #
30
+ # @return [URI]
31
+ #
34
32
  def source_uri
35
33
  URI.parse(url_for(@software))
36
34
  end
35
+
36
+ private
37
+
38
+ #
39
+ # The URL for the cached software.
40
+ #
41
+ # @return [String]
42
+ #
43
+ def url_for(software)
44
+ "http://#{Config.s3_bucket}.s3.amazonaws.com/#{S3Cache.key_for(software)}"
45
+ end
37
46
  end
38
47
  end
@@ -48,7 +48,7 @@ module Omnibus
48
48
  template('Gemfile.erb', "#{target}/Gemfile", template_options)
49
49
  template('gitignore.erb', "#{target}/.gitignore", template_options)
50
50
  template('README.md.erb', "#{target}/README.md", template_options)
51
- template('omnibus.rb.example.erb', "#{target}/omnibus.rb.example", template_options)
51
+ template('omnibus.rb.erb', "#{target}/omnibus.rb", template_options)
52
52
  end
53
53
 
54
54
  def create_project_definition
@@ -124,7 +124,7 @@ module Omnibus
124
124
  def template_options
125
125
  @template_options ||= {
126
126
  name: name,
127
- install_path: "/opt/#{name}",
127
+ install_dir: "/opt/#{name}",
128
128
  }
129
129
  end
130
130
  end
@@ -5,7 +5,10 @@ gem 'berkshelf', '~> 3.0'
5
5
 
6
6
  # Install omnibus software
7
7
  gem 'omnibus', '~> <%= Omnibus::VERSION.split('.')[0...-1].join('.') %>'
8
- gem 'omnibus-software', github: 'opscode/omnibus-software'
8
+
9
+ # Use Chef's software definitions. It is recommended that you write your own
10
+ # software definitions, but you can clone/fork Chef's to get you started.
11
+ # gem 'omnibus-software', github: 'opscode/omnibus-software'
9
12
 
10
13
  # Use Test Kitchen with Vagrant for converging the build environment
11
14
  gem 'test-kitchen', '~> 1.2'
@@ -44,6 +44,16 @@ the package cache directory (`/var/cache/omnibus/pkg`):
44
44
  $ bin/omnibus clean <%= config[:name] %> --purge
45
45
  ```
46
46
 
47
+ ### Publish
48
+
49
+ Omnibus has a built-in mechanism for releasing to a variety of "backends", such
50
+ as Amazon S3. You must set the proper credentials in your `omnibus.rb` config
51
+ file or specify them via the command line.
52
+
53
+ ```shell
54
+ $ bin/omnibus publish path/to/*.deb --backend s3
55
+ ```
56
+
47
57
  ### Help
48
58
 
49
59
  Full help for the Omnibus command line interface can be accessed with the
@@ -1,13 +1,13 @@
1
1
  #
2
2
  # This file is used to configure the <%= config[:name] %> project. It contains
3
- # come minimal configuration examples for working with Omnibus. For a full list
3
+ # some minimal configuration examples for working with Omnibus. For a full list
4
4
  # of configurable options, please see the documentation for +omnibus/config.rb+.
5
5
  #
6
6
 
7
7
  # Build internally
8
8
  # ------------------------------
9
9
  # By default, Omnibus uses system folders (like +/var+ and +/opt+) to build and
10
- # cache compontents. If you would to build everything internally, you can
10
+ # cache components. If you would to build everything internally, you can
11
11
  # uncomment the following options. This will prevent the need for root
12
12
  # permissions in most cases. You will also need to update the <%= config[:name] %>
13
13
  # project configuration to build at +./local/omnibus/build+ instead of
@@ -19,21 +19,30 @@
19
19
  #
20
20
  # Alternatively you can tune the individual values
21
21
  # ------------------------------------------------
22
- # cache_dir './local/omnibus/cache'
23
- # install_path_cache_dir './local/omnibus/cache/install_path'
24
- # source_dir './local/omnibus/src'
25
- # build_dir './local/omnibus/build'
26
- # package_dir './local/omnibus/pkg'
27
- # package_tmp './local/omnibus/pkg-tmp'
22
+ # cache_dir './local/omnibus/cache'
23
+ # git_cache_dir './local/omnibus/cache/install_path'
24
+ # source_dir './local/omnibus/src'
25
+ # build_dir './local/omnibus/build'
26
+ # package_dir './local/omnibus/pkg'
27
+ # package_tmp './local/omnibus/pkg-tmp'
28
+
29
+ # Disable git caching
30
+ # ------------------------------
31
+ # use_git_caching false
28
32
 
29
33
  # Enable S3 asset caching
30
34
  # ------------------------------
31
35
  # use_s3_caching true
32
- # s3_access_key 'something'
33
- # s3_secret_key 'something'
34
- # s3_bucket 'some-bucket'
36
+ # s3_access_key ENV['S3_ACCESS_KEY']
37
+ # s3_secret_key ENV['S3_SECRET_KEY']
38
+ # s3_bucket ENV['S3_BUCKET']
35
39
 
36
40
  # Customize compiler bits
37
41
  # ------------------------------
38
42
  # solaris_compiler 'gcc'
39
43
  # build_retries 5
44
+
45
+ # Load additional software
46
+ # ------------------------------
47
+ # software_gems ['omnibus-software', 'my-company-software']
48
+ # local_software_dirs ['/path/to/local/software']
@@ -5,7 +5,7 @@
5
5
 
6
6
  PROGNAME=`basename $0`
7
7
  INSTALLER_DIR=`dirname $0`
8
- DEST_DIR=<%= config[:install_path] %>
8
+ DEST_DIR=<%= config[:install_dir] %>
9
9
  CONFIG_DIR=/etc/<%= config[:name] %>
10
10
  USAGE="usage: $0"
11
11
 
@@ -1,9 +1,9 @@
1
1
 
2
2
  name '<%= config[:name] %>'
3
3
  maintainer 'CHANGE ME'
4
- homepage 'CHANGEME.com'
4
+ homepage 'https://CHANGE-ME.com'
5
5
 
6
- install_path '<%= config[:install_path] %>'
6
+ install_dir '<%= config[:install_dir] %>'
7
7
  build_version Omnibus::BuildVersion.semver
8
8
  build_iteration 1
9
9
 
@@ -2,8 +2,8 @@
2
2
  <WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
3
3
  <!-- http://wix.codeplex.com/SourceControl/changeset/view/792e101c5cf7#src%2fext%2fUIExtension%2fwixlib%2fWixUI_en-us.wxl -->
4
4
  <String Id="LANG">1033</String>
5
- <String Id="ProductName"><%= friendly_name %></String>
6
- <String Id="ManufacturerName"><%= maintainer %></String>
5
+ <String Id="ProductName"><%= project.friendly_name %></String>
6
+ <String Id="ManufacturerName"><%= project.maintainer %></String>
7
7
  <String Id="WelcomeDlgTitle">{\WixUI_Font_Bigger}Welcome to the [ProductName] Setup Wizard</String>
8
8
 
9
9
  <String Id="LicenseAgreementDlgTitle">{\WixUI_Font_Title_White}End-User License Agreement</String>
@@ -16,5 +16,5 @@
16
16
 
17
17
  <String Id="VerifyReadyDlgInstallTitle">{\WixUI_Font_Title_White}Ready to install [ProductName]</String>
18
18
 
19
- <String Id="FeatureMainName"><%= friendly_name %></String>
19
+ <String Id="FeatureMainName"><%= project.friendly_name %></String>
20
20
  </WixLocalization>
@@ -0,0 +1,192 @@
1
+ #
2
+ # Copyright 2014 Chef Software, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'digest'
18
+ require 'fileutils'
19
+
20
+ module Omnibus
21
+ class GitCache
22
+ include Util
23
+ include Logging
24
+
25
+ REQUIRED_GIT_FILES = [
26
+ 'HEAD',
27
+ 'description',
28
+ 'hooks',
29
+ 'info',
30
+ 'objects',
31
+ 'refs',
32
+ ].freeze
33
+
34
+ #
35
+ # @return [Software]
36
+ #
37
+ attr_reader :software
38
+
39
+ #
40
+ # @param [Software] software
41
+ # the software this git cache is for
42
+ #
43
+ def initialize(software)
44
+ @software = software
45
+ end
46
+
47
+ #
48
+ # The path to the full install_dir cache for the project.
49
+ #
50
+ # @return [String]
51
+ #
52
+ def cache_path
53
+ @cache_path ||= File.join(Config.git_cache_dir, install_dir)
54
+ end
55
+
56
+ #
57
+ # Creates the full path if it does not exist already.
58
+ #
59
+ # @return [true, false]
60
+ # true if the path was created, false otherwise
61
+ #
62
+ def create_cache_path
63
+ if File.directory?(cache_path)
64
+ log.info(log_key) { "Cache path `#{cache_path}' exists, skipping creation" }
65
+ false
66
+ else
67
+ log.info(log_key) { "Creating cache path `#{cache_path}'" }
68
+ FileUtils.mkdir_p(File.dirname(cache_path))
69
+ shellout!("git --git-dir=#{cache_path} init -q")
70
+ true
71
+ end
72
+ end
73
+
74
+ #
75
+ # Computes the tag for this cache entry.
76
+ #
77
+ # @return [String]
78
+ #
79
+ def tag
80
+ return @tag if @tag
81
+
82
+ log.info(log_key) { "Calculating tag" }
83
+
84
+ # Accumulate an array of all the software projects that come before
85
+ # the name and version we are tagging. So if you have
86
+ #
87
+ # build_order = [ 1, 2, 3, 4, 5 ]
88
+ #
89
+ # And we are tagging 3, you would get dep_list = [ 1, 2 ]
90
+ dep_list = software.project.library.build_order.take_while do |dep|
91
+ if dep.name == software.name && dep.version == software.version
92
+ false
93
+ else
94
+ true
95
+ end
96
+ end
97
+
98
+ log.debug(log_key) { "dep_list: #{dep_list.map(&:name).inspect}" }
99
+
100
+ # This is the list of all the unqiue shasums of all the software build
101
+ # dependencies, including the on currently being acted upon.
102
+ shasums = [dep_list.map(&:shasum), software.shasum].flatten
103
+ suffix = Digest::SHA256.hexdigest(shasums.join('|'))
104
+ @tag = "#{software.name}-#{suffix}"
105
+
106
+ log.debug(log_key) { "tag: #{@tag}" }
107
+
108
+ @tag
109
+ end
110
+
111
+ # Create an incremental install path cache for the software step
112
+ def incremental
113
+ log.info(log_key) { 'Performing incremental cache' }
114
+
115
+ create_cache_path
116
+ remove_git_dirs
117
+
118
+ shellout!(%Q(git --git-dir=#{cache_path} --work-tree=#{install_dir} add -A -f))
119
+ begin
120
+ shellout!(%Q(git --git-dir=#{cache_path} --work-tree=#{install_dir} commit -q -m "Backup of #{tag}"))
121
+ rescue Mixlib::ShellOut::ShellCommandFailed => e
122
+ if e.message !~ /nothing to commit/
123
+ raise
124
+ end
125
+ end
126
+ shellout!(%Q(git --git-dir=#{cache_path} --work-tree=#{install_dir} tag -f "#{tag}"))
127
+ end
128
+
129
+ def restore
130
+ log.info(log_key) { 'Performing cache restoration' }
131
+
132
+ create_cache_path
133
+
134
+ cmd = shellout(%Q(git --git-dir=#{cache_path} --work-tree=#{install_dir} tag -l "#{tag}"))
135
+
136
+ restore_me = false
137
+ cmd.stdout.each_line do |line|
138
+ restore_me = true if tag == line.chomp
139
+ end
140
+
141
+ if restore_me
142
+ log.debug(log_key) { "Detected tag `#{tag}' can be restored, restoring" }
143
+ shellout!(%Q(git --git-dir=#{cache_path} --work-tree=#{install_dir} checkout -f "#{tag}"))
144
+ true
145
+ else
146
+ log.debug(log_key) { "Could not find tag `#{tag}', skipping restore" }
147
+ false
148
+ end
149
+ end
150
+
151
+ #
152
+ # Git caching will attempt to version embedded git directories, partially
153
+ # versioning them. This causes failures on subsequent runs. This method
154
+ # will find git directories and remove them to prevent those errors.
155
+ #
156
+ # @return [true]
157
+ def remove_git_dirs
158
+ log.info(log_key) { "Removing git directories" }
159
+
160
+ Dir.glob("#{install_dir}/**/{,.*}/config").reject do |path|
161
+ REQUIRED_GIT_FILES.any? do |required_file|
162
+ !File.exist?(File.join(File.dirname(path), required_file))
163
+ end
164
+ end.each do |path|
165
+ log.info(log_key) { "Removing git dir `#{path}'" }
166
+ FileUtils.rm_rf(File.dirname(path))
167
+ end
168
+
169
+ true
170
+ end
171
+
172
+ private
173
+
174
+ #
175
+ #
176
+ # The installation directory for this software's project. Drive letters are
177
+ # stripped for Windows.
178
+ #
179
+ # @return [String]
180
+ #
181
+ def install_dir
182
+ @install_dir ||= software.project.install_dir.sub(/^([A-Za-z]:)/, '')
183
+ end
184
+
185
+ # Override the log_key for this class to include the software name
186
+ #
187
+ # @return [String]
188
+ def log_key
189
+ @log_key ||= "#{super}: #{software.name}"
190
+ end
191
+ end
192
+ end