-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add 'v2/' from commit 'd184da41b02eca5aa382d9094bcc71146c4617b0'
- Loading branch information
Showing
24 changed files
with
824 additions
and
0 deletions.
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,9 @@ | ||
/.gopath | ||
/bin | ||
/vendor/ | ||
/pkg/ | ||
/.github | ||
/payload.zip | ||
/.tools/ | ||
/Dockerfile | ||
prospectus |
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 @@ | ||
[submodule "meta"] | ||
path = meta | ||
url = https://github.com/akerl/pkgforge-golang-helper |
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,30 @@ | ||
name 'prospectus' | ||
org 'akerl' | ||
|
||
source( | ||
type: 'git', | ||
path: '.' | ||
) | ||
|
||
build do | ||
run 'make local' | ||
cp 'bin' | ||
end | ||
|
||
package( | ||
type: 'file', | ||
artifacts: [ | ||
{ | ||
source: "bin/#{@forge.name}-ng_darwin", | ||
name: "#{@forge.name}_darwin" | ||
}, | ||
{ | ||
source: "bin/#{@forge.name}-ng_linux", | ||
name: "#{@forge.name}_linux" | ||
} | ||
] | ||
) | ||
|
||
test do | ||
# TODO: add tests | ||
end |
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,13 @@ | ||
#!/usr/bin/env ruby | ||
|
||
require 'prospectus' | ||
|
||
Prospectus.extra_dep('file', 'prospectus_travis') | ||
Prospectus.extra_dep('file', 'prospectus_golang') | ||
|
||
item do | ||
noop | ||
|
||
extend ProspectusGolang::Deps.new | ||
extend ProspectusTravis::Build.new('akerl/prospectus-ng') | ||
end |
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,16 @@ | ||
sudo: required | ||
dist: xenial | ||
services: | ||
- docker | ||
env: | ||
global: | ||
- PKGFORGE_STATEFILE=/tmp/pkgforge | ||
script: make | ||
deploy: | ||
provider: script | ||
script: make release || travis_terminate 1 | ||
skip_cleanup: true | ||
on: | ||
tags: true | ||
notifications: | ||
email: false |
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,22 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2019 Les Aker | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
|
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 @@ | ||
include meta/Makefile |
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 @@ | ||
PACKAGE = prospectus |
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,43 @@ | ||
prospectus-ng | ||
========= | ||
|
||
[![Build Status](https://img.shields.io/travis/com/akerl/prospectus-ng.svg)](https://travis-ci.com/akerl/prospectus) | ||
[![GitHub release](https://img.shields.io/github/release/akerl/prospectus-ng.svg)](https://github.com/akerl/prospectus-ng/releases) | ||
[![MIT Licensed](https://img.shields.io/badge/license-MIT-green.svg)](https://tldrlegal.com/license/mit-license) | ||
|
||
Tool to check for changes in expected vs. actual state | ||
|
||
## Usage | ||
|
||
### Check specification | ||
|
||
Checks must implement responses for the following commands: | ||
|
||
### load | ||
|
||
The `load` command accepts a hash with a single key, the directory being checked, and returns an array of checks with optional metadata. | ||
|
||
Input: `{"dir": "/path/to/main/dir"}` | ||
Output: `[{"name": "check_N", "metadata": {"foo": "bar"}}, ...]` | ||
|
||
### execute | ||
|
||
The `execute` command accepts a hash representing the check object. Metadata provided during the `load` call is included. The return value must be a Result object for the given check. | ||
|
||
Input: `{"dir": "/path/to/main/dir", "file": "/path/to/main/dir/.prospectus.d/checkfile", "name": "check_N", "metadata": {"foo": "bar"}}` | ||
Output: `{"actual": "unhappy", "expected": {"type": "string", "data": {"expected": "happy"}}}` | ||
|
||
### fix | ||
|
||
The `fix` command can attempt to fix a failed check automatically. It accepts a hash representing the failed result, which includes the originating check. The return value must be a Result object for the given check. | ||
|
||
**Note:** The check must respond to the `fix` command, but if it does not support automatic fixes, it can respond by emiting the same result object it was given. | ||
|
||
Input: `{"actual": "unhappy", "expected": {"type": "string", "data": {"expected": "happy"}}, "check": {"dir": "/path/to/main/dir", "file": "/path/to/main/dir/.prospectus.d/checkfile", "name": "check_N", "metadata": {"foo": "bar"}}}` | ||
Output: `{"actual": "happy", "expected": {"type": "string", "data": {"expected": "happy"}}}` | ||
|
||
## Installation | ||
|
||
## License | ||
|
||
prospectus-ng is released under the MIT License. See the bundled LICENSE file for details. |
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,221 @@ | ||
package checks | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"os/exec" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/akerl/prospectus/expectations" | ||
) | ||
|
||
const ( | ||
prospectusDirName = ".prospectus.d" | ||
) | ||
|
||
// TODO: add timber logging | ||
// TODO: add parallelization | ||
|
||
// Check defines a single check that is ready for execution | ||
type Check struct { | ||
Dir string `json:"dir"` | ||
File string `json:"file"` | ||
Name string `json:"name"` | ||
Metadata map[string]string `json:"metadata"` | ||
} | ||
|
||
// CheckSet defines a group of Checks | ||
type CheckSet []Check | ||
|
||
// Result defines the results of executing a Check | ||
type Result struct { | ||
Actual string `json:"actual"` | ||
Expected expectations.Wrapper `json:"expected"` | ||
Check Check `json:"check"` | ||
} | ||
|
||
// ResultSet defines a group of Results | ||
type ResultSet []Result | ||
|
||
type loadCheckInput struct { | ||
Dir string `json:"dir"` | ||
} | ||
|
||
// NewSet returns a CheckSet based on a provided list of directories | ||
func NewSet(relativeDirs []string) (CheckSet, error) { | ||
var err error | ||
|
||
dirs := make([]string, len(relativeDirs)) | ||
for index, item := range relativeDirs { | ||
dirs[index], err = filepath.Abs(item) | ||
if err != nil { | ||
return CheckSet{}, err | ||
} | ||
} | ||
|
||
var cs CheckSet | ||
for _, item := range dirs { | ||
newSet, err := newSetFromDir(item) | ||
if err != nil { | ||
return CheckSet{}, err | ||
} | ||
cs = append(cs, newSet...) | ||
} | ||
|
||
return cs, nil | ||
} | ||
|
||
func newSetFromDir(absoluteDir string) (CheckSet, error) { | ||
prospectusDir := filepath.Join(absoluteDir, prospectusDirName) | ||
|
||
fileObjs, err := ioutil.ReadDir(prospectusDir) | ||
if err != nil { | ||
return CheckSet{}, err | ||
} | ||
|
||
var cs CheckSet | ||
for _, fileObj := range fileObjs { | ||
file := filepath.Join(prospectusDir, fileObj.Name()) | ||
newSet, err := newSetFromFile(absoluteDir, file) | ||
if err != nil { | ||
return CheckSet{}, err | ||
} | ||
cs = append(cs, newSet...) | ||
} | ||
|
||
return cs, nil | ||
} | ||
|
||
func newSetFromFile(dir, file string) (CheckSet, error) { | ||
cs := CheckSet{} | ||
input := loadCheckInput{Dir: dir} | ||
err := execProspectusFile(file, "load", input, &cs) | ||
if err != nil { | ||
return CheckSet{}, fmt.Errorf("Failed loading %s: %s", file, err) | ||
} | ||
for index := range cs { | ||
cs[index].Dir = dir | ||
cs[index].File = file | ||
} | ||
return cs, nil | ||
} | ||
|
||
func execProspectusFile(file, command string, input interface{}, output interface{}) error { | ||
cmd := exec.Command(file, command) | ||
|
||
inputBytes, err := json.Marshal(input) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
stdin, err := cmd.StdinPipe() | ||
if err != nil { | ||
return err | ||
} | ||
stdin.Write(inputBytes) | ||
stdin.Close() | ||
|
||
stdout, err := cmd.Output() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return json.Unmarshal(stdout, output) | ||
} | ||
|
||
// Execute returns the Results from a CheckSet by calling Execute on each Check | ||
func (cs CheckSet) Execute() ResultSet { | ||
resultSet := make(ResultSet, len(cs)) | ||
for index, item := range cs { | ||
resultSet[index] = item.Execute() | ||
} | ||
return resultSet | ||
} | ||
|
||
// Execute runs the Check and returns Results | ||
func (c Check) Execute() Result { | ||
return execProspectusForResult("execute", c, c) | ||
} | ||
|
||
func execProspectusForResult(method string, c Check, input interface{}) Result { | ||
r := Result{} | ||
err := execProspectusFile(c.File, method, input, &r) | ||
if err != nil { | ||
return NewErrorResult(fmt.Sprintf("%s error: %s", method, err), c) | ||
} | ||
r.Check = c | ||
return r | ||
} | ||
|
||
// String returns the Result as a human-readable string | ||
func (c Check) String() string { | ||
return fmt.Sprintf( | ||
"%s::%s", | ||
c.Dir, | ||
c.Name, | ||
) | ||
} | ||
|
||
// Changed filters a ResultSet to only Results which do not match | ||
func (rs ResultSet) Changed() ResultSet { | ||
var newResultSet ResultSet | ||
for _, item := range rs { | ||
if !item.Matches() { | ||
newResultSet = append(newResultSet, item) | ||
} | ||
} | ||
return newResultSet | ||
} | ||
|
||
// Matches returns true if the Expected and Actual values of the Result match | ||
func (r Result) Matches() bool { | ||
return r.Expected.Matches(r.Actual) | ||
} | ||
|
||
// JSON returns the ResultsSet as a marshalled JSON string | ||
func (rs ResultSet) JSON() (string, error) { | ||
data, err := json.MarshalIndent(rs, "", " ") | ||
if err != nil { | ||
return "", err | ||
} | ||
return string(data), nil | ||
} | ||
|
||
// String returns the ResultsSet as a human-readable string | ||
func (rs ResultSet) String() string { | ||
var b strings.Builder | ||
for _, item := range rs { | ||
b.WriteString(item.String()) | ||
b.WriteString("\n") | ||
} | ||
return b.String() | ||
} | ||
|
||
// String returns the Result as a human-readable string | ||
func (r Result) String() string { | ||
return fmt.Sprintf( | ||
"%s: %s / %s", | ||
r.Check, | ||
r.Actual, | ||
r.Expected.String(), | ||
) | ||
} | ||
|
||
// Fix attempts to resolve a mismatched expectation | ||
func (r Result) Fix() Result { | ||
return execProspectusForResult("fix", r.Check, r) | ||
} | ||
|
||
// NewErrorResult creates an error result from a given string | ||
func NewErrorResult(msg string, c Check) Result { | ||
return Result{ | ||
Actual: "error", | ||
Expected: expectations.Wrapper{ | ||
Type: "error", | ||
Data: map[string]string{"msg": msg}, | ||
}, | ||
Check: c, | ||
} | ||
} |
Oops, something went wrong.