terraspace 0.4.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/lib/templates/base/arg/terraform.rb.tt +3 -0
  4. data/lib/templates/base/helper/%name%_helper.rb.tt +2 -0
  5. data/lib/templates/base/hook/%kind%.rb.tt +7 -0
  6. data/lib/terraspace.rb +4 -3
  7. data/lib/terraspace/all/base.rb +0 -1
  8. data/lib/terraspace/app.rb +1 -0
  9. data/lib/terraspace/autoloader.rb +20 -3
  10. data/lib/terraspace/cli/bundle.rb +0 -1
  11. data/lib/terraspace/cli/clean/base.rb +0 -1
  12. data/lib/terraspace/cli/clean/cache.rb +0 -1
  13. data/lib/terraspace/cli/help/new/arg.md +19 -0
  14. data/lib/terraspace/cli/help/new/helper.md +39 -0
  15. data/lib/terraspace/cli/help/new/hook.md +25 -0
  16. data/lib/terraspace/cli/help/new/test.md +34 -0
  17. data/lib/terraspace/cli/new.rb +22 -16
  18. data/lib/terraspace/cli/new/arg.rb +62 -0
  19. data/lib/terraspace/cli/new/helper.rb +44 -12
  20. data/lib/terraspace/cli/new/helpers.rb +22 -0
  21. data/lib/terraspace/cli/new/helpers/plugin_gem.rb +25 -0
  22. data/lib/terraspace/cli/new/hook.rb +70 -0
  23. data/lib/terraspace/cli/new/module.rb +0 -11
  24. data/lib/terraspace/cli/new/plugin.rb +4 -4
  25. data/lib/terraspace/cli/new/plugin/helper.rb +1 -1
  26. data/lib/terraspace/cli/new/project.rb +16 -7
  27. data/lib/terraspace/cli/new/sequence.rb +3 -10
  28. data/lib/terraspace/cli/new/source/core.rb +1 -1
  29. data/lib/terraspace/cli/new/stack.rb +1 -12
  30. data/lib/terraspace/cli/new/test.rb +50 -0
  31. data/lib/terraspace/cli/summary.rb +0 -1
  32. data/lib/terraspace/command.rb +16 -0
  33. data/lib/terraspace/compiler/builder.rb +2 -0
  34. data/lib/terraspace/compiler/dsl/mod.rb +2 -0
  35. data/lib/terraspace/compiler/dsl/syntax/mod.rb +2 -0
  36. data/lib/terraspace/compiler/dsl/syntax/mod/backend.rb +1 -1
  37. data/lib/terraspace/compiler/erb/context.rb +2 -0
  38. data/lib/terraspace/compiler/helper_extender.rb +27 -0
  39. data/lib/terraspace/core.rb +0 -6
  40. data/lib/terraspace/ext/core/module.rb +16 -0
  41. data/lib/terraspace/hooks/builder.rb +6 -7
  42. data/lib/terraspace/hooks/concern.rb +2 -2
  43. data/lib/terraspace/logger.rb +6 -0
  44. data/lib/terraspace/mod.rb +0 -1
  45. data/lib/terraspace/plugin.rb +8 -4
  46. data/lib/terraspace/plugin/config/interface.rb +2 -2
  47. data/lib/terraspace/plugin/helper/interface.rb +31 -0
  48. data/lib/terraspace/terraform/args/custom.rb +2 -3
  49. data/lib/terraspace/terraform/runner/retryer.rb +7 -3
  50. data/lib/terraspace/version.rb +1 -1
  51. data/spec/terraspace/terraform/args/custom_spec.rb +6 -4
  52. data/terraspace.gemspec +4 -4
  53. metadata +27 -21
  54. data/lib/terraspace/cli/help/new/bootstrap_test.md +0 -8
  55. data/lib/terraspace/cli/help/new/module_test.md +0 -12
  56. data/lib/terraspace/cli/help/new/project_test.md +0 -8
  57. data/lib/terraspace/cli/new/helper/plugin_gem.rb +0 -12
  58. data/lib/terraspace/cli/new/test/base.rb +0 -17
  59. data/lib/terraspace/cli/new/test/bootstrap.rb +0 -18
  60. data/lib/terraspace/cli/new/test/module.rb +0 -15
  61. data/lib/terraspace/cli/new/test/project.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bae908fcf2dc448dc5b0d2bba463eedd9487c428a296b74955975b66e2faa7c3
