summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndinus <andinus@nand.sh>2020-04-08 17:48:21 +0530
committerAndinus <andinus@nand.sh>2020-04-08 17:48:21 +0530
commite80b9a2c4adc076f66e8239041512942c14c8e16 (patch)
treecc8db99c2a9365e342edc8756938cc9edcfd1cb2
parentcd94bf2bdd4da3a0e48386454916c4e7c23ae9ac (diff)
downloadgrus-e80b9a2c4adc076f66e8239041512942c14c8e16.tar.gz
Rethink grus design & add GRUS_STRICT_UNJUMBLE
-rw-r--r--README.org44
-rw-r--r--grus.go94
2 files changed, 80 insertions, 58 deletions
diff --git a/README.org b/README.org
index 7a32ef0..8574be5 100644
--- a/README.org
+++ b/README.org
@@ -19,20 +19,21 @@ Grus is a simple word unjumbler written in Go.
 |-------------+------------------------------------|
 | [[https://diode.zone/videos/watch/515e2528-a731-4c73-a0da-4f8da21a90c0][Grus v0.2.0]] | OpenBSD 6.6 (with /pledge/ & /unveil/) |
 
-Grus stops the search as soon as it unjumbles the word, so no anagrams are
-returned & maybe all dictionaries were not searched. However, this behaviour can
-be changed with two environment variables documented below.
-
-*Note*: If grus couldn't unjumble the word with first dictionary then it'll search
-in next dictionary, search stops once the word gets unjumbled.
-
-| Environment variable      | Explanation                        |
-|---------------------------+------------------------------------|
-| =GRUS_SEARCH_ALL=           | Search in all dictionaries         |
-| =GRUS_ANAGRAMS=             | Print all anagrams                 |
-| =GRUS_PRINT_PATH= =(v0.2.1+)= | Print dictionary path before words |
-
-Set these environment variable to /1 / true/ to change behaviour.
+*Note*: This is documentation for latest release, releases are tagged & so
+previous documentation can be checked by browsing source at tags.
+
+** Environment Variables
+*** =GRUS_SEARCH_ALL=
+Search in all dictionaries, by default Grus will exit after searching in first
+dictionary.
+*** =GRUS_ANAGRAMS=
+Prints all anagrams if set to true, by default Grus will print all anagrams.
+*** =GRUS_PRINT_PATH=
+Prints path to dictionary if set to true, this is set to false by default.
+*** =GRUS_STRICT_UNJUMBLE=
+Overrides everything & will try to print at least one match, if it doesn't find
+any then it will exit the program with a non-zero exit code. This will ignore
+=GRUS_SEARCH_ALL= till it finds at least one match.
 ** Default Dictionaries
 These files will be checked by default (in order).
 - =/usr/local/share/dict/words=
@@ -46,23 +47,20 @@ These files will be checked by default (in order).
 # unjumble word
 grus word
 
-# print all anagrams
-GRUS_ANAGRAMS=true grus word
-
-# search for word in all dictionaries
-GRUS_SEARCH_ALL=true grus word
+# don't print all anagrams
+GRUS_ANAGRAMS=false grus word
 
 # search for word in custom dictionaries too
 grus word /path/to/dict1 /path/to/dict2
 
 # search for word in all dictionaries
-GRUS_SEARCH_ALL=1 grus word /path/to/dict1 /path/to/dict2
-
-# search for word in all dictionaries & print all anagrams
-GRUS_SEARCH_ALL=1 GRUS_ANAGRAMS=1 grus word
+GRUS_SEARCH_ALL=true grus word /path/to/dict1 /path/to/dict2
 
 # print path to dictionary
 GRUS_PRINT_PATH=1 grus word
+
+# find at least one match
+GRUS_STRICT_UNJUMBLE=1 grus word
 #+END_SRC
 * Installation
 ** Pre-built binaries
diff --git a/grus.go b/grus.go
index f84d9a1..24714c4 100644
--- a/grus.go
+++ b/grus.go
@@ -16,11 +16,40 @@ func grus() {
 
 	version := "v0.2.1"
 
+	// Print version if first argument is version.
 	if os.Args[1] == "version" {
 		fmt.Printf("Grus %s\n", version)
 		os.Exit(0)
 	}
 
+	// Define default environment variables.
+	envVar := make(map[string]bool)
+	envVar["GRUS_SEARCH_ALL"] = false
+	envVar["GRUS_ANAGRAMS"] = true
+	envVar["GRUS_STRICT_UNJUMBLE"] = false
+	envVar["GRUS_PRINT_PATH"] = false
+
+	// Check environment variables.
+	for k, _ := range envVar {
+		env := os.Getenv(k)
+		if env == "false" ||
+			env == "0" {
+			envVar[k] = false
+		} else if env == "true" ||
+			env == "1" {
+			envVar[k] = true
+		}
+	}
+
+	// Print environment variables if first argument is env.
+	if os.Args[1] == "env" {
+		for k, v := range envVar {
+			fmt.Printf("%s: %t\n", k, v)
+		}
+		os.Exit(0)
+	}
+
+	// Define default dictionaries.
 	dicts := []string{
 		"/usr/local/share/dict/words",
 		"/usr/local/share/dict/web2",
@@ -36,31 +65,10 @@ func grus() {
 		dicts = append(os.Args[2:], dicts...)
 	}
 
-	// Check if user has asked to search in all dictionaries.
-	searchAll := false
-	searchAllEnv := os.Getenv("GRUS_SEARCH_ALL")
-	if searchAllEnv == "true" ||
-		searchAllEnv == "1" {
-		searchAll = true
-	}
-
-	// Check if user wants anagrams.
-	anagrams := false
-	anagramsEnv := os.Getenv("GRUS_ANAGRAMS")
-	if anagramsEnv == "true" ||
-		anagramsEnv == "1" {
-		anagrams = true
-	}
+	// We use this to record if the word was unjumbled.
+	unjumbled := false
 
-	// Check if user wants to print dictionary path.
-	printPath := false
-	printPathEnv := os.Getenv("GRUS_PRINT_PATH")
-	if printPathEnv == "true" ||
-		printPathEnv == "1" {
-		printPath = true
-	}
-
-	for _, dict := range dicts {
+	for k, dict := range dicts {
 		if _, err := os.Stat(dict); err != nil &&
 			!os.IsNotExist(err) {
 			// Error is not nil & also it's not path
@@ -75,16 +83,15 @@ func grus() {
 		}
 
 		// Print path to dictionary if printPath is true.
-		if printPath {
+		if envVar["GRUS_PRINT_PATH"] {
+			if k != 0 {
+				fmt.Println()
+			}
 			fmt.Println(dict)
 		}
 
 		file, err := os.Open(dict)
 		panicOnErr(err)
-		defer file.Close()
-
-		// We use this to record if the word was unjumbled.
-		unjumbled := false
 
 		scanner := bufio.NewScanner(file)
 		for scanner.Scan() {
@@ -96,21 +103,38 @@ func grus() {
 				fmt.Println(scanner.Text())
 				// If the user doesn't want anagrams
 				// then exit the program.
-				if !anagrams {
+				if !envVar["GRUS_ANAGRAMS"] {
 					os.Exit(0)
 				}
 				unjumbled = true
 			}
 		}
 		panicOnErr(scanner.Err())
+		file.Close()
+
+		// If the user has asked to strictly unjumble then we
+		// cannot exit till it's unjumbled.
+		if envVar["GRUS_STRICT_UNJUMBLE"] &&
+			!unjumbled {
+			// If user has asked to strictly unjumble & we
+			// haven't done that yet & this is the last
+			// dictionary then we've failed to unjumble it
+			// & the program must exit with a non-zero
+			// exit code.
+			if k == len(dicts)-1 {
+				os.Exit(1)
+			}
 
-		// If word was unjumbled & user hasn't asked to search
-		// in all dictionaries then exit the program otherwise
-		// keep searching in other dictionaries.
-		if unjumbled &&
-			!searchAll {
+			// Cannot exit, must search next dictionary.
+			continue
+		}
+
+		// If user hasn't asked to search all dictionaries
+		// then exit the program.
+		if !envVar["GRUS_SEARCH_ALL"] {
 			os.Exit(0)
 		}
+
 	}
 }