Skip to content

Commit 6a44fe5

Browse files
authored
Merge pull request #50 from TangRufus/dotenv
Add `dotenv` command
2 parents 5ac98b4 + b5856b3 commit 6a44fe5

File tree

9 files changed

+440
-5
lines changed

9 files changed

+440
-5
lines changed

.circleci/config.yml

+25-1
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,34 @@ jobs:
1010
- restore_cache:
1111
keys:
1212
- go-mod-v1-{{ checksum "go.sum" }}
13-
- run: go test -v ./...
13+
- run: go test -v -short ./...
1414
- save_cache:
1515
key: go-mod-v1-{{ checksum "go.sum" }}
1616
paths:
1717
- /go/pkg/mod
18+
19+
integration-test:
20+
docker:
21+
- image: rootsdev/trellis-cli-dev
22+
steps:
23+
- run: go version
24+
- run: ansible --version
25+
- run:
26+
name: Trellis version
27+
command: git log -1 --format="%h %s %aD"
28+
working_directory: /test/dummy/trellis
29+
- checkout
30+
- restore_cache:
31+
keys:
32+
- go-mod-v1-{{ checksum "go.sum" }}
33+
- run: make test RUN=
34+
- save_cache:
35+
key: go-mod-v1-{{ checksum "go.sum" }}
36+
paths:
37+
- /go/pkg/mod
38+
- store_artifacts:
39+
path: /test/trellis-cli
40+
1841
release:
1942
docker:
2043
- image: circleci/golang:1.12
@@ -27,6 +50,7 @@ workflows:
2750
test:
2851
jobs:
2952
- test
53+
- integration-test
3054
- release:
3155
filters:
3256
branches:

Dockerfile

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# This docker image is for integration testing only.
2+
3+
FROM golang:1.12-buster
4+
5+
ARG DEBIAN_FRONTEND=noninteractive
6+
7+
ENV TEST_BINARY=/test/trellis-cli
8+
ENV TEST_DUMMY=/test/dummy
9+
10+
WORKDIR /app
11+
12+
# CircleCI
13+
# https://circleci.com/docs/2.0/custom-images/
14+
RUN apt-get -q update && \
15+
apt-get install -q -y --no-install-recommends git openssh-client openssh-server tar gzip && \
16+
apt-get clean && apt-get -y autoremove && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
17+
18+
# Ansible
19+
# https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#latest-releases-via-apt-debian
20+
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367 && \
21+
echo "deb http://ppa.launchpad.net/ansible/ansible-2.7/ubuntu trusty main" | tee -a /etc/apt/sources.list && \
22+
apt-get -q update && \
23+
apt-get install -q -y --no-install-recommends ansible && \
24+
apt-get clean && apt-get -y autoremove && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
25+
26+
# Trellis
27+
RUN git clone https://github.com/roots/trellis.git "${TEST_DUMMY}/trellis" && \
28+
cd "${TEST_DUMMY}/trellis" && \
29+
ansible-galaxy install -r requirements.yml
30+
31+
# Bedrock
32+
RUN mkdir -p "${TEST_DUMMY}/site" && \
33+
touch "${TEST_DUMMY}/site/.keep"
34+
35+
RUN go version && \
36+
ansible --version && \
37+
echo "Trellis commit: " && cd "${TEST_DUMMY}/trellis" && git log -1 --format="%h %s %aD"

Makefile

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
DOCKER_NAME=rootsdev/trellis-cli-dev
2+
DOCKER_RUN=docker run --rm -it -v $(shell pwd):/app -v $(GOPATH):/go
3+
RUN=$(DOCKER_RUN) $(DOCKER_NAME)
4+
5+
.PHONY: docker docker-no-cache
6+
docker:
7+
docker build -t $(DOCKER_NAME) .
8+
docker-no-cache:
9+
docker build -t $(DOCKER_NAME) --no-cache .
10+
11+
.PHONY: shell
12+
shell:
13+
$(RUN) bash
14+
15+
.PHONY: test
16+
test:
17+
$(RUN) sh -c 'go build -v -o $$TEST_BINARY && go test -v ./...'

README.md

+37-4
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,43 @@ Supported commands so far:
4949

5050
trellis-cli requires Go 1.11+ since it uses Go modules.
5151

