terraspace 0.6.22 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.cody/README.md +2 -0
  3. data/.cody/azurerm/bin/az/configure.sh +5 -1
  4. data/.cody/azurerm/project.rb +4 -0
  5. data/.cody/azurerm/role.rb +0 -1
  6. data/.cody/google/bin/gcloud/configure.sh +2 -1
  7. data/.cody/google/project.rb +4 -0
  8. data/.cody/google/role.rb +0 -1
  9. data/.cody/none/bin/build.sh +15 -0
  10. data/.cody/none/buildspec.yml +10 -0
  11. data/.cody/none/project.rb +2 -0
  12. data/.cody/none/role.rb +4 -0
  13. data/.cody/shared/script/install/terraform.sh +14 -6
  14. data/.cody/unit/buildspec.yml +1 -0
  15. data/.pipedream/pipeline.rb +1 -0
  16. data/CHANGELOG.md +37 -0
  17. data/Gemfile +6 -0
  18. data/README.md +8 -4
  19. data/lib/templates/examples/hcl/module/main.tf +3 -0
  20. data/lib/templates/examples/hcl/module/outputs.tf +4 -0
  21. data/lib/templates/examples/hcl/module/variables.tf +5 -0
  22. data/lib/templates/examples/hcl/stack/main.tf +4 -0
  23. data/lib/templates/examples/hcl/stack/outputs.tf +4 -0
  24. data/lib/templates/examples/hcl/stack/variables.tf +5 -0
  25. data/lib/templates/examples/ruby/module/main.rb +3 -0
  26. data/lib/templates/examples/ruby/module/outputs.rb +4 -0
  27. data/lib/templates/examples/ruby/module/variables.rb +5 -0
  28. data/lib/templates/examples/ruby/stack/main.rb +4 -0
  29. data/lib/templates/examples/ruby/stack/outputs.rb +4 -0
  30. data/lib/templates/examples/ruby/stack/variables.rb +5 -0
  31. data/lib/templates/hcl/project/config/terraform/backend.tf.tt +5 -13
  32. data/lib/templates/hcl/project/config/terraform/provider.tf +4 -14
  33. data/lib/terraspace/autodetect.rb +15 -0
  34. data/lib/terraspace/autoloader.rb +6 -1
  35. data/lib/terraspace/builder.rb +1 -9
  36. data/lib/terraspace/bundle.rb +54 -0
  37. data/lib/terraspace/cli/concern.rb +113 -0
  38. data/lib/terraspace/cli/help/new/example.md +7 -1
  39. data/lib/terraspace/cli/help.rb +7 -8
  40. data/lib/terraspace/cli/new/example.rb +36 -0
  41. data/lib/terraspace/cli/new/helpers/plugin_gem.rb +2 -14
  42. data/lib/terraspace/cli/new/helpers.rb +1 -1
  43. data/lib/terraspace/cli/new/module.rb +1 -1
  44. data/lib/terraspace/cli/new/plugin/helper.rb +1 -1
  45. data/lib/terraspace/cli/new/plugin.rb +1 -1
  46. data/lib/terraspace/cli/new/project.rb +11 -17
  47. data/lib/terraspace/cli/new/sequence.rb +1 -1
  48. data/lib/terraspace/cli/new/source/core.rb +7 -6
  49. data/lib/terraspace/cli/new/source/plugin.rb +2 -2
  50. data/lib/terraspace/cli/new/stack.rb +3 -2
  51. data/lib/terraspace/cli/new/test.rb +12 -2
  52. data/lib/terraspace/cli/new.rb +4 -0
  53. data/lib/terraspace/cli/{check_setup.rb → setup/check.rb} +5 -3
  54. data/lib/terraspace/cli/setup.rb +9 -0
  55. data/lib/terraspace/cli/tfc_concern.rb +1 -1
  56. data/lib/terraspace/cli.rb +34 -27
  57. data/lib/terraspace/command.rb +3 -2
  58. data/lib/terraspace/compiler/commands_concern.rb +0 -8
  59. data/lib/terraspace/compiler/expander/backend.rb +44 -0
  60. data/lib/terraspace/compiler/expander.rb +11 -19
  61. data/lib/terraspace/core.rb +10 -0
  62. data/lib/terraspace/plugin/expander/friendly.rb +1 -0
  63. data/lib/terraspace/plugin/expander/interface.rb +19 -4
  64. data/lib/terraspace/terraform/api/client.rb +1 -1
  65. data/lib/terraspace/terraform/args/custom.rb +11 -6
  66. data/lib/terraspace/terraform/args/pass.rb +110 -0
  67. data/lib/terraspace/terraform/args/{default.rb → thor.rb} +1 -3
  68. data/lib/terraspace/{compiler → terraform/runner}/backend/parser.rb +1 -1
  69. data/lib/terraspace/{compiler → terraform/runner}/backend.rb +14 -1
  70. data/lib/terraspace/terraform/runner/retryer.rb +1 -1
  71. data/lib/terraspace/terraform/runner.rb +25 -15
  72. data/lib/terraspace/terraform/tfc/sync.rb +1 -1
  73. data/lib/terraspace/version.rb +1 -1
  74. data/lib/terraspace.rb +6 -1
  75. data/spec/terraspace/terraform/args/custom_spec.rb +4 -4
  76. data/spec/terraspace/terraform/args/pass_spec.rb +101 -0
  77. data/terraspace.gemspec +2 -4
  78. metadata +46 -50
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a4ab50a302acfb8803dd00d42b67bee179e0524dc425866c6ed56d9a0ad2be5
4
- data.tar.gz: d59bcf8434474bbbea0352cbcaf253b04112c3bdc8cb18b032fe56619dabf445
3
+ metadata.gz: 34fd5fc528a54f97026d5daf99d11ecee90882e915a94c92e50039c69a418e4c
4
+ data.tar.gz: '01418d9a47515ebd4b0ad15b10af00ca07492ea549d70a8555d82078c7cc40ea'
5
5
  SHA512:
