terraspace-bundler 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/exe/{terraform-bundler → terraspace-bundler} +0 -0
  4. data/lib/terraspace_bundler.rb +1 -0
  5. data/lib/terraspace_bundler/cli/bundle.rb +3 -1
  6. data/lib/terraspace_bundler/cli/purge_cache.rb +21 -3
  7. data/lib/terraspace_bundler/core.rb +10 -0
  8. data/lib/terraspace_bundler/dsl/syntax.rb +4 -0
  9. data/lib/terraspace_bundler/exporter.rb +22 -6
  10. data/lib/terraspace_bundler/exporter/base.rb +1 -1
  11. data/lib/terraspace_bundler/exporter/copy.rb +2 -1
  12. data/lib/terraspace_bundler/extract.rb +21 -0
  13. data/lib/terraspace_bundler/extract/tar.rb +34 -0
  14. data/lib/terraspace_bundler/extract/zip.rb +16 -0
  15. data/lib/terraspace_bundler/info.rb +7 -0
  16. data/lib/terraspace_bundler/lockfile/version_comparer.rb +1 -7
  17. data/lib/terraspace_bundler/mod.rb +23 -15
  18. data/lib/terraspace_bundler/mod/concerns/local_concern.rb +10 -0
  19. data/lib/terraspace_bundler/mod/concerns/notation_concern.rb +42 -0
  20. data/lib/terraspace_bundler/mod/concerns/path_concern.rb +90 -0
  21. data/lib/terraspace_bundler/mod/{stack_concern.rb → concerns/stack_concern.rb} +1 -1
  22. data/lib/terraspace_bundler/mod/fetcher.rb +18 -0
  23. data/lib/terraspace_bundler/mod/fetcher/base.rb +27 -0
  24. data/lib/terraspace_bundler/mod/fetcher/gcs.rb +48 -0
  25. data/lib/terraspace_bundler/mod/{downloader.rb → fetcher/git.rb} +10 -16
  26. data/lib/terraspace_bundler/mod/fetcher/local.rb +15 -0
  27. data/lib/terraspace_bundler/mod/fetcher/s3.rb +66 -0
  28. data/lib/terraspace_bundler/mod/http/concern.rb +45 -0
  29. data/lib/terraspace_bundler/mod/http/source.rb +19 -0
  30. data/lib/terraspace_bundler/mod/props.rb +101 -0
  31. data/lib/terraspace_bundler/mod/{props_extension.rb → props/extension.rb} +6 -2
  32. data/lib/terraspace_bundler/mod/props/typer.rb +39 -0
  33. data/lib/terraspace_bundler/mod/registry.rb +77 -23
  34. data/lib/terraspace_bundler/syncer.rb +1 -2
  35. data/lib/terraspace_bundler/terrafile.rb +3 -3
  36. data/lib/terraspace_bundler/util/git.rb +10 -4
  37. data/lib/terraspace_bundler/util/sure.rb +22 -0
  38. data/lib/terraspace_bundler/version.rb +1 -1
  39. data/spec/fixtures/terrafiles/example/Terrafile +29 -0
  40. data/spec/terraform_bundler/mod/props_spec.rb +34 -0
  41. data/terraspace-bundler.gemspec +4 -0
  42. metadata +84 -10
  43. data/lib/terraspace_bundler/mod/path_concern.rb +0 -33
  44. data/lib/terraspace_bundler/mod/props_builder.rb +0 -56
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b65082aa14ea1fb025bf7578584d9ee307e88107fff02c14ccad67fbcdf49ce
4
- data.tar.gz: d6a597993b5e20c4de5384dae7751091dad02a85e7190d0d127589cc164cdf70
3
+ metadata.gz: c8245c4a3b7fd5b149298bdf0084bddeee9153ff1cd7016e7e13facb0f3bede2
4
+ data.tar.gz: 761d564519e6958842cc5386e7b84f4a2b2cc90e3801fc2c3845f752983241b2
5
5
  SHA512:
