1
0
Fork 0

Rethink grus design & add GRUS_STRICT_UNJUMBLE

This commit is contained in:
Andinus 2020-04-08 17:48:21 +05:30
parent cd94bf2bdd
commit e80b9a2c4a
Signed by: andinus
GPG Key ID: B67D55D482A799FD
2 changed files with 79 additions and 57 deletions

View File

@ -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*: This is documentation for latest release, releases are tagged & so
previous documentation can be checked by browsing source at tags.
*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.
** 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

94
grus.go
View File

@ -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
}
// We use this to record if the word was unjumbled.
unjumbled := false
// Check if user wants anagrams.
anagrams := false
anagramsEnv := os.Getenv("GRUS_ANAGRAMS")
if anagramsEnv == "true" ||
anagramsEnv == "1" {
anagrams = true
}
// 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 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 {
// 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)
}
// 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)
}
}
}