Skip to content

Commit

Permalink
Merge pull request #14 from YakDriver/make-env
Browse files Browse the repository at this point in the history
Add functionality to generate a .env file
  • Loading branch information
YakDriver authored Jun 22, 2019
2 parents 303491c + c505cbb commit 2e04041
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.3.0
current_version = 0.4.0
commit = False
tag = False
tag_name = {new_version}
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGE LOG

## 0.4.0 - 2019.06.21

* Add feature to generate dot-env (`.env`) file

## 0.3.0 - 2019.04.25

* Add functionality to check existing `main.tf` and `variables.tf` for missing variables
Expand Down
72 changes: 54 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,26 @@

Terraform module development tool.

1. Extract variables from `main.tf` and create `variables.tf` files
1. Extract variables from `main.tf` and generate a `variables.tf` file
1. Find missing variables in `variables.tf` and `main.tf` based on each other
1. Create a module use stub from a `variables.tf` file
1. Generate a module use stub from a `variables.tf` file
1. Generate a .env file with variables from `main.tf`
1. Delete extra *scratchrelaxtv* files

# install

```
pip install scratchrelaxtv
```

# tip

Once installed, you can just type "relaxtv."

# workflows

Here are two example workflows using *scratchrelaxtv*.

**Original module development**:
1. Write `main.tf` with whatever variables you need
1. Run *scratchrelaxtv* to generate `variables.tf`
Expand All @@ -32,17 +45,11 @@ Terraform module development tool.
1. Fill in descriptions, defaults, etc. in `variables.tf` for newly added vars
1. Run `terraform fmt` to prettify everything

# install

```
pip install scratchrelaxtv
```

# examples

## generate `variables.tf`
## example: generate `variables.tf`

By default, *scratchrelaxtv* looks for `main.tf` and will generate a `variables.tf` file. Variables will be in the same order in `variables.tf` as they were in `main.tf`. There are options to sort variables. You can `--force` to overwrite an existing `variables.tf` file. Otherwise, *scratchrelaxtv* will create new `variables.tf` files with each run: `variables.1.tf`, `variables.2.tf` and so on.
By default, *scratchrelaxtv* looks for `main.tf` and will generate a `variables.tf` file. Variables will be in the same order in `variables.tf` as they were in `main.tf`. There are options to sort variables. You can `--force` to overwrite an existing `variables.tf` file. Otherwise, *scratchrelaxtv* will generate new `variables.tf` files with each run: `variables.1.tf`, `variables.2.tf` and so on.

Assume this `main.tf`:
```hcl
Expand All @@ -56,7 +63,7 @@ resource "aws_s3_bucket" "this" {
Run *scratchrelaxtv*:
```console
$ scratchrelaxtv
2019-04-26 08:02:54,011 - INFO - creating variables.tf file
2019-04-26 08:02:54,011 - INFO - generating variables file
2019-04-26 08:02:54,011 - INFO - input file: main.tf
2019-04-26 08:02:54,011 - INFO - output file: variables.tf
2019-04-26 08:02:54,011 - INFO - not forcing overwrite of output file
Expand Down Expand Up @@ -84,7 +91,7 @@ variable "region" {
}
```

## Find and fix missing variables
## example: find and fix missing variables

Assume you already have a `main.tf` and a `variables.tf`. In this example, the `variables.tf` is missing the `region` variable.

Expand Down Expand Up @@ -133,9 +140,9 @@ variable "region" {
}
```

## Create a stub for using the module
## example: generate a stub for using the module

By default, when creating a stub, *scratchrelaxtv* looks for `variables.tf`.
By default, when generating a stub, *scratchrelaxtv* looks for `variables.tf`.

