Skip to content

Commit

Permalink
Add --dir arg to list a specific location (#26)
Browse files Browse the repository at this point in the history
* Add --dir arg to list a specific location

- Add new 'dir' flag. Default to current directory
- Add unit tests for flags. Cannot use --dir with --merge.
- Fix a bug in git-log when running --merge from outside of the git repo

* Rename 'chrooted' to 'pathContains'

* Add test for listing from outisde repo

* Rename pathContains to isRoot
  • Loading branch information
fridim authored Mar 21, 2023
1 parent 6158f34 commit 26ecbec
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 31 deletions.
95 changes: 73 additions & 22 deletions cli/agnosticv.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var validateFlag bool
var versionFlag bool
var gitFlag bool
var outputFlag string
var dirFlag string

// Build info
var Version = "development"
Expand Down Expand Up @@ -64,6 +65,7 @@ func parseFlags(args []string, output io.Writer) controlFlow {
flags := flag.NewFlagSet(args[0], flag.ContinueOnError)
flags.SetOutput(output)
flags.BoolVar(&listFlag, "list", false, "List all the catalog items present in current directory.")
flags.StringVar(&dirFlag, "dir", "", "Directory to use as dir when listing catalog items. Default = current directory.")
flags.BoolVar(&validateFlag, "validate", true, "Validate variables against schemas present in .schemas directory.")
flags.Var(&relatedFlags, "related", `Use with --list only. Filter output and display only related catalog items.
A catalog item is related to FILE if:
Expand Down Expand Up @@ -142,6 +144,35 @@ need this parameter unless your files are not in a git repository, or if you wan
outputFlag = "yaml"
}

if mergeFlag != "" && dirFlag != "" {
fmt.Fprintln(output, "You cannot use --merge and --dir simultaneously.")
return controlFlow{true, 2}
}
if dirFlag != "" {
// Ensure dir is a directory
fi, err := os.Stat(dirFlag)
if err != nil {
fmt.Fprintln(output, "Error:", err)
return controlFlow{true, 1}
}
if !fi.IsDir() {
fmt.Fprintln(output, "Error:", dirFlag, "is not a directory")
return controlFlow{true, 2}
}
dirFlag, err = filepath.Abs(dirFlag)
if err != nil {
fmt.Fprintln(output, "Error:", err)
return controlFlow{true, 1}
}
} else {
// Default to current directory
var err error
if dirFlag, err = os.Getwd(); err != nil {
fmt.Fprintln(output, "Error:", err)
return controlFlow{true, 1}
}
}

if rootFlag != "" {
if !fileExists(rootFlag) {
log.Fatalf("File %s does not exist", rootFlag)
Expand All @@ -151,22 +182,41 @@ need this parameter unless your files are not in a git repository, or if you wan
} else {
// init rootFlag by discovering depending on other flags
if listFlag {
// use current workdir
var workdir string
if wd, errWorkDir := os.Getwd(); errWorkDir == nil {
workdir = wd
if dirFlag != "" {
rootFlag = findRoot(dirFlag)
} else {
logErr.Fatal(errWorkDir)
// use current workdir to find root
var workdir string
if wd, errWorkDir := os.Getwd(); errWorkDir == nil {
workdir = wd
} else {
logErr.Fatal(errWorkDir)
}
rootFlag = findRoot(workdir)
}

rootFlag = findRoot(workdir)

} else if mergeFlag != "" {
// Use root of the file to merge
rootFlag = findRoot(mergeFlag)
}
}

// Validate rootflag is compatible with other flags
if listFlag {
// Ensure listing will be done inside root
absDir, err := filepath.Abs(dirFlag)
if err != nil {
fmt.Fprintln(output, "Error:", err)
return controlFlow{true, 1}
}

if !isRoot(rootFlag, absDir) {
fmt.Fprintln(output, "Error: --dir", dirFlag, "is not inside --root", rootFlag)
return controlFlow{true, 2}
}
}


// Do not perform git operations when listing
if listFlag {
gitFlag = false
Expand Down Expand Up @@ -200,7 +250,7 @@ func isPathCatalogItem(root, p string) bool {
return false
}

if !chrooted(root, p) {
if !isRoot(root, p) {
return false
}

Expand Down Expand Up @@ -335,6 +385,7 @@ func findCatalogItems(workdir string, hasFlags []string, relatedFlags []string,
if rootFlag == "" {
rootFlag = findRoot(workdir)
}

err := filepath.Walk(".", func(p string, info os.FileInfo, err error) error {
if err != nil {
logErr.Printf("%q: %v\n", p, err)
Expand Down Expand Up @@ -475,10 +526,10 @@ func parentDir(path string) string {
return filepath.Dir(currentDir)
}

// chrooted function compares strings and returns true if
// path is chrooted in root.
// isRoot function compares strings and returns true if
// path is contained in root.
// It's a poor man's chroot
func chrooted(root string, path string) bool {
func isRoot(root string, path string) bool {
if root == path {
return true
}
Expand Down Expand Up @@ -540,7 +591,7 @@ func nextCommonFile(position string) string {
for _, commonFile := range validCommonFileNames {
if path.Base(position) == commonFile {
// If parent is out of chroot, stop
if !chrooted(rootFlag, parentDir(position)) {
if !isRoot(rootFlag, parentDir(position)) {
logDebug.Println("parent of", position, ",", parentDir(position),
"is out of chroot", rootFlag)
return ""
Expand Down Expand Up @@ -574,7 +625,7 @@ func nextCommonFile(position string) string {
}

// If parent is out of chroot, stop
if !chrooted(rootFlag, parentDir(position)) {
if !isRoot(rootFlag, parentDir(position)) {
logDebug.Println("parent of", position, ",", parentDir(position),
"is out of chroot", rootFlag)
return ""
Expand All @@ -592,20 +643,12 @@ func main() {
initConf(rootFlag)
initMergeStrategies()

// Save current work directory
var workDir string
if wd, errWorkDir := os.Getwd(); errWorkDir == nil {
workDir = wd
} else {
logErr.Fatal(errWorkDir)
}

if len(schemas) == 0 {
initSchemaList()
}

if listFlag {
catalogItems, err := findCatalogItems(workDir, hasFlags, relatedFlags, orRelatedFlags)
catalogItems, err := findCatalogItems(dirFlag, hasFlags, relatedFlags, orRelatedFlags)

if err != nil {
logErr.Printf("error walking the path %q: %v\n", ".", err)
Expand All @@ -629,6 +672,14 @@ func main() {
}

if mergeFlag != "" {
// Get current work directory
var workDir string
if wd, errWorkDir := os.Getwd(); errWorkDir == nil {
workDir = wd
} else {
logErr.Fatal(errWorkDir)
}

merged, mergeList, err := mergeVars(mergeFlag, mergeStrategies)
if err != nil {
logErr.Fatal(err)
Expand Down
4 changes: 2 additions & 2 deletions cli/agnosticv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestParentDir(t *testing.T) {
}
}

func TestChrooted(t *testing.T) {
func TestPathContains(t *testing.T) {
testCases := []struct {
root string
path string
Expand Down Expand Up @@ -101,7 +101,7 @@ func TestChrooted(t *testing.T) {
}

for _, tc := range testCases {
if tc.result != chrooted(tc.root, tc.path) {
if tc.result != isRoot(tc.root, tc.path) {
t.Error(tc.root, tc.path, tc.result)
}
}
Expand Down
5 changes: 4 additions & 1 deletion cli/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,15 @@ func findMostRecentCommitCmd(p string, related []Include) *object.Commit {
cmd := exec.Command("git", args...)
logDebug.Println(cmd)

// Run git log from the directory of the catalog item
cmd.Dir = filepath.Dir(p)

var out bytes.Buffer
cmd.Stdout = &out

err := cmd.Run()
if err != nil {
logErr.Fatal(err)
logErr.Fatal("git log error:", err)
}

repo, err := git.PlainOpenWithOptions(p, &git.PlainOpenOptions{DetectDotGit: true})
Expand Down
2 changes: 1 addition & 1 deletion cli/includes.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func resolvePath(root string, includePath string, contextFile string) (string, e
}
result := filepath.Join(path.Dir(contextFile), filepath.Clean(includePath))

if !chrooted(root, result) {
if !isRoot(root, result) {
return "", ErrorIncludeOutOfChroot
}
return result, nil
Expand Down
29 changes: 29 additions & 0 deletions cli/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,35 @@ func TestFlag(t *testing.T) {
description: "-output and -merge, yaml output",
result: controlFlow{false, 0},
},
{
args: []string{"agnosticv",
"--merge", "fixtures/test/BABYLON_EMPTY_CONFIG/dev.yaml",
"--dir", "/tmp/repo"},
description: "-dir and -merge should fail",
result: controlFlow{true, 2},
},
{
args: []string{"agnosticv",
"--list",
"--dir", "/tmp/doesntexist"},
description: "-list and -dir with a dir that doesn't exist",
result: controlFlow{true, 1},
},
{
args: []string{"agnosticv",
"--list",
"--dir", "fixtures"},
description: "-list and -dir",
result: controlFlow{false, 0},
},
{
args: []string{"agnosticv",
"--list",
"--root", "fixtures",
"--dir", "."},
description: "-dir is outside -root",
result: controlFlow{true, 2},
},
}

for _, tc := range testCases {
Expand Down
22 changes: 17 additions & 5 deletions tools/test_new_version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ cd ${1}
cli1="${2}"
cli2="${3}"

echo -n "Testing listing ......................."
echo -n "listing ......................."
diff -u <($cli1 --list) <($cli2 --list)
if [ $? != 0 ]; then
echo >&2 "Listing is not the same"
Expand All @@ -32,14 +32,26 @@ echo OK

for dir in *; do
if [ -d $dir ]; then
echo -n "Testing listing in ${dir}......................."
printf "%-80s" "listing in ${dir}"
cd "${dir}"
diff -u <($cli1 --list) <($cli2 --list)
if [ $? != 0 ]; then
echo >&2 "Listing is not the same"
exit 2
fi
echo OK

if $cli1 --help | grep '\-dir string' -q; then
cd /tmp
printf "%-80s" "from oustide ${dir} with --dir"
diff -u <($cli1 --list --dir "${dir}") <($cli2 --list --dir "${dir}")
if [ $? != 0 ]; then
echo >&2 "Listing is not the same"
exit 2
fi
echo OK
fi

cd ${1}
fi
done
Expand All @@ -50,7 +62,7 @@ if [ $? != 0 ]; then
exit 2
fi
for ci in $($cli1 --list); do
echo -n "testing merge $ci ......................."
printf "%-80s" "merge $ci"

diff -u <($cli1 --merge $ci) <($cli2 --merge $ci) > /dev/null
if [ $? != 0 ]; then
Expand All @@ -61,7 +73,7 @@ for ci in $($cli1 --list); do

echo YES

echo -n "testing merge $ci JSON ......................."
printf "%-80s" "merge $ci JSON"
if ! $cli2 --merge $ci --output json | jq . > /dev/null; then
echo NO
else
Expand All @@ -70,7 +82,7 @@ for ci in $($cli1 --list); do
done

for fil in $(find -name common.yaml) $(find -name account.yaml) $(find includes -type f); do
echo -n "testing related files $fil ......................."
printf "%-80s" "related files $fil"
diff -u <($cli1 --list --related $fil) <($cli2 --list --related $fil) > /dev/null
if [ $? != 0 ]; then
echo "NO"
Expand Down

0 comments on commit 26ecbec

Please sign in to comment.