6
- metadata.gz: 8f658972433c8e00ee3363beebfa0d55940d0febba4e00562fa77f3bfede938a5fa851cb261f9879ab340348d65aee57c0d324e25b41a1ddaa86478eb7ff2923
7
- data.tar.gz: 30f54a4f76034c01ed607564acdc4bcaac8f63adf85f120779dc212ec4e7615479a1a71a705f89deecc25dff38fd8e265fe9d8eb5e2b3f6347a4007b8f9e27ca
6
+ metadata.gz: fbecb189c794586eb959cddbd052c018dd1271100c414dc787b4ba0329845662dfa160820be321894c37dbec74275a546fc3d85ed14ab1de2f4b502de799f027
7
+ data.tar.gz: 5fa0edad8d472981ee79a067100a208249e30f882ab7ec70e0c9858ba9c80931113e2e11a9f1393836dd9d1f8f20c8ab123bc9bf8b47fa2f1628cb2fad4e93ff
data/.cody/README.md CHANGED
@@ -19,6 +19,8 @@ To start a CodeBuild build:
19
19
  cody start --type aws
20
20
  cody start --type azurerm
21
21
  cody start --type google
22
+ cody start --type none
23
+ cody start --type unit
22
24
 
23
25
  To specify a branch:
24
26
 
@@ -3,7 +3,10 @@
3
3
  set -eux
4
4
 
5
5
  mkdir -p ~/.azure
6
- aws secretsmanager get-secret-value --secret-id terraspace/azure-client | jq -r '.SecretString | fromjson' > ~/.azure/app-client.json
6
+
7
+ set +x
8
+ # aws secretsmanager get-secret-value --secret-id terraspace/azure-client | jq -r '.SecretString | fromjson' > ~/.azure/app-client.json
9
+ echo $AZURE_APP_CLIENT_JSON > ~/.azure/app-client.json
7
10
 
8
11
  # ~/.azure/app-client.json
9
12
  export ARM_CLIENT_ID=$(cat ~/.azure/app-client.json | jq -r '.client_id')
@@ -16,6 +19,7 @@ az login --service-principal \
16
19
  --username $ARM_CLIENT_ID \