Assume this `variables.tf`:
```hcl
Expand All @@ -161,7 +168,7 @@ variable "region" {
Run *scratchrelaxtv* with the module stub option:
```console
$ scratchrelaxtv -m
2019-04-26 08:09:27,147 - INFO - creating module usage stub
2019-04-26 08:09:27,147 - INFO - generating module usage stub
2019-04-26 08:09:27,147 - INFO - input file: variables.tf
2019-04-26 08:09:27,147 - INFO - output file: modstub.tf
2019-04-26 08:09:27,147 - INFO - not forcing overwrite of output file
Expand All @@ -183,8 +190,36 @@ module "tests2" {
}
```

## example: generate a `.env` (dotenv) file

By default, when generating a `.env` file, *scratchrelaxtv* looks for `variables.tf`.

Assume this `variables.tf`:
```hcl
resource "aws_s3_bucket" "this" {
bucket = "${var.bucket}"
region = "${var.region}"
}
```

Run *scratchrelaxtv* with the generate `.env` and sort-ascending options:
```console
$ scratchrelaxtv -ea
2019-06-21 20:01:35,362 - INFO - generating .env file
2019-06-21 20:01:35,362 - INFO - input file: main.tf
2019-06-21 20:01:35,362 - INFO - output file: .env
2019-06-21 20:01:35,362 - INFO - not forcing overwrite of output file
2019-06-21 20:01:35,362 - INFO - ordering output file ascending
```

The generated `.env`:
```bash
unset "${!TF_VAR_@}"
TF_VAR_bucket=replace
TF_VAR_region=replace
```

## remove files
## example: remove files

```console
$ scratchrelaxtv -r
Expand Down Expand Up @@ -213,7 +248,7 @@ $ scratchrelaxtv -r
```console
$ scratchrelaxtv --help
usage: scratchrelaxtv [-h] [-i INPUT] [-o OUTPUT] [-f] [-m] [-n MODNAME] [-r]
[-c] [-a | -d]
[-c] [-e] [-a | -d]

optional arguments:
-h, --help show this help message and exit
Expand All @@ -222,11 +257,12 @@ optional arguments:
-o OUTPUT, --output OUTPUT
file to write extracted vars to
-f, --force overwrite existing out file
-m, --modstub create module usage stub
-m, --modstub generate module usage stub
-n MODNAME, --modname MODNAME
name to use in module stub
-r, --remove remove all modstub.tf, variables.#.tf files
-c, --check check that all vars are listed
-e, --env generate .env with Terraform vars
-a, --asc sort output variables in ascending order
-d, --desc sort output variables in descending order
```
5 changes: 0 additions & 5 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# Python package
# Create and test a Python package on multiple Python versions.
# Add steps that analyze code, save the dist with the build record, publish to a PyPI-compatible index, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/python

trigger:
- master

Expand Down
47 changes: 42 additions & 5 deletions scratchrelaxtv/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
tool. Use it to:
* extract vars from HCL and generate an HCL variables file;
* generate a module-use stub file;
* delete files created by scratchrelaxtv; and
* delete files generated by scratchrelaxtv; and
* check whether existing files include all the variables used.
Example:
Expand All @@ -20,7 +20,7 @@
import re


__version__ = "0.3.0"
__version__ = "0.4.0"
EXIT_OKAY = 0
EXIT_NOT_OKAY = 1

Expand Down Expand Up @@ -65,13 +65,15 @@ def __init__(self, args):
def log_arguments(self):
"""Log all the attributes of this run."""
if self.args.modstub:
logger.info("creating module usage stub")
logger.info("generating module usage stub")
elif self.args.remove:
logger.info("attempting removal of files")
elif self.args.check:
logger.info("checking for missing variables")
elif self.args.env:
logger.info("generating .env file")
else:
logger.info("creating variables.tf file")
logger.info("generating variables file")

logger.info("input file: %s", self.args.input)
logger.info("output file: %s", self.args.output)
Expand Down Expand Up @@ -192,7 +194,7 @@ def extract(self):

class StubMaker(BassExtractor):
"""
A class that extracts variables from Terraform HCL files and creates a
A class that extracts variables from Terraform HCL files and generates a
module-use stub.
"""
def __init__(self, args):
Expand Down Expand Up @@ -236,6 +238,41 @@ def extract(self):
return EXIT_OKAY


class EnvGenerator(BassExtractor):
"""
A class that extracts variables from Terraform HCL files and generates a
.env file.
"""
def __init__(self, args):
"""Instantiate"""
# defaults
if not args.input:
args.input = "main.tf"

if not args.output:
args.output = ".env"

super().__init__(args)

def write_file(self):
"""Output vars to .env file."""
self._find_non_existing_filename()
with open(self.args.output, "w", encoding='utf_8') as file_handle:
file_handle.write('unset "${!TF_VAR_@}"\n')
for tf_var in self.tf_vars:
file_handle.write("".join([
'TF_VAR_',
tf_var,
"=replace\n"]))

def extract(self):
"""Extract vars from .tf file."""
self.find_vars_in_file(self.main_phrase_find, self.main_token_find)
self.write_file()

return EXIT_OKAY


