Skip to content

Commit

Permalink
feat: Implement envdef.
Browse files Browse the repository at this point in the history
  • Loading branch information
locona committed Mar 13, 2020
1 parent 26561bc commit 0544c47
Show file tree
Hide file tree
Showing 16 changed files with 6,843 additions and 0 deletions.
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export GO111MODULE=on
25 changes: 25 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Release
on:
push:
# Sequence of patterns matched against refs/heads
branches:
- 'release/**' # Push events to branches matching refs/heads/releases/10

jobs:
release:
name: Release
runs-on: ubuntu-18.04
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 12
- name: Install dependencies
run: npm ci
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
59 changes: 59 additions & 0 deletions .github/workflows/reviewdog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: reviewdog on Pull Request
on: [pull_request]
jobs:
golangci-lint:
name: runner / golangci-lint
runs-on: ubuntu-latest
steps:
- name: set up
uses: actions/setup-go@v1
with:
go-version: 1.12
id: go

- name: Add $GOPATH/bin
run: |
echo ::add-path::$(go env GOPATH)/bin
- name: Check out code into the Go module directory
uses: actions/checkout@v1

# cache store
- name: cache
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: download modules
# キャッシュが保存されていればそれを使う
if: steps.cache.outputs.cache-hit != 'true'
run: go mod download

- name: Setup reviewdog
run: |
curl -sfL https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh| sh -s -- -b $(go env GOPATH)/bin
- name: install lint
run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.18.0

- name: Run reviewdog
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
golangci-lint run --out-format line-number --enable-all --exclude-use-default=false -c=./.golangci.yml \
| reviewdog -f=golangci-lint -name="golangci-lint" -reporter="github-check"
misspell:
name: runner / misspell
runs-on: ubuntu-latest
steps:
- name: Check out code.
uses: actions/checkout@v1
- name: misspell
uses: reviewdog/action-misspell@v1
with:
github_token: ${{ secrets.github_token }}
reporter: github-check
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
31 changes: 31 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
linters-settings:
golint:
# minimal confidence for issues, default is 0.8
min-confidence: 1.1

lll:
line-length: 150

funlen:
lines: 200
statements: 120

linters:
disable:
- gochecknoinits
- gocyclo
- godox
- gocognit
- maligned
- dupl
- gochecknoglobals

issues:
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
# excluded by default patterns execute `golangci-lint run --help`
exclude:
- should have comment or be unexported
- ST1000
- ST1003
58 changes: 58 additions & 0 deletions .releaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"branches": [{name: "release/v*"}],
"plugins": [
["@semantic-release/commit-analyzer", {
"preset": "conventionalcommits",
"releaseRules": [
{breaking: true, release: 'major'},
{revert: true, release: 'patch'},
{type: 'feat', release: 'minor'},
{type: 'fix', release: 'patch'},
{type: "improvement", release: "patch"},
{type: 'docs', release: 'patch'},
{type: 'perf', release: 'patch'},
{type: 'refactor', release: 'patch'},
],
"presetConfig": {
"types": [
{"type": "feat", "section": "New Features", "hidden": false},
{"type": "fix", "section": "Bug Fixes", "hidden": false},
{"type": "improvement", "section": "Improvement", "hidden": false},
{"type": "docs", "section": "Docs", "hidden": false},
{"type": "perf", "section": "Performance", "hidden": false},
{"type": "refactor", "section": "Refactor", "hidden": false}
]
}
}],
["@semantic-release/release-notes-generator", {
"preset": "conventionalcommits",
"releaseRules": [
{breaking: true, release: 'major'},
{revert: true, release: 'patch'},
{type: 'feat', release: 'minor'},
{type: 'fix', release: 'patch'},
{type: "improvement", release: "patch"},
{type: 'docs', release: 'patch'},
{type: 'perf', release: 'patch'},
{type: 'refactor', release: 'patch'},
],
"presetConfig": {
"types": [
{"type": "feat", "section": "New Features", "hidden": false},
{"type": "fix", "section": "Bug Fixes", "hidden": false},
{"type": "improvement", "section": "Improvement", "hidden": false},
{"type": "docs", "section": "Docs", "hidden": false},
{"type": "perf", "section": "Performance", "hidden": false},
{"type": "refactor", "section": "Refactor", "hidden": false}
]
}
}],
"@semantic-release/changelog",
"@semantic-release/github",
["@semantic-release/git", {
"message": "chore(release): ${nextRelease.version} [skip semantic-release]"
}]
]
}


29 changes: 29 additions & 0 deletions cmd/envdef.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"flag"
"log"

"github.com/locona/envdef"
)

var (
defaultSource = ".env.sample"
defaultDist = ".env"
)

func main() {
var source string
flag.StringVar(&source, "s", defaultSource, "source .env file")
var dist string
flag.StringVar(&dist, "d", defaultDist, "distribution .env file")
flag.Parse()

result, err := envdef.Diff(source, dist)
if err != nil {
log.Fatal(err)
}

result.Write()
result.Print()
}
65 changes: 65 additions & 0 deletions envdef.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package envdef