4
- data.tar.gz: bef0979ecaeab8eca50387da95a119719696a759ecff7de55659ff0d8cbac322
3
+ metadata.gz: bbf29f1226e7dc336c0eaf99892e158aff3b804bd56bbd1dc744fd17a65c6ff0
4
+ data.tar.gz: 6c32f1fe94e9dc53f6ddbfca3cef7c1178a11d788b32ad6ad3fdc88d64e268fa
5
5
  SHA512:
6
- metadata.gz: 882b9a94cf48af9399a66540385dcd7dbcdbb8118df046c6af833e053f265e57dfeb0a3692f32e315b6a13bb59334c51cfc856db0fc68a067cee4800bc1a3a32
7
- data.tar.gz: 720aa71881469e415445a1ff83e853c1ece6d71873830111eb1de59c121e9408e478ddaabdd30e6c29e2d48d39b1ec1c96c739e16ca682b3e13e129253594d44
6
+ metadata.gz: b5e45213f23aaed8b4348d4a68179b2706577d6cdf7cf2588f979feb6433e742851392331a8d2909be4a745b6ef9089c419d22d4dd6140ec981c536e809c29df
7
+ data.tar.gz: f9e436d5ee96f410c66d673819a789ffdca814f8d53c8f7c97b2b005c9d2bd5cd48fc9a6619407ec7da42e0d3ca503666a5e3d2f2124f30b211a22ba87ec7075
@@ -3,6 +3,21 @@
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.5.0] - 2020-11-15
7
+ - [#55](https://github.com/boltops-tools/terraspace/pull/55) custom helpers support
8
+ - plugin helpers support: aws_secret, aws_ssm, google_secret, etc
9
+ - introduce stack-level test concept and change project-level test concept
10
+ - generators: standardize and unifiy new test
11
+ - new generators: arg, hook, helper
12
+ - clean up Terraspace check project
13
+ - setup up autoloader and bundler/setup earlier. removes need for shim
14
+ - test generator plugin autodetection
15
+ - remove internal run_generator_hook_script
16
+ - stack-level args customization support
17
+ - improve test output noise-level
18
+ - new setting: config.terraform.plugin_cache.purge_on_error
19
+ - quiet option for project generator
20
+
6
21
  ## [0.4.4]
7
22
  - #50 retry logic for shared cache error
8
23
  - #51 fix cloud sync: call build first
@@ -0,0 +1,3 @@
1
+ command("<%= arg_name %>",
2
+ args: ["-lock-timeout=22m"],
3
+ )
@@ -0,0 +1,2 @@
1
+ module <%= helper_class %>
2
+ end
@@ -0,0 +1,7 @@
1
+ before("<%= hook_name %>",
2
+ execute: "echo '<%= hook_path %>: test <%= type %> before hook for <%= kind %> <%= hook_name %>'",
3
+ )
4
+
5
+ after("<%= hook_name %>",
6
+ execute: "echo '<%= hook_path %>: test <%= type %> after hook for <%= kind %> <%= hook_name %>'"
7
+ )
@@ -1,6 +1,10 @@
1
1
  $stdout.sync = true unless ENV["TS_STDOUT_SYNC"] == "0"
2
2
 
3
3
  $:.unshift(File.expand_path("../", __FILE__))
4
+
5
+ require "terraspace/autoloader"
6
+ Terraspace::Autoloader.setup
7
+
4
8
  require "active_support/concern"
5
9
  require "active_support/core_ext/class"
6
10
  require "active_support/core_ext/hash"
@@ -18,9 +22,6 @@ require "set"
18
22
  require "terraspace/ext"
19
23
  require "terraspace/version"
20
24
 
21
- require "terraspace/autoloader"
22
- Terraspace::Autoloader.setup
23
-
24
25
  DslEvaluator.backtrace_reject = "lib/terraspace"
25
26
 
26
27
  module Terraspace
@@ -2,7 +2,6 @@ module Terraspace::All
2
2
  class Base
3
3
  def initialize(options={})
4
4
  @options = options
5
- Terraspace.check_project! unless ENV['TS_TEST']
6
5
  end
7
6
  end
8
7
  end
@@ -47,6 +47,7 @@ module Terraspace
47
47
  config.terraform.plugin_cache = ActiveSupport::OrderedOptions.new
48
48
  config.terraform.plugin_cache.dir = ENV['TF_PLUGIN_CACHE_DIR'] || "#{Terraspace.tmp_root}/plugin_cache"
49
49
  config.terraform.plugin_cache.enabled = true
50
+ config.terraform.plugin_cache.purge_on_error = true
50
51
  config.test_framework = "rspec"
51
52
  config
52
53
  end
@@ -1,8 +1,15 @@
1
- require "terraspace/bundle"
2
- Terraspace::Bundle.setup
1
+ if File.exist?("config/app.rb")
2
+ require "terraspace/bundle"
3
+ Terraspace::Bundle.setup
4
+ end
3
5
  require "zeitwerk"
4
6
 
5
7
  module Terraspace
8
+ # These modules are namespaces for user-defined custom helpers
9
+ module Module; end
10
+ module Project; end
11
+ module Stack; end
12
+
6
13
  class Autoloader
7
14
  class Inflector < Zeitwerk::Inflector
8
15
  def camelize(basename, _abspath)
@@ -16,10 +23,20 @@ module Terraspace
16
23
  loader = Zeitwerk::Loader.new
17
24
  loader.inflector = Inflector.new
18
25
  loader.push_dir(File.dirname(__dir__)) # lib
26
+ loader.push_dir(project_helpers, namespace: Terraspace::Project) if File.exist?(project_helpers)
19
27
  loader.log! if ENV["TS_AUTOLOAD_LOG"]
20
- loader.ignore("#{__dir__}/core_ext.rb")
28
+ loader.ignore("#{__dir__}/ext.rb")
21
29
  loader.setup
22
30
  end
31
+
32
+ def project_helpers
33
+ "#{ts_root}/config/helpers"
34
+ end
35
+
36
+ # Duplicate definition because autoloader logic runs very early and doesnt have access to core methods yet
37
+ def ts_root
38
+ ENV['TS_ROOT'] || Dir.pwd
39
+ end
23
40
  end
24
41
  end
25
42
  end
@@ -7,7 +7,6 @@ class Terraspace::CLI
7
7
  end
8
8
 
9
9
  def run
10
- Terraspace.check_project!
11
10
  TerraspaceBundler.config.deep_merge!(Terraspace.config.bundle)
12
11
  TerraspaceBundler::CLI.start(args)
13
12
  end
@@ -5,7 +5,6 @@ class Terraspace::CLI::Clean
5
5
 
6
6
  def initialize(options={})
7
7
  @options = options
8
- Terraspace.check_project!
9
8
  end
10
9
 
11
10
  def pretty(path)
@@ -1,7 +1,6 @@
1
1
  class Terraspace::CLI::Clean
2
2
  class Cache < Base
3
3
  def run
4
- Terraspace.check_project!
5
4
  paths = [Terraspace.cache_root, Terraspace.tmp_root]
6
5
  are_you_sure?(paths)
7
6
  paths.each do |path|
@@ -0,0 +1,19 @@
1
+ ## Examples
2
+
3
+ Project-level arg:
4
+
5
+ $ terraspace new arg --type project
6
+ create config/args
7
+ create config/args/terraform.rb
8
+
9
+ Stack-level arg:
10
+
11
+ $ terraspace new arg demo --type stack
12
+ create app/stacks/demo/config/args
13
+ create app/stacks/demo/config/args/terraform.rb
14
+
15
+ Module-level arg:
16
+
17
+ $ terraspace new arg example --type module
18
+ create app/modules/example/config/args
19
+ create app/modules/example/config/args/terraform.rb
@@ -0,0 +1,39 @@
1
+ ## Project Examples
2
+
3
+ Conventionally name the helper custom.
4
+
5
+ $ terraspace new helper custom --type project
6
+ create config/helpers
7
+ create config/helpers/custom_helper.rb
8
+
9
+ ## Stack Examples
10
+
11
+ Conventionally name the helper to be the same as the stack name.
12
+
13
+ $ terraspace new helper demo --type stack
14
+ create app/stacks/demo/config/helpers
15
+ create app/stacks/demo/config/helpers/demo_helper.rb
16
+ $
17
+
18
+ Explictly name helper method. IE: custom here.
19
+
20
+ $ terraspace new helper demo --type stack --name custom
21
+ create app/stacks/demo/config/helpers
22
+ create app/stacks/demo/config/helpers/custom_helper.rb
23
+ $
24
+
25
+ ## Module Examples
26
+
27
+ Conventionally name the helper to be the same as the module name.
28
+
29
+ $ terraspace new helper example --type module
30
+ create app/module/example/config/helpers
31
+ create app/module/example/config/helpers/example_helper.rb
32
+ $
33
+
34
+ Explictly name helper method. IE: custom here.
35
+
36
+ $ terraspace new helper example --type module --name custom
37
+ create app/module/example/config/helpers
38
+ create app/module/example/config/helpers/custom_helper.rb
39
+ $
@@ -0,0 +1,25 @@
1
+ ## Examples
2
+
3
+ Project-level hook:
4
+
5
+ $ terraspace new hook --type project
6
+ create config/hooks
7
+ create config/hooks/terraform.rb
8
+
9
+ Stack-level hook:
10
+
11
+ $ terraspace new hook demo --type stack
12
+ create app/stacks/demo/config/hooks
13
+ create app/stacks/demo/config/hooks/terraform.rb
14
+
15
+ Stack-level hook with kind option:
16
+
17
+ $ terraspace new hook demo --type stack --kind terraspace
18
+ exist app/stacks/demo/config/hooks
19
+ create app/stacks/demo/config/hooks/terraspace.rb
20
+
21
+ Module-level hook:
22
+
23
+ $ terraspace new hook example --type module
24
+ create app/modules/example/config/hooks
25
+ create app/modules/example/config/hooks/terraform.rb
@@ -0,0 +1,34 @@
1
+ ## Stack Examples
2
+
3
+ $ terraspace new test demo --type stack
4
+ => Creating stack test: example
5
+ exist app/stacks/example
6
+ create app/stacks/example/test/.rspec
7
+ create app/stacks/example/test/Gemfile
8
+ create app/stacks/example/test/spec/fixtures/stack/main.tf
9
+ create app/stacks/example/test/spec/fixtures/stack/outputs.tf
10
+ create app/stacks/example/test/spec/main_spec.rb
11
+ create app/stacks/example/test/spec/spec_helper.rb
12
+ $
13
+
14
+ ## Module Examples
15
+
16
+ $ terraspace new test example --type module
17
+ => Creating module test: example
18
+ exist app/modules/example
19
+ create app/modules/example/test/.rspec
20
+ create app/modules/example/test/Gemfile
21
+ create app/modules/example/test/spec/fixtures/stack/main.tf
22
+ create app/modules/example/test/spec/fixtures/stack/outputs.tf
23
+ create app/modules/example/test/spec/main_spec.rb
24
+ create app/modules/example/test/spec/spec_helper.rb
25
+ $
26
+
27
+ ## Project Examples
28
+
29
+ $ terraspace new test my --type project
30
+ => Creating test bootstrap structure
31
+ exist
32
+ create .rspec
33
+ create spec/spec_helper.rb
34
+ $
@@ -1,5 +1,9 @@
1
1
  class Terraspace::CLI
2
2
  class New < Terraspace::Command
3
+ long_desc Help.text("new/arg")
4
+ Arg.options.each { |args| option(*args) }
5
+ register(Arg, "arg", "arg NAME", "Generates new arg.")
6
+
3
7
  long_desc Help.text("new/git_hook")
4
8
  GitHook.cli_options.each { |args| option(*args) }
5
9
  register(GitHook, "git_hook", "git_hook", "Generates new git hook.")
@@ -8,33 +12,35 @@ class Terraspace::CLI
8
12
  Shim.cli_options.each { |args| option(*args) }
9
13
  register(Shim, "shim", "shim", "Generates terraspace shim.")
10
14
 
15
+ long_desc Help.text("new/helper")
16
+ Helper.options.each { |args| option(*args) }
17
+ register(Helper, "helper", "helper NAME", "Generates new helper.")
18
+
19
+ long_desc Help.text("new/hook")
20
+ Hook.options.each { |args| option(*args) }
21
+ register(Hook, "hook", "hook NAME", "Generates new hook.")
22
+
11
23
  long_desc Help.text("new/module")
12
24
  Module.base_options.each { |args| option(*args) }
13
25
  Module.component_options.each { |args| option(*args) }
14
26
  register(Module, "module", "module NAME", "Generates new module.")
15
27
 
16
- long_desc Help.text("new/stack")
17
- Stack.base_options.each { |args| option(*args) }
18
- Stack.component_options.each { |args| option(*args) }
19
- register(Stack, "stack", "stack NAME", "Generates new stack.")
20
-
21
28
  long_desc Help.text("new/project")
22
29
  Project.base_options.each { |args| option(*args) }
23
30
  Project.project_options.each { |args| option(*args) }
24
31
  register(Project, "project", "project NAME", "Generates new project.")
25
32
 
26
- long_desc Help.text("new/project_test")
27
- register(Test::Project, "project_test", "project_test NAME", "Generates new project test.")
28
-
29
- long_desc Help.text("new/module_test")
30
- register(Test::Module, "module_test", "module_test NAME", "Generates new module test.")
31
-
32
- long_desc Help.text("new/bootstrap_test")
33
- Test::Bootstrap.options.each { |args| option(*args) }
34
- register(Test::Bootstrap, "bootstrap_test", "bootstrap_test", "Generates bootstrap test setup.")
35
-
36
33
  long_desc Help.text("new/plugin")
37
34
  Plugin.options.each { |args| option(*args) }
38
- register(Plugin, "plugin", "plugin", "Generates plugin.")
35
+ register(Plugin, "plugin", "plugin NAME", "Generates plugin.")
36
+
37
+ long_desc Help.text("new/stack")
38
+ Stack.base_options.each { |args| option(*args) }
39
+ Stack.component_options.each { |args| option(*args) }
40
+ register(Stack, "stack", "stack NAME", "Generates new stack.")
41
+
42
+ long_desc Help.text("new/test")
43
+ Test.options.each { |args| option(*args) }
44
+ register(Test, "test", "test NAME", "Generates new test.")
39
45
  end
40
46
  end
@@ -0,0 +1,62 @@
1
+ class Terraspace::CLI::New
2
+ class Arg < Thor::Group
3
+ include Thor::Actions
4
+
5
+ argument :stack, required: false
6
+
7
+ def self.options
8
+ [
9
+ [:force, aliases: %w[y], type: :boolean, desc: "Bypass overwrite are you sure prompt for existing files"],
10
+ [:name, default: "apply", desc: "command name"],
11
+ [:type, default: "project", desc: "project, stack or module"],
12
+ ]
13
+ end
14
+ options.each { |args| class_option(*args) }
15
+
16
+ def self.source_root
17
+ File.expand_path("../../../templates/base/arg", __dir__)
18
+ end
19
+
20
+ private
21
+ def type
22
+ valid_types = %w[project stack module]
23
+ type = @options[:type]
24
+ valid_types.include?(type) ? type : "project" # fallback to project if user provides invalid type
25
+ end
26
+
27
+ def name
28
+ options[:name] ? options[:name] : "apply"
29
+ end
30
+
31
+ def dest
32
+ map = {
33
+ project: "config/args",
34
+ stack: "app/stacks/#{stack}/config/args",
35
+ module: "app/modules/#{stack}/config/args",
36
+ }
37
+ map[type.to_sym]
38
+ end
39
+
40
+ def arg_path
41
+ "#{dest}/#{kind}.rb"
42
+ end
43
+
44
+ public
45
+
46
+ def check_stack_arg
47
+ return if type == "project"
48
+ return unless stack.nil?
49
+ # Else check for STACK argument for type module or stack
50
+ puts <<~EOL
51
+ Required STACK argument, either the module or stack name. Usage:
52
+
53
+ terraspace new arg STACK --type #{type}
54
+ EOL
55
+ exit 1
56
+ end
57
+
58
+ def create
59
+ directory ".", dest
60
+ end
61
+ end
62
+ end
@@ -1,22 +1,54 @@
1
1
  class Terraspace::CLI::New
2
- module Helper
3
- include Helper::PluginGem
2
+ class Helper < Thor::Group
3
+ include Thor::Actions
4
+
5
+ argument :stack
6
+
7
+ def self.options
8
+ [
9
+ [:force, aliases: %w[y], type: :boolean, desc: "Bypass overwrite are you sure prompt for existing files"],
10
+ [:name, desc: "Helper name used for the filename. Defaults to the project, module or stack name"],
11
+ [:type, default: "project", desc: "project, stack or module"],
12
+ ]
13
+ end
14
+ options.each { |args| class_option(*args) }
15
+
16
+ def self.source_root
17
+ File.expand_path("../../../templates/base/helper", __dir__)
18
+ end
4
19
 
5
20
  private
6
- def build_gemfile(*list)
7
- lines = []
8
- list.each do |name|
9
- lines << gem_line(name)
10
- end
11
- lines.join("\n")
21
+ def type
22
+ valid_types = %w[project stack module]
23
+ type = @options[:type]
24
+ valid_types.include?(type) ? type : "project" # fallback to project if user provides invalid type
12
25
  end
13
26
 
14
- def gem_line(name)
15
- if name == "terraspace"
16
- %Q|gem "#{name}", '~> #{Terraspace::VERSION}'|
27
+ def helper_class
28
+ if type == "project"
29
+ "Terraspace::#{type.camelize}::#{name.camelize}Helper"
17
30
  else
18
- %Q|gem "#{name}"|
31
+ "Terraspace::#{type.camelize}::#{stack.camelize}::#{name.camelize}Helper"
19
32
  end
20
33
  end
34
+
35
+ def name
36
+ options[:name] || stack
37
+ end
38
+
39
+ def dest
40
+ map = {
41
+ project: "config/helpers",
42
+ stack: "app/stacks/#{stack}/config/helpers",
43
+ module: "app/modules/#{stack}/config/helpers",
44
+ }
45
+ map[type.to_sym]
46
+ end
47
+
48
+ public
49
+
50
+ def create
51
+ directory ".", dest
52
+ end
21
53
  end
22
54
  end