17
20
  --password $ARM_CLIENT_SECRET \
18
21
  --tenant $ARM_TENANT_ID
22
+ set -x
19
23
 
20
24
  git clone https://github.com/boltops-tools/azure_check.git
21
25
  cd azure_check
@@ -1,2 +1,6 @@
1
1
  github_url("https://github.com/boltops-tools/terraspace.git")
2
2
  linux_image("aws/codebuild/amazonlinux2-x86_64-standard:3.0")
3
+ environment_variables(
4
+ # Used by .cody/azurerm/bin/az/configure.sh
5
+ AZURE_APP_CLIENT_JSON: ssm("/terraspace/#{Cody.env}/azure_app_client_json"),
6
+ )
@@ -1,5 +1,4 @@
1
1
  iam_policy(
2
2
  "logs",
3
- "secretsmanager",
4
3
  "ssm",
5
4
  )
@@ -3,7 +3,8 @@
3
3
  set -eu
4
4
 
5
5
  mkdir -p ~/.gcp
6
- aws secretsmanager get-secret-value --secret-id terraspace/gcloud-credentials | jq '.SecretString | fromjson' > ~/.gcp/credentials.json
6
+ # aws secretsmanager get-secret-value --secret-id terraspace/gcloud-credentials | jq '.SecretString | fromjson' > ~/.gcp/credentials.json
7
+ echo $GOOGLE_CREDS_JSON > ~/.gcp/credentials.json
7
8
 
8
9
  # ~/.gcp/credentials.json
9
10
  export GOOGLE_APPLICATION_CREDENTIALS=~/.gcp/credentials.json
@@ -1,2 +1,6 @@
1
1
  github_url("https://github.com/boltops-tools/terraspace.git")
2
2
  linux_image("aws/codebuild/amazonlinux2-x86_64-standard:3.0")
3
+ environment_variables(
4
+ # Used by .cody/google/bin/gcloud/configure.sh
5
+ GOOGLE_CREDS_JSON: ssm("/terraspace/#{Cody.env}/google_creds_json"),
6
+ )
data/.cody/google/role.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  iam_policy(
2
2
  "logs",
3
- "secretsmanager",
4
3
  "ssm",
5
4
  )
@@ -0,0 +1,15 @@
1
+ #!/bin/bash
2
+
3
+ set -eu
4
+
5
+ # will build from /tmp because terraspace/Gemfile may interfere
6
+ cd /tmp
7
+
8
+ export PATH=~/bin:$PATH # ~/bin/terraspace wrapper
9
+
10
+ set -x
11
+ terraspace new project infra --plugin none --examples
12
+ cd infra
13
+ terraspace new test demo --type stack
14
+ cd app/stacks/demo
15
+ terraspace test
@@ -0,0 +1,10 @@
1
+ version: 0.2
2
+
3
+ phases:
4
+ install:
5
+ runtime-versions:
6
+ ruby: latest
7
+ build:
8
+ commands:
9
+ - .cody/shared/script/install.sh
10
+ - .cody/none/bin/build.sh
@@ -0,0 +1,2 @@
1
+ github_url("https://github.com/boltops-tools/terraspace.git")
2
+ linux_image("aws/codebuild/amazonlinux2-x86_64-standard:3.0")
@@ -0,0 +1,4 @@
1
+ iam_policy(
2
+ "logs",
3
+ "ssm",
4
+ )
@@ -2,10 +2,18 @@
2
2
 
3
3
  set -eu
4
4
 
5
- TERRAFORM_VERSION=0.12.26
5
+ TERRAFORM_VERSION=latest
6
6
 
7
- mkdir /tmp/terraform
8
- cd /tmp/terraform
9
- wget -q https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip
10
- unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip
11
- mv terraform /usr/local/bin
7
+ git clone https://github.com/tfutils/tfenv.git ~/.tfenv
8
+ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
9
+ export PATH="$HOME/.tfenv/bin:$PATH"
10
+ tfenv install $TERRAFORM_VERSION
11
+ tfenv use $TERRAFORM_VERSION
12
+
13
+ # Generate wrapper so dont have to worry about adding .tfenv/bin to PATH in codebuild env
14
+ cat << 'EOL' > /usr/local/bin/terraform
15
+ #!/bin/bash
16
+ export PATH="$HOME/.tfenv/bin:$PATH"
17
+ exec terraform "$@"
18
+ EOL
19
+ chmod +x /usr/local/bin/terraform
@@ -6,4 +6,5 @@ phases:
6
6
  ruby: latest