52-
1. Make sure Go 1.11+ is installed (`brew install go` on macOS)
53-
2. Clone the repo
54-
3. Run `go build`
55-
4. To run tests: `go test -v ./...`
52+
Make sure Go 1.11+ is installed (`brew install go` on macOS)
53+
54+
```bash
55+
# Clone the repo
56+
git clone https://github.com/roots/trellis-cli
57+
cd trellis-cli
58+
59+
# Build the binary for your machine
60+
go build
61+
62+
# Run tests (without integration tests)
63+
go test -v -short ./...
64+
65+
# (Optional) Build the docker image for testing (requires `docker`)
66+
make docker
67+
# Alternatively, do not use cache when building the doccker image (requires `docker`)
68+
make docker-no-cache
69+
70+
# Run all tests (requires `docker`)
71+
make test
72+
```
73+
74+
## Releasing Docker Images
75+
76+
*This section only intended for the maintainers*
77+
78+
```bash
79+
make docker
80+
81+
# docker tag rootsdev/trellis-cli-dev:latest rootsdev/trellis-cli-dev:YYYY.MM.DD.N
82+
# where N is a sequential integer, starting from 1.
83+
docker tag rootsdev/trellis-cli-dev:latest rootsdev/trellis-cli-dev:2019.08.12.1
84+
85+
# docker push rootsdev/trellis-cli-dev:YYYY.MM.DD.N
86+
docker push rootsdev/trellis-cli-dev:2019.08.12.1
87+
docker push rootsdev/trellis-cli-dev:latest
88+
```
5689

5790
## Contributing
5891

cmd/dot_env.go

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"log"
7+
"os"
8+
"os/exec"
9+
"path"
10+
"runtime"
11+
"strings"
12+
13+
"github.com/mitchellh/cli"
14+
"trellis-cli/trellis"
15+
)
16+
17+
type DotEnvCommand struct {
18+
UI cli.Ui
19+
Trellis *trellis.Trellis
20+
}
21+
22+
func copyPlaybook(source string, destination string) {
23+
b, readFileErr := ioutil.ReadFile(source)
24+
if readFileErr != nil {
25+
log.Fatal(readFileErr)
26+
}
27+
28+
writeFileErr := ioutil.WriteFile(destination, b, 0644)
29+
if writeFileErr != nil {
30+
log.Fatal(writeFileErr)
31+
}
32+
}
33+
34+
func deletePlaybook(path string) {
35+
err := os.Remove(path)
36+
37+
if err != nil {
38+
log.Fatal(err)
39+
}
40+
}
41+
42+
func appendEnvironmentVariable(cmd *exec.Cmd, elem string) {
43+
env := os.Environ()
44+
// To allow mockExecCommand injects its environment variables
45+
if cmd.Env != nil {
46+
env = cmd.Env
47+
}
48+
cmd.Env = append(env, elem)
49+
}
50+
51+
func (c *DotEnvCommand) Run(args []string) int {
52+
if err := c.Trellis.LoadProject(); err != nil {
53+
c.UI.Error(err.Error())
54+
return 1
55+
}
56+
57+
var environment string
58+
59+
switch len(args) {
60+
case 0:
61+
environment = "development"
62+
case 1:
63+
environment = args[0]
64+
default:
65+
c.UI.Error(fmt.Sprintf("Error: too many arguments (expected 0 or 1, got %d)\n", len(args)))
66+
c.UI.Output(c.Help())
67+
return 1
68+
}
69+
70+
_, ok := c.Trellis.Environments[environment]
71+
if !ok {
72+
c.UI.Error(fmt.Sprintf("Error: %s is not a valid environment", environment))
73+
return 1
74+
}
75+
76+
// Copy playbook file from package to Trellis
77+
_, filename, _, ok := runtime.Caller(0)
78+
playbookTemplatePath := path.Join(path.Dir(filename), "../playbooks/dotenv.yml")
79+
playbookPath := "dotenv.yml"
80+
copyPlaybook(playbookTemplatePath, playbookPath)
81+
defer deletePlaybook(playbookPath)
82+
83+
dotEnv := execCommand("ansible-playbook", "dotenv.yml", "-e", "env=" + environment)
84+
appendEnvironmentVariable(dotEnv, "ANSIBLE_RETRY_FILES_ENABLED=false")
85+
86+
logCmd(dotEnv, c.UI, true)
87+
runErr := dotEnv.Run()
88+
89+
if runErr != nil {
90+
c.UI.Error(fmt.Sprintf("Error running ansible-playbook: %s", runErr))
91+
return 1
92+
}
93+
94+
return 0
95+
}
96+
97+
func (c *DotEnvCommand) Synopsis() string {
98+
return "Template .env files to local system"
99+
}
100+
101+
func (c *DotEnvCommand) Help() string {
102+
helpText := `
103+
Usage: trellis dotenv [options] [ENVIRONMENT=development]
104+
105+
Template .env files to local system
106+
107+
Options:
108+
-h, --help show this help
109+
`
110+
111+
return strings.TrimSpace(helpText)
112+
}

0 commit comments

Comments
 (0)