6
- metadata.gz: 3ee15d36d396afa262f2b2e8a7765d6665ffc6d1559ee2b37f1465a35703637240b1689110a81454c6ccb56fa74618d6ac0c78d01a001636b1310e09226034fd
7
- data.tar.gz: 6843a2efc05ec4b08df20e276bb1247c9b0638f9534afcbf37ead78f815f99dfbad754535e8854459b7dab0cd320a0ddc6b459850171170471bb5dd73f426bb2
6
+ metadata.gz: d23b49ddabd983bf1927c62aabc2a9bf4165970a32b7325e41965bc804267297cf269741677582e4c0c4f7603e15dc21fef9d5370200b18adb2f369733b653ae
7
+ data.tar.gz: 38bf841d2c9d721b34930786c46567a47e881e3951153272eb7f9dea66e23e974994071e5514a4e92091db0fb19d787ce22893bfb514464ae967fcc04bb34959
data/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [0.4.0] - 2021-08-10
7
+ - [#10](https://github.com/boltops-tools/terraspace-bundler/pull/10) terraspace bundle info: warning when no lockfile
8
+ - [#12](https://github.com/boltops-tools/terraspace-bundler/pull/12) support for: private registry, s3, gcs, local
9
+
10
+ ## [0.3.4] - 2021-04-15
11
+ - [#11](https://github.com/boltops-tools/terraspace-bundler/pull/11) improve registry dectection and gitlab repository support
12
+
13
+ ## [0.3.3] - 2021-02-24
14
+ - [#8](https://github.com/boltops-tools/terraspace-bundler/pull/8) fix https sources
15
+ - [#9](https://github.com/boltops-tools/terraspace-bundler/pull/9) Git checkout retry with v
16
+
17
+ ## [0.3.2]
18
+ - #4 only purge and export explicit mods
19
+ - are you sure prompt for purge_cache
20
+ - clean up update mode
21
+
6
22
  ## [0.3.1]
7
23
  - #3 all_stacks: only consider dirs
8
24
 
File without changes
@@ -7,6 +7,7 @@ require "dsl_evaluator"
7
7
  require "fileutils"
8
8
  require "memoist"
9
9
  require "rainbow/ext/string"
10
+ require "singleton"
10
11
  require "terraspace_bundler/version"
11
12
  require "yaml"
12
13
 
@@ -27,6 +27,7 @@ class TerraspaceBundler::CLI
27
27
 
28
28
  desc "purge_cache", "Purge cache."
29
29
  long_desc Help.text("bundle/purge_cache")
30
+ option :yes, aliases: :y, type: :boolean, desc: "bypass are you sure prompt"
30
31
  def purge_cache
31
32
  PurgeCache.new(options).run
32
33
  end
@@ -35,7 +36,8 @@ class TerraspaceBundler::CLI
35
36
  long_desc Help.text("bundle/update")
36
37
  terrafile_option.call
37
38
  def update(*mods)
38
- TB::Runner.new(options.merge(mods: mods, mode: "update")).run
39
+ TB.update_mode = true
40
+ TB::Runner.new(options.merge(mods: mods)).run
39
41
  end
40
42
  end
41
43
  end
@@ -1,11 +1,29 @@
1
1
  class TerraspaceBundler::CLI
2
2
  class PurgeCache < Base
3
- include TB::Mod::PathConcern
3
+ include TB::Mod::Concerns::PathConcern
4
4
  include TB::Util::Logging
5
+ include TB::Util::Sure
5
6
 
6
7
  def run
7
- FileUtils.rm_rf(tmp_root)
8
- logger.info "Removed #{tmp_root}"
8
+ paths = [tmp_root]
9
+ are_you_sure?(paths)
10
+ paths.each do |path|
11
+ FileUtils.rm_rf(path)
12
+ logger.info "Removed #{path}"
13
+ end
14
+
15
+ end
16
+
17
+ def are_you_sure?(paths)
18
+ pretty_paths = paths.map { |p| " #{p}" }.join("\n")
19
+ message = <<~EOL.chomp
20
+ Will remove these folders and all their files:
21
+
22
+ #{pretty_paths}
23
+
24
+ Are you sure?
25
+ EOL
26
+ sure?(message) # from Util::Sure
9
27
  end
10
28
  end
11
29
  end
@@ -22,5 +22,15 @@ module TerraspaceBundler
22
22
  dsl
23
23
  end
24
24
  memoize :dsl
25
+
26
+ @@update_mode = false
27
+ def update_mode
28
+ @@update_mode
29
+ end
30
+ alias_method :update_mode?, :update_mode
31
+
32
+ def update_mode=(v)
33
+ @@update_mode = v
34
+ end
25
35
  end
26
36
  end
@@ -21,6 +21,10 @@ class TerraspaceBundler::Dsl
21
21
  config.stack_options.merge!(value)
22
22
  end
23
23
 
24
+ def clone_with(value)
25
+ config.clone_with = value
26
+ end
27
+
24
28
  def config
25
29
  TB.config
26
30
  end
@@ -1,5 +1,6 @@
1
1
  module TerraspaceBundler
2
2
  class Exporter
3
+ include TB::Mod::Concerns::PathConcern
3
4
  include TB::Util::Logging
4
5
 
5
6
  def initialize(options={})
@@ -7,17 +8,26 @@ module TerraspaceBundler
7
8
  end
8
9
 
9
10
  def run
10
- purge
11
- lockfile.mods.each do |mod|
11
+ purge_all
12
+ mods.each do |mod|
12
13
  logger.info "Exporting #{mod.name}"
14
+ purge(mod)
13
15
  export(mod)
14
16
  end
15
17
  end
16
18
 
19
+ def mods
20
+ mods = lockfile.mods
21
+ if TB.update_mode? && !@options[:mods].empty?
22
+ mods.select! { |mod| @options[:mods].include?(mod.name) }
23
+ end
24
+ mods
25
+ end
26
+
17
27
  def export(mod)
18
- downloader = Mod::Downloader.new(mod)
19
- downloader.run
20
- downloader.switch_version(mod.sha)
28
+ fetcher = Mod::Fetcher.new(mod).instance
29
+ fetcher.run
30
+ fetcher.switch_version(mod.sha)
21
31
  copy = Copy.new(mod)
22
32
  copy.mod
23
33
  copy.stacks
@@ -25,11 +35,17 @@ module TerraspaceBundler
25
35
  end
26
36
 
27
37
  private
28
- def purge
38
+ def purge_all
39
+ return if TB.update_mode?
29
40
  return unless TB.config.export_purge
30
41
  FileUtils.rm_rf(TB.config.export_to)
31
42
  end
32
43
 
44
+ def purge(mod)
45
+ mod_path = get_mod_path(mod)
46
+ FileUtils.rm_rf(mod_path)
47
+ end
48
+
33
49
  def lockfile
34
50
  Lockfile.instance
35
51
  end
@@ -1,6 +1,6 @@
1
1
  class TerraspaceBundler::Exporter
2
2
  class Base
3
- include TB::Mod::PathConcern
3
+ include TB::Mod::Concerns::PathConcern
4
4
  include TB::Util::Logging
5
5
  end
6
6
  end
@@ -7,6 +7,7 @@ class TerraspaceBundler::Exporter
7
7
  def mod
8
8
  FileUtils.rm_rf(mod_path)
9
9
  FileUtils.mkdir_p(File.dirname(mod_path))
10
+ logger.debug "Copy: cp -r #{src_path} #{mod_path}"
10
11
  FileUtils.cp_r(src_path, mod_path)
11
12
  FileUtils.rm_rf("#{mod_path}/.git")
12
13
  end
@@ -17,7 +18,7 @@ class TerraspaceBundler::Exporter
17
18
 
18
19
  # src path is from the stage area
19
20
  def src_path
20
- path = stage_path(@mod.full_repo) # from PathConcern
21
+ path = stage_path(rel_dest_dir)
21
22
  path = "#{path}/#{@mod.subfolder}" if @mod.subfolder
22
23
  path
23
24
  end
@@ -0,0 +1,21 @@
1
+ module TerraspaceBundler
2
+ class Extract
3
+ def self.extract(archive, dest)
4
+ FileUtils.rm_rf(dest)
5
+ FileUtils.mkdir_p(File.dirname(dest))
6
+
7
+ if archive.ends_with?('.tgz') || archive.ends_with?('.tar.gz')
8
+ Tar.extract(archive, dest)
9
+ elsif archive.ends_with?('.zip')
10
+ Zip.extract(archive, dest)
11
+ else
12
+ puts <<~EOL.color(:red)
13
+ ERROR: Unable to extract. Unsupported archive extension for:
14
+
15
+ #{archive}
16
+ EOL
17
+ exit 1
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ require 'rubygems/package'
2
+ require 'zlib'
3
+ require 'fileutils'
4
+
5
+ # Thanks: https://gist.github.com/ForeverZer0/2adbba36fd452738e7cca6a63aee2f30
6
+ class TerraspaceBundler::Extract
7
+ class Tar
8
+ # tar_gz_archive = '/tmp/terraspace/bundler/stage/s3-us-west-2.amazonaws.com/demo-terraform-test/modules/example-module.tgz'
9
+ # destination = '/tmp/terraspace/where/extract/to'
10
+ def self.extract(tar_gz_archive, destination)
11
+ reader = Zlib::GzipReader.open(tar_gz_archive)
12
+ Gem::Package::TarReader.new(reader) do |tar|
13
+ dest = nil
14
+ tar.each do |entry|
15
+ dest ||= File.join destination, entry.full_name
16
+ if entry.directory?
17
+ FileUtils.rm_rf dest unless File.directory? dest
18
+ FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
19
+ elsif entry.file?
20
+ FileUtils.rm_rf dest unless File.file? dest
21
+ File.open dest, "wb" do |f|
22
+ f.print entry.read
23
+ end
24
+ FileUtils.chmod entry.header.mode, dest, :verbose => false
25
+ elsif entry.header.typeflag == '2' #Symlink!
26
+ File.symlink entry.header.linkname, dest
27
+ end
28
+ dest = nil
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'zip'
3
+
4
+ class TerraspaceBundler::Extract
5
+ class Zip
6
+ def self.extract(file, dest)
7
+ ::Zip::File.open(file) { |zip_file|
8
+ zip_file.each { |f|
9
+ f_path=File.join(dest, f.name)
10
+ FileUtils.mkdir_p(File.dirname(f_path))
11
+ zip_file.extract(f, f_path) unless File.exist?(f_path)
12
+ }
13
+ }
14
+ end
15
+ end
16
+ end
@@ -1,6 +1,13 @@
1
1
  module TerraspaceBundler
2
2
  class Info < TB::CLI::Base
3
3
  def run
4
+ file = TB.config.lockfile
5
+ unless File.exist?(file)
6
+ logger.info "No #{file} found".color(:red)
7
+ logger.info "Maybe run: terraspace bundle"
8
+ return
9
+ end
10
+
4
11
  name = @options[:mod]
5
12
  found = lockfile.mods.find { |m| m.name == @options[:mod] }
6
13
  if found
@@ -40,7 +40,7 @@ class TerraspaceBundler::Lockfile
40
40
  # Only check when set.
41
41
  # Also in update mode then always check it.
42
42
  @changed = @current.sha && !@locked.sha.include?(@current.sha) ||
43
- update_mode? && !@current.latest_sha.include?(@locked.sha)
43
+ TB.update_mode? && !@current.latest_sha.include?(@locked.sha)
44
44
  if @changed
45
45
  @reason = reason_message("sha")
46
46
  return @changed
@@ -52,11 +52,5 @@ class TerraspaceBundler::Lockfile
52
52
  def reason_message(version)
53
53
  "Replacing mod #{@current.name} because #{version} is different in Terrafile and Terrafile.lock"
54
54
  end
55
-
56
- def update_mode?
57
- self.class.update_mode
58
- end
59
-
60
- class_attribute :update_mode
61
55
  end
62
56
  end
@@ -1,9 +1,10 @@
1
1
  module TerraspaceBundler
2
2
  class Mod
3
- extend PropsExtension
4
- props :export_to, :name, :sha, :source, :subfolder, :type, :url
3
+ extend Props::Extension
4
+ props :export_to, :name, :sha, :source, :subfolder, :type, :url, :clone_with
5
5
 
6
- include StackConcern
6
+ include Concerns::StackConcern
7
+ include Concerns::LocalConcern
7
8
 
8
9
  attr_reader :props, :version, :ref, :tag, :branch
9
10
  def initialize(props={})
@@ -12,19 +13,21 @@ module TerraspaceBundler
12
13
  @version, @ref, @tag, @branch = @props[:version], @props[:ref], @props[:tag], @props[:branch]
13
14
  end
14
15
 
16
+ # support variety of options, prefer version
15
17
  def checkout_version
16
- v = detected_version
17
- v = "v#{v}" if type == "registry" && @version && !v.starts_with?("v")
18
- v
18
+ @version || @ref || @tag || @branch
19
19
  end
20
20
 
21
21
  # use url instead of source because for registry modules, the repo name is different
22
22
  def repo
23
- url_words[-1]
23
+ url_words[-1].sub(/\.git$/,'')
24
24
  end
25
25
 
26
+ # https://github.com/tongueroo/pet - 2nd to last word
27
+ # git@github.com:tongueroo/pet - 2nd to last word without chars before :
26
28
  def org
27
- url_words[-2] # second to last word
29
+ s = url_words[-2] # second to last word
30
+ s.split(':').last # in case of git@github.com:tongueroo/pet form
28
31
  end
29
32
 
30
33
  def full_repo
@@ -32,17 +35,22 @@ module TerraspaceBundler
32
35
  end
33
36
 
34
37
  def latest_sha
35
- downloader = Downloader.new(self)
36
- downloader.run
37
- downloader.sha
38
+ fetcher = Fetcher.new(self).instance
39
+ fetcher.run
40
+ fetcher.sha
38
41
  end
39
42
 
40
- private
41
- # support variety of options, prefer version
42
- def detected_version
43
- @version || @ref || @tag || @branch
43
+ def vcs_provider
44
+ if url.include?('http')
45
+ # "https://github.com/org/repo" => github.com
46
+ url.match(%r{http[s]?://(.*?)/})[1]
47
+ else # git@
48
+ # "git@github.com:org/repo" => github.com
49
+ url.match(%r{git@(.*?):})[1]
50
+ end
44
51
  end
45
52
 
53
+ private
46
54
  def url_words
47
55
  url.split('/')
48
56
  end
@@ -0,0 +1,10 @@
1
+ module TerraspaceBundler::Mod::Concerns
2
+ module LocalConcern
3
+ def local?
4
+ source.starts_with?("/") ||
5
+ source.starts_with?(".") ||
6
+ source.starts_with?("..") ||
7
+ source.starts_with?("~")
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,42 @@
1
+ require 'uri'
2
+
3
+ module TerraspaceBundler::Mod::Concerns
4
+ module NotationConcern
5
+ def remove_notations(source)
6
+ remove_subfolder_notation(remove_ref_notation(source))
7
+ end
8
+
9
+ def remove_ref_notation(source)
10
+ source.sub(/\?.*/,'')
11
+ end
12
+
13
+ def remove_subfolder_notation(source)
14
+ parts = clean_notation(source).split('//')
15
+ if parts.size == 2 # has subfolder
16
+ source.split('//')[0..-2].join('//') # remove only subfolder, keep rest of original source
17
+ else
18
+ source
19
+ end
20
+ end
21
+
22
+ def subfolder(source)
23
+ parts = clean_notation(source).split('//')
24
+ if parts.size == 2 # has subfolder
25
+ remove_ref_notation(parts.last)
26
+ end
27
+ end
28
+
29
+ def ref(source)
30
+ url = clean_notation(source)
31
+ uri = URI(url)
32
+ if uri.query
33
+ params = URI::decode_www_form(uri.query).to_h # if you are in 2.1 or later version of Ruby
34
+ params['ref']
35
+ end
36
+ end
37
+
38
+ def clean_notation(source)
39
+ source.sub(/.*::/,'').sub(%r{http[s?]://},'').sub(%r{git@(.*?):},'') # also remove git@ notation
40
+ end
41
+ end
42
+ end