class Checker(BassExtractor):
"""
A class that extracts variables from Terraform HCL files and checks them.
Expand Down
13 changes: 9 additions & 4 deletions scratchrelaxtv/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
"""scratchrelaxtv command line interface (CLI).
scratchrelaxtv (anagram of extract-hcl-vars) is a Terraform development
convenience tool that extracts vars from HCL and creates an HCL variables file
with the extracted vars. The point is to make creating Terraform modules
convenience tool that extracts vars from HCL and generates an HCL variables
file with the extracted vars. The point is to make creating Terraform modules
easier.
Running scratchrelaxtv without any options reads a main.tf, extracts the vars
from that file, and creates a variables.tf file with those variables.
from that file, and generates a variables.tf file with those variables.
Options include:
-i, -o changing input/output file names
Expand All @@ -28,14 +28,17 @@ def parse_args(args):
help="file to write extracted vars to")
parser.add_argument("-f", "--force", default=False, action="store_true",
help="overwrite existing out file")

task = parser.add_mutually_exclusive_group()
task.add_argument("-m", "--modstub", default=False, action="store_true",
help="create module usage stub")
help="generate module usage stub")
parser.add_argument("-n", "--modname", help="name to use in module stub")
task.add_argument("-r", "--remove", default=False, action="store_true",
help="remove all modstub.tf, variables.#.tf files")
task.add_argument("-c", "--check", default=False, action="store_true",
help="check that all vars are listed")
task.add_argument("-e", "--env", default=False, action="store_true",
help="generate .env with Terraform vars")

sort_order = parser.add_mutually_exclusive_group()
sort_order.add_argument("-a", "--asc", action="store_true",
Expand All @@ -58,6 +61,8 @@ def main():
extractor = scratchrelaxtv.StubMaker(args)
elif args.check:
extractor = scratchrelaxtv.Checker(args)
elif args.env:
extractor = scratchrelaxtv.EnvGenerator(args)
else:
extractor = scratchrelaxtv.VarExtractor(args)

Expand Down
6 changes: 3 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[metadata]
name = scratchrelaxtv
description = Terraform developer tool to extract variables and create variables.tf files.
description = Terraform developer tool to extract variables and generate variables.tf files.
long_description = file: README.md, CHANGELOG.md
long_description_content_type = text/markdown
version = 0.3.0
version = 0.4.0
author = YakDriver
author_email = [email protected]
url = https://github.com/YakDriver/scratchrelaxtv
Expand Down Expand Up @@ -36,7 +36,7 @@ include_package_data = True
[options.entry_points]
console_scripts =
scratchrelaxtv = scratchrelaxtv.cli:main
hclextract = scratchrelaxtv.cli:main
relaxtv = scratchrelaxtv.cli:main

[bdist_wheel]
universal = 1
Expand Down
11 changes: 11 additions & 0 deletions tests/.env.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
unset "${!TF_VAR_@}"
TF_VAR_acl=replace
TF_VAR_bucket=replace
TF_VAR_create_2=replace
TF_VAR_create_keystore_bucket=replace
TF_VAR_org_ids=replace
TF_VAR_prefix=replace
TF_VAR_problem_var=replace
TF_VAR_region=replace
TF_VAR_tags=replace
TF_VAR_versioning=replace
24 changes: 22 additions & 2 deletions tests/test_scratchrelaxtv.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

import os
from contextlib import contextmanager
from scratchrelaxtv import cli, Checker, StubMaker, VarExtractor, EXIT_OKAY,\
remove_files
from scratchrelaxtv import cli, Checker, StubMaker, VarExtractor,\
EnvGenerator, EXIT_OKAY, remove_files


@contextmanager
Expand Down Expand Up @@ -140,3 +140,23 @@ def test_check():

assert len(missing['main']) == 1 and missing['main'][0] == "create"
assert len(missing['var']) == 1 and missing['var'][0] == "extra_var"


def test_gen_env():
"""Test extracting variables."""
with change_dir("tests"):
filename = ".env.2"
if os.path.isfile(filename):
os.remove(filename)

args = cli.parse_args(["-fea", "-o", filename])

extractor = EnvGenerator(args)

assert extractor.extract() == EXIT_OKAY
with open(".env.1", "r", encoding='utf_8') as file_handle:
first_list = file_handle.read().splitlines()
with open(filename, "r", encoding='utf_8') as file_handle:
second_list = file_handle.read().splitlines()
assert first_list == second_list
os.remove(filename)

0 comments on commit 2e04041

Please sign in to comment.