import (
"fmt"

"github.com/joho/godotenv"
)

var iconFormat = "%v %v"
var envFormat = "%v=%v"

func Diff(source, dist string) (*Result, error) {
var insertSlice InsertSlice
var updateSlice UpdateSlice
var deleteSlice DeleteSlice
var noChangeSlice NoChangeSlice

sourceEnv, err := Read(source)
if err != nil {
return nil, err
}

distEnv, err := Read(dist)
if err != nil {
return nil, err
}

for k, v := range sourceEnv {
// update
if _, ok := distEnv[k]; ok {
if v != distEnv[k] {
updateSlice = append(updateSlice, fmt.Sprintf(envFormat, k, v))
continue
}

noChangeSlice = append(noChangeSlice, fmt.Sprintf(envFormat, k, v))
continue
}

// insert
insertSlice = append(insertSlice, fmt.Sprintf(envFormat, k, v))
}

for k, v := range distEnv {
if _, ok := sourceEnv[k]; !ok {
deleteSlice = append(deleteSlice, fmt.Sprintf(envFormat, k, v))
}
}

return &Result{
InsertSlice: insertSlice,
UpdateSlice: updateSlice,
DeleteSlice: deleteSlice,
NoChangeSlice: noChangeSlice,
}, nil
}

func Read(path string) (map[string]string, error) {
e, err := godotenv.Read(path)
if err != nil {
return nil, err
}

return e, nil
}
92 changes: 92 additions & 0 deletions envdef_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package envdef

import (
"reflect"
"testing"
)

func TestRead(t *testing.T) {
testdata := []struct {
path string
expected map[string]string
}{
{
path: "testdata/.env",
expected: map[string]string{
"UPDATE": "update",
"DELETE": "delete",
"NOCHANGE": "nochange",
},
},
{
path: "testdata/notfound",
expected: nil,
},
}

for idx := range testdata {
res, _ := Read(testdata[idx].path)
if len(testdata[idx].expected) != len(res) {
t.Errorf("expected len(%v), got len(%v)", len(testdata[idx].expected), len(res))
}

for k, v := range testdata[idx].expected {
if v != res[k] {
t.Errorf("expected %s to be %s, got %s", k, v, res[k])
}
}
}
}

func TestDiff(t *testing.T) {
testdata := []struct {
source string
dist string
expected Result
}{
{
source: "testdata/.env.sample",
dist: "testdata/.env",
expected: Result{
InsertSlice: InsertSlice{"INSERT=insert"},
UpdateSlice: UpdateSlice{"UPDATE=default"},
DeleteSlice: DeleteSlice{"DELETE=delete"},
NoChangeSlice: NoChangeSlice{"NOCHANGE=nochange"},
},
},
}

for _, d := range testdata {
res, _ := Diff(d.source, d.dist)
// check len

if len(d.expected.InsertSlice) != len(res.InsertSlice) {
t.Errorf("expected len(%v), got len(%v)", len(d.expected.InsertSlice), len(res.InsertSlice))
}
if len(d.expected.UpdateSlice) != len(res.UpdateSlice) {
t.Errorf("expected len(%v), got len(%v)", len(d.expected.UpdateSlice), len(res.UpdateSlice))
}
if len(d.expected.DeleteSlice) != len(res.DeleteSlice) {
t.Errorf("expected len(%v), got len(%v)", len(d.expected.DeleteSlice), len(res.DeleteSlice))
}
if len(d.expected.NoChangeSlice) != len(res.NoChangeSlice) {
t.Errorf("expected len(%v), got len(%v)", len(d.expected.NoChangeSlice), len(res.NoChangeSlice))
}

if !reflect.DeepEqual(d.expected.InsertSlice, res.InsertSlice) {
t.Errorf("expected %s, got %s", d.expected.InsertSlice, res.InsertSlice)
}

if !reflect.DeepEqual(d.expected.UpdateSlice, res.UpdateSlice) {
t.Errorf("expected %s, got %s", d.expected.UpdateSlice, res.UpdateSlice)
}

if !reflect.DeepEqual(d.expected.DeleteSlice, res.DeleteSlice) {
t.Errorf("expected %s, got %s", d.expected.DeleteSlice, res.DeleteSlice)
}
if !reflect.DeepEqual(d.expected.NoChangeSlice, res.NoChangeSlice) {
t.Errorf("expected %s, got %s", d.expected.NoChangeSlice, res.NoChangeSlice)
}

}
}
10 changes: 10 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/locona/envdef

go 1.12

require (
github.com/fatih/color v1.9.0
github.com/joho/godotenv v1.3.0
github.com/k0kubun/pp v3.0.1+incompatible
github.com/mattn/go-colorable v0.1.6 // indirect
)
18 changes: 18 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40=
github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Loading

0 comments on commit 0544c47

Please sign in to comment.