7
7
  build:
8
8
  commands:
9
+ - .cody/shared/script/install/terraform.sh
9
10
  - .cody/unit/bin/build.sh
@@ -12,6 +12,7 @@ stage "Build" do
12
12
  "terraspace-aws",
13
13
  "terraspace-azurerm",
14
14
  "terraspace-google",
15
+ "terraspace-none",
15
16
  "terraspace-unit",
16
17
  )
17
18
  end
data/CHANGELOG.md CHANGED
@@ -3,6 +3,43 @@
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.7.2] - 2022-01-05
7
+ - [#187](https://github.com/boltops-tools/terraspace/pull/187) put thor cli options at the end
8
+
9
+ ## [0.7.1] - 2022-01-04
10
+ - [#185](https://github.com/boltops-tools/terraspace/pull/185) pass value through untouch when expand method not defined
11
+
12
+ ## [0.7.0] - 2021-12-30
13
+ Highlights:
14
+ - Non-cloud provider support
15
+ - Better passthrough terraspace options to terraform. Pretty much all terraform options are now supported.
16
+ - Remove `terraspace_plugin_*` gem dependencies out of core
17
+ - Improve top CLI help: group main commands at top
18
+
19
+ Details:
20
+ - [#168](https://github.com/boltops-tools/terraspace/pull/168) terraspace new example command
21
+ - [#169](https://github.com/boltops-tools/terraspace/pull/169) fix new plugin generator, use right include Helper
22
+ - [#170](https://github.com/boltops-tools/terraspace/pull/170) remove project --test-structure option in favor of terraspace new test --type project
23
+ - [#171](https://github.com/boltops-tools/terraspace/pull/171) improve cli help: group main commands at top
24
+ - [#172](https://github.com/boltops-tools/terraspace/pull/172) better wrap and pass through terraform args
25
+ - [#173](https://github.com/boltops-tools/terraspace/pull/173) remove `terraspace_plugin_*` gem dependencies out of core
26
+ - [#174](https://github.com/boltops-tools/terraspace/pull/174) support non-cloud providers and backends
27
+ - [#175](https://github.com/boltops-tools/terraspace/pull/175) Pass args cleanup
28
+ - [#176](https://github.com/boltops-tools/terraspace/pull/176) fix new example command
29
+ - [#177](https://github.com/boltops-tools/terraspace/pull/177) Shim message
30
+ - [#178](https://github.com/boltops-tools/terraspace/pull/178) fix no backend.tf src file case
31
+ - [#179](https://github.com/boltops-tools/terraspace/pull/179) terraspace check setup command
32
+ - [#180](https://github.com/boltops-tools/terraspace/pull/180) hide check_setup command
33
+ - [#181](https://github.com/boltops-tools/terraspace/pull/181) generator improvements: core examples for plugin=none. creates simple random_pet
34
+ - [#182](https://github.com/boltops-tools/terraspace/pull/182) move backend auto creation to runner stage
35
+ - [#183](https://github.com/boltops-tools/terraspace/pull/183) fix example generator lang option
36
+ - allow --version command to run outside terraspace project
37
+ - allow terraspace -help to work also
38
+ - friendly shim message for gem dependency resolution errors
39
+
40
+ ## [0.6.23] - 2021-12-18
41
+ - [#167](https://github.com/boltops-tools/terraspace/pull/167) require active_support properly
42
+
6
43
  ## [0.6.22] - 2021-12-16
7
44
  - [#165](https://github.com/boltops-tools/terraspace/pull/165) check if file command is installed
8
45
  - [#166](https://github.com/boltops-tools/terraspace/pull/166) add bundler as a dependency
data/Gemfile CHANGED
@@ -2,3 +2,9 @@ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem dependencies in terraspace.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem "terraspace_plugin_aws"
8
+ gem "terraspace_plugin_azurerm"
9
+ gem "terraspace_plugin_google"
10
+ end
data/README.md CHANGED
@@ -8,18 +8,22 @@
8
8
 
9
9
  [![BoltOps Badge](https://img.boltops.com/boltops/badges/boltops-badge.png)](https://www.boltops.com)
10
10
 
11
- The Terraform Framework.
11
+ [![BoltOps Learn Badge](https://img.boltops.com/boltops-learn/boltops-learn.png)](https://learn.boltops.com)
12
+
12
13
 
13
- Please **watch/star** this repo to help grow and support the project.
14
+ The Terraform Framework.
14
15
 
15
16
  Official Docs Site: [terraspace.cloud](https://terraspace.cloud)
16
17
 
17
- Quick Start Demo:
18
+ ## Support the Project
18
19
 
19
- [![Watch the video](https://img.boltops.com/boltops/tools/terraspace/youtube/terraspace-quick-start.png)](https://www.youtube.com/watch?v=EZfsBJx8pxQ)
20
+ * Please **watch/star** this repo to help grow and support the project.
21
+ * Consider subscribing to [BoltOps Learn](https://learn.boltops.com/). You'll get access to many training videos. Subscribing helps support the project.
20
22
 
21
23
  ## Quick Start
22
24
 
25
+ [![Watch the video](https://img.boltops.com/boltops/tools/terraspace/youtube/terraspace-quick-start.png)](https://learn.boltops.com/courses/terraspace-fundamentals/lessons/terraspace-quick-start)
26
+
23
27
  Here are commands to get started:
24
28
 
25
29
  terraspace new project infra --plugin aws --examples
@@ -0,0 +1,3 @@
1
+ resource "random_pet" "this" {
2
+ length = var.length
3
+ }
@@ -0,0 +1,4 @@
1
+ output "id" {
2
+ description = "Random pet id"
3
+ value = random_pet.this.id
4
+ }
@@ -0,0 +1,5 @@
1
+ variable "length" {
2
+ type = number
3
+ description = "number of words"
4
+ default = 2
5
+ }
@@ -0,0 +1,4 @@
1
+ module "pet" {
2
+ source = "../../modules/example"
3
+ length = var.length
4
+ }
@@ -0,0 +1,4 @@
1
+ output "pet_id" {
2
+ description = "Pet id"
3
+ value = module.pet.id
4
+ }
@@ -0,0 +1,5 @@
1
+ variable "length" {
2
+ type = number
3
+ description = "number of words"
4
+ default = 2
5
+ }
@@ -0,0 +1,3 @@
1
+ resource("random_pet", "this",
2
+ length: var.length
3
+ )
@@ -0,0 +1,4 @@
1
+ output("id",
2
+ description: "Random pet id",
3
+ value: "${random_pet.this.id}",
4
+ )
@@ -0,0 +1,5 @@
1
+ variable("length",
2
+ type: :number,
3
+ description: "number of words",
4
+ default: 2,
5
+ )
@@ -0,0 +1,4 @@
1
+ module!("pet",
2
+ source: "../../modules/example",
3
+ length: var.length,
4
+ )
@@ -0,0 +1,4 @@
1
+ output("pet_id",
2
+ description: "Pet id",
3
+ value: "${module.pet.id}",
4
+ )
@@ -0,0 +1,5 @@
1
+ variable("length",
2
+ type: :number,
3
+ description: "number of words",
4
+ default: 2,
5
+ )
@@ -1,18 +1,10 @@
1
- # This is where you put your backend declaration. Here are some examples:
1
+ # This is where you put your backend declaration. Example:
2
2
  #
3
3
  # terraform {
4
- # backend "s3" {
5
- # bucket = "<%= options[:bucket] || "terraform-state-:ACCOUNT-:REGION-:ENV" %>"
6
- # key = "<%%= expansion(":REGION/:ENV/:BUILD_DIR/terraform.tfstate") %> # IE: us-west-2/dev/ec2/modules/vpc/terraform.tfstate
7
- # region = "<%%= expansion(":REGION") %>"
8
- # encrypt = true
9
- # dynamodb_table = "terraform_locks"
4
+ # backend "local" {
5
+ # path = "terraform.tfstate"
10
6
  # }
11
7
  # }
12
8
  #
13
- # terraform {
14
- # backend "gcs" {
15
- # bucket = "<%= options[:bucket] || "terraform-state-:PROJECT-:REGION-:ENV" %>"
16
- # prefix = "<%%= expansion(":REGION/:ENV/:BUILD_DIR") %>" # IE: us-central1/dev/modules/vm
17
- # }
18
- # }
9
+ # More examples: https://terraspace.cloud/docs/config/backend/examples/
10
+ #
@@ -1,16 +1,6 @@
1
- # This is where you put your provider declaration. Here are some examples:
1
+ # This is where you put your provider declaration.
2
2
  #
3
- # provider "aws" {
4
- # region = "<%= ENV['AWS_REGION'] || 'us-east-1' %>"
5
- # }
3
+ # If you end up adding a cloud provider, you should also configure a terraspace_plugin_* gem
4
+ # in the Terraspace project Gemfile and run bundle.
6
5
  #
7
- # Docs: https://www.terraform.io/docs/providers/aws/index.html
8
- #
9
- # provider "google" {
10
- # project = "REPLACE_ME"
11
- # region = "us-central1" # update to your region
12
- # zone = "us-central1-a" # update to your zone
13
- # }
14
- #
15
- # Docs: https://www.terraform.io/docs/providers/google/index.html
16
- #
6
+ # See: https://terraspace.cloud/docs/plugins/
@@ -0,0 +1,15 @@
1
+ module Terraspace
2
+ class Autodetect
3
+ def plugin
4
+ plugins = Terraspace::Plugin.meta.keys
5
+ if plugins.size == 1
6
+ plugins.first
7
+ else
8
+ precedence = %w[aws azurerm google]
9
+ precedence.find do |p|
10
+ plugins.include?(p)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,6 +1,10 @@
1
1
  require "terraspace/bundle"
2
2
  Terraspace::Bundle.setup
3
- require "zeitwerk"
3
+ begin
4
+ require "zeitwerk"
5
+ rescue LoadError => e
6
+ Terraspace::Bundle.handle_already_activated_error(e)
7
+ end
4
8
 
5
9
  module Terraspace
6
10
  # These modules are namespaces for user-defined custom helpers
@@ -38,3 +42,4 @@ module Terraspace
38
42
  end
39
43
  end
40
44
  end
45
+
@@ -8,7 +8,7 @@ module Terraspace
8
8
 
9
9
  def run
10
10
  return if @options[:build] == false
11
- Terraspace::CLI::CheckSetup.check!
11
+ Terraspace::CLI::Setup::Check.check!
12
12
  @mod.root_module = true
13
13
  clean
14
14
  build_dir = Util.pretty_path(@mod.cache_dir)
@@ -20,7 +20,6 @@ module Terraspace
20
20
  run_hooks("terraspace.rb", "build") do
21
21
  check_allow!
22
22
  build_unresolved
23
- auto_create_backend
24
23
  batches = build_batches
25
24
  build_all
26
25
  logger.info "Built in #{build_dir}" unless @options[:quiet] # from terraspace all
@@ -66,13 +65,6 @@ module Terraspace
66
65
  end
67
66
  end
68
67
 
69
- # Auto create after build_unresolved since will need to run state pull for dependencies
70
- def auto_create_backend
71
- return if Terraspace.config.auto_create_backend == false
72
- return unless requires_backend?
73
- Terraspace::Compiler::Backend.new(@mod).create
74
- end
75
-
76
68
  def clean
77
69
  Compiler::Cleaner.new(@mod, @options).clean if clean?
78
70
  end
@@ -55,6 +55,60 @@ module Terraspace
55
55
  [:default, Terraspace.env.to_sym]
56
56
  end
57
57
 
58
+ # When there are gem dependency issues, requiring zeitwerk with this debugging code
59
+ # begin
60
+ # require "zeitwerk"
61
+ # rescue LoadError => e
62
+ # puts "#{e.class}: #{e.message}"
63
+ # exit 1
64
+ # end
65
+ #
66
+ # Produces:
67
+ #
68
+ # You have already activated faraday 1.8.0, but your Gemfile requires faraday 1.7.2. Prepending `bundle exec` to your command may solve this.
69
+ # LoadError: cannot load such file -- zeitwerk
70
+ #
71
+ # Sadly, the captured exception only contains this info:
72
+ #
73
+ # LoadError: cannot load such file -- zeitwerk
74
+ #
75
+ # The useful "already activated" info that shows gem dependencies issues. Example:
76
+ #
77
+ # You have already activated faraday 1.8.0, but your Gemfile requires faraday 1.7.2. Prepending `bundle exec` to your command may solve this.
78
+ #
79
+ # Is printed to stdout earlier and before exception.
80
+ #
81
+ # So making an assumption that a zeitwerk LoadError is due to gem dependencies issue.
82
+ # It's not ideal, but think this is ok.
83
+ #
84
+ # Note: Not checking shim upon install because it wont be a good user experience
85
+ # to check for a shim unless this error actually occurs.
86
+ #
87
+ # Only been able to reproduce this error for a gem install with: alpine
88
+ # The standalone install already has a shim wrapper.
89
+ #
90
+ def handle_already_activated_error(e)
91
+ # color is not yet available
92
+ puts "ERROR: #{e.class}: #{e.message}" if ENV['TS_DEBUG_ALREADY_ACTIVATED']
93
+ check_shim!
94
+ exit 1
95
+ end
96
+
97
+ def check_shim!
98
+ return unless File.exist?("Gemfile")
99
+ $stderr.puts <<~EOL
100
+ Looks like there are issues trying to resolve gem dependencies.
101
+
102
+ To resolve this, you can generate a shim:
103
+
104
+ terraspace new shim
105
+
106
+ You only have to do this one time.
107
+
108
+ More info: https://terraspace.cloud/docs/install/shim/
109
+ EOL
110
+ end
111
+
58
112
  extend self
59
113
  end
60
114
  end
@@ -0,0 +1,113 @@
1
+ class Terraspace::CLI
2
+ module Concern
3
+ extend ActiveSupport::Concern
4
+
5
+ class_methods do
6
+ # So the Thor::Parser::Options#parse allows flag switch shorthand notation. IE:
7
+ #
8
+ # command -abc
9
+ #
10
+ # Is same as:
11
+ #
12
+ # command -a -b -c
13
+ #
14
+ # This messes up the options like -destroy.
15
+ #
16
+ # terraspace plan -destroy
17
+ #
18
+ # Since only a single dash (-) is passed. It's interpreted as a bunch of flag switches.
19
+ # Providing -- works just fine
20
+ #
21
+ # terraspace plan --destroy
22
+ #
23
+ # But it'll be nice if user can use -destroy or --destroy
24
+ #
25
+ # Interestingly, -no-color won't be interpreted by Thor as switch flag due to the - inbetween.
26
+ #
27
+ # Looked into the Thor code:
28
+ #
29
+ # Thor::Parser::Options#parse https://github.com/rails/thor/blob/5c666b4c25e748e57eec2d529d94c5059030979e/lib/thor/parser/options.rb#L88
30
+ # Thor::Parser::Options#current_is_switch? https://github.com/rails/thor/blob/5c666b4c25e748e57eec2d529d94c5059030979e/lib/thor/parser/options.rb#L165
31
+ #
32
+ # Overriding the current_is_switch? is dirtier than overriding start
33
+ # and adjusting the argv before passing to Thor.
34
+ #
35
+ # There are only so few Terraform boolean options that are single words. To find (fish shell)
36
+ #
37
+ # for i in init validate plan apply destroy console fmt force-unlock get graph import login logout output providers refresh show state taint test untaint version workspace ; echo "$i:" ; terraform $i -h | grep '^ -' ; end
38
+ # for i in init validate plan apply destroy console fmt force-unlock get graph import login logout output providers refresh show state taint test untaint version workspace ; echo "$i:" ; terraform $i -h | grep '^ -' | grep -v = | sed 's/ -//' | grep -v - | sed -r 's/\s+.*//' | sed 's/^/ /' ; end
39
+ # for i in init validate plan apply destroy console fmt force-unlock get graph import login logout output providers refresh show state taint test untaint version workspace ; terraform $i -h | grep '^ -' | grep -v = | sed 's/ -//' | grep -v - | sed -r 's/\s+.*//' ; end | sort | uniq
40
+ #
41
+ def start(argv)
42
+ # Note: help is for terraspace -help
43
+ single_word_boolean_args = %w[
44
+ check
45
+ destroy
46
+ diff
47
+ force
48
+ help
49
+ json
50
+ raw
51
+ reconfigure
52
+ recursive
53
+ upgrade
54
+ ]
55
+ args = single_word_boolean_args.map { |s| "-#{s}" }
56
+ argv.map! do |arg|
57
+ if args.include?(arg)
58
+ # Ensure double dash (--).
59
+ # Later in Terraspace::Terraform::Args::Pass#args a single dash (-) is ensured.
60
+ "-#{arg}" # IE: -destroy => --destroy
61
+ else
62
+ arg
63
+ end
64
+ end
65
+ super(argv)
66
+ end
67
+
68
+ def main_commands
69
+ %w[
70
+ all
71
+ build
72
+ bundle
73
+ down
74
+ list
75
+ new
76
+ plan
77
+ seed
78
+ up
79
+ ]
80
+ end
81
+
82
+ def help(shell, subcommand)
83
+ list = printable_commands(true, subcommand)
84
+ list.sort! { |a, b| a[0] <=> b[0] }
85
+ filter = Proc.new do |command, desc|
86
+ main_commands.detect { |name| command =~ Regexp.new("^terraspace #{name}") }
87
+ end
88
+ main = list.select(&filter)
89
+ other = list.reject(&filter)
90
+
91
+ shell.say <<~EOL
92
+ Usage: terraspace COMMAND [args]
93
+
94
+ The available commands are listed below.
95
+ The primary workflow commands are given first, followed by
96
+ less common or more advanced commands.
97
+ EOL
98
+ shell.say "\nMain Commands:\n\n"
99
+ shell.print_table(main, indent: 2, truncate: true)
100
+ shell.say "\nOther Commands:\n\n"
101
+ shell.print_table(other, indent: 2, truncate: true)
102
+ shell.say <<~EOL
103
+
104
+ For more help on each command, you can use the -h option. Example:
105
+
106
+ terraspace up -h
107
+
108
+ CLI Reference also available at: https://terraspace.cloud/reference/
109
+ EOL
110
+ end
111
+ end
112
+ end
113
+ end
@@ -1,8 +1,14 @@
1
1
  ## Example
2
2
 
3
- => Creating test for new module: example
3
+ $ terraspace new example
4
+ => Creating new module called example
4
5
  create app/modules/example
5
6
  create app/modules/example/main.tf
6
7
  create app/modules/example/outputs.tf
7
8
  create app/modules/example/variables.tf
9
+ => Creating new stack called demo
10
+ create app/stacks/demo
11
+ create app/stacks/demo/main.tf
12
+ create app/stacks/demo/outputs.tf
13
+ create app/stacks/demo/variables.tf
8
14
  $
@@ -1,11 +1,10 @@
1
1
  class Terraspace::CLI
2
- class Help
3
- class << self
4
- def text(namespaced_command)
5
- path = namespaced_command.to_s.gsub(':','/')
6
- path = File.expand_path("../help/#{path}.md", __FILE__)
7
- IO.read(path) if File.exist?(path)
8
- end
2
+ module Help
3
+ def text(namespaced_command)
4
+ path = namespaced_command.to_s.gsub(':','/')
5
+ path = File.expand_path("../help/#{path}.md", __FILE__)
6
+ IO.read(path) if File.exist?(path)
9
7
  end
8
+ extend self
10
9
  end
11
- end
10
+ end