This repository has been archived by the owner on Oct 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
10a4c05
commit 23bb169
Showing
13 changed files
with
293 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# .circleci/config.yml | ||
version: 2.1 | ||
workflows: | ||
main: | ||
jobs: | ||
- release: | ||
# Only run this job on git tag pushes | ||
filters: | ||
branches: | ||
ignore: /.*/ | ||
tags: | ||
only: /v[0-9]+(\.[0-9]+)*(-.*)*/ | ||
jobs: | ||
release: | ||
docker: | ||
- image: circleci/golang:1.13 | ||
steps: | ||
- checkout | ||
- run: curl -sL https://git.io/goreleaser | bash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,6 @@ | |
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Binary when built locally | ||
dy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Main build and github release | ||
before: | ||
hooks: | ||
# you may remove this if you don't use vgo | ||
# - go mod tidy | ||
# you may remove this if you don't need go generate | ||
# - go generate ./... | ||
builds: | ||
- env: | ||
- CGO_ENABLED=0 | ||
archives: | ||
- replacements: | ||
darwin: Darwin | ||
linux: Linux | ||
windows: Windows | ||
386: i386 | ||
amd64: x86_64 | ||
checksum: | ||
name_template: 'checksums.txt' | ||
snapshot: | ||
name_template: "{{ .Tag }}-next" | ||
changelog: | ||
sort: asc | ||
filters: | ||
exclude: | ||
- '^docs:' | ||
- '^test:' | ||
|
||
# Homebrew | ||
brews: | ||
- | ||
github: | ||
owner: sampointer | ||
name: homebrew-dy | ||
|
||
commit_author: | ||
name: goreleaserbot | ||
email: [email protected] | ||
|
||
folder: Formula | ||
homepage: "https://github.com/sampointer/dy" | ||
description: "Construct YAML from a directory tree" | ||
install : | | ||
bin.install "dy" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,75 @@ | ||
# dy | ||
# dy [![Go Report Card](https://goreportcard.com/badge/github.com/sampointer/dy)](https://goreportcard.com/report/github.com/sampointer/dy) [![CircleCI](https://circleci.com/gh/sampointer/dy.svg?style=shield)](https://circleci.com/gh/sampointer/dy) | ||
Construct YAML from a directory tree | ||
|
||
## Description | ||
The entire world seems to think declarative configuration is best represented as YAML. This is especially prevailant in the land of Kubernetes and related tools. Terrible ideas have a tendency to accumulate leading to [awful solutions](https://twitter.com/sam_pointer/status/1182321989895311362) to the wrong problems. | ||
|
||
Whilst this tool doesn't pretend to move the mountain it does try to nudge it back in the right direction. | ||
|
||
Put simply, `dy` allows one to build a YAML document from a directory tree containing snippets of YAML. The aim is to make the document easier to reason about and maintain. | ||
|
||
## Introducing Divvy Yaml | ||
> **divvy** */ˈdɪvi/* - To share out. *Informal, British* - A foolish or stupid person | ||
`dy` parses a directory tree according to the following rules: | ||
|
||
* A directory is a text key | ||
* A file name has contents that are rendered under a key named after the file prefix | ||
* A file name that begins with an underscore is rendered without a key at the current indentation level | ||
|
||
Consider the following [example](https://github.com/sampointer/dy/tree/master/examples/k8s_deployment): | ||
|
||
``` | ||
$ tree k8s_deployment/ | ||
k8s_deployment/ | ||
├── _header.yaml | ||
├── metadata.yaml | ||
└── spec | ||
├── _replicas.yaml | ||
├── selector.yaml | ||
└── template | ||
├── metadata | ||
│ └── labels.yaml | ||
└── spec | ||
└── containers.yaml | ||
4 directories, 6 files | ||
``` | ||
|
||
``` | ||
$ dy k8s_deployment/ | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: nginx-deployment | ||
labels: | ||
app: nginx | ||
spec: | ||
replicas: 3 | ||
selector: | ||
matchLabels: | ||
app: nginx | ||
template: | ||
metadata: | ||
labels: | ||
app: nginx | ||
spec: | ||
containers: | ||
- name: nginx | ||
image: nginx:1.7.9 | ||
ports: | ||
- containerPort: 80 | ||
``` | ||
|
||
``` | ||
$ dy k8s_deployment/ | kubectl apply --validate=true --dry-run=true -f - | ||
deployment.apps/nginx-deployment created (dry run) | ||
``` | ||
|
||
## Installing | ||
### Homebrew | ||
1. `brew tap sampointer/dy` | ||
1. `brew install dy` | ||
|
||
### Manually | ||
Download the latest [release](https://github.com/sampointer/dy/releases) and unpack it into an appropriate place in your `${PATH}`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package divvyyaml | ||
|
||
import ( | ||
"bufio" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
// Represents a DivvyYaml document and its methods | ||
type DivvyYaml struct { | ||
Doc string // The constructed YAML document | ||
} | ||
|
||
// Parse populates the structure from the given path and options | ||
func (d *DivvyYaml) Parse(path string) error { | ||
|
||
// Store the current working directory | ||
cwd, err := os.Getwd() | ||
defer os.Chdir(cwd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Change to the directory given | ||
path = filepath.Clean(path) | ||
err = os.Chdir(path) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Since our cwd is where we need to be, walk the current directory | ||
err = filepath.Walk(".", processWalk) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
d.Doc = doc | ||
return nil | ||
} | ||
|
||
var doc string // Constructed YAML document | ||
|
||
func processWalk(path string, info os.FileInfo, err error) error { | ||
// Pass all errors back up the call chain | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Skip the root directory | ||
if path == "." { | ||
return nil | ||
} | ||
|
||
if info.IsDir() { | ||
// A directory is a key | ||
key := filepath.Base(path) | ||
depth := directoryElements(path) | ||
doc += indentString(depth, key) + ":\n" | ||
} else { | ||
// A file has contents that exist under a key named after the file prefix | ||
// unless the file name starts with an underscore, in which case no key | ||
// is written | ||
var key string | ||
var depth int | ||
|
||
base := filepath.Base(path) | ||
if strings.HasPrefix(base, "_") { | ||
key = "" | ||
depth = directoryElements(path) - 1 | ||
} else { | ||
key = strings.TrimSuffix(base, filepath.Ext(path)) + ":\n" | ||
depth = directoryElements(path) | ||
} | ||
|
||
doc += indentString(depth, key) | ||
|
||
file, err := os.Open(path) | ||
if err != nil { | ||
return err | ||
} | ||
defer file.Close() | ||
|
||
scanner := bufio.NewScanner(file) | ||
for scanner.Scan() { | ||
doc += indentString(depth+1, scanner.Text()) + "\n" | ||
} | ||
|
||
if err := scanner.Err(); err != nil { | ||
return err | ||
} | ||
|
||
} | ||
|
||
return err | ||
} | ||
|
||
// indentString returns the passed string prefixed with the specified number of double spaces | ||
func indentString(indent int, s string) string { | ||
var rs string | ||
|
||
for i := 0; i < indent; i++ { | ||
rs += " " | ||
} | ||
|
||
rs += s | ||
return rs | ||
} | ||
|
||
// directoryElements returns a count of the number of directories in a path string | ||
func directoryElements(path string) int { | ||
return len(strings.Split(path, string(os.PathSeparator))) - 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
apiVersion: apps/v1 | ||
kind: Deployment |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
name: nginx-deployment | ||
labels: | ||
app: nginx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
replicas: 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
matchLabels: | ||
app: nginx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
app: nginx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
- name: nginx | ||
image: nginx:1.7.9 | ||
ports: | ||
- containerPort: 80 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module github.com/sampointer/dy | ||
|
||
go 1.13 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
divvy "github.com/sampointer/dy/divvyyaml" | ||
"os" | ||
) | ||
|
||
func main() { | ||
var dy divvy.DivvyYaml | ||
|
||
// Do the most basic argument parsing possible | ||
if len(os.Args) < 2 { | ||
os.Stderr.WriteString("you must pass a path as an argument\n") | ||
os.Exit(1) | ||
} | ||
|
||
err := dy.Parse(os.Args[1]) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "%v\n", err) | ||
} else { | ||
fmt.Println(dy.Doc) | ||
} | ||
} |