Skip to content

Commit

Permalink
Add core CLI logic and basic commands
Browse files Browse the repository at this point in the history
  • Loading branch information
danhunsaker committed Aug 27, 2018
1 parent f809ed2 commit 6d95896
Show file tree
Hide file tree
Showing 51 changed files with 2,425 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ build/
*/Makefile.*
core*
!core*.sh
!core*.go
*~
.build/
7 changes: 5 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ script:
- |
cd ${TRAVIS_BUILD_DIR}/libcalends
go build -o libcalends.so -buildmode=c-shared .
- |
cd ${TRAVIS_BUILD_DIR}/cli
go build -o calends .
after_failure:
- ${TRAVIS_BUILD_DIR}/tests/core_dump_info.sh /tmp/
Expand All @@ -99,13 +102,13 @@ after_success:
go get github.com/aktau/github-release
github-release info --user danhunsaker --repo calends --tag ${TRAVIS_TAG} || \
github-release release --user danhunsaker --repo calends --tag ${TRAVIS_TAG} --draft
for archive in $(find dist/ -iname '*.tgz')
for archive in $(find dist/ -type f -name '*.tgz' -o -type f -name 'calends-*')
do
github-release upload \
--user danhunsaker \
--repo calends \
--tag ${TRAVIS_TAG} \
--name "${archive#dist/}" \
--name "$(echo ${archive} | sed 's:dist/(bin/)?::;s/windows/win/;s/win-4.0/win-nt/;s/win-6.0/win-vista/;s/win-6.1/win-7/;s/win-6.3/win-8.1/;s/win-10.0/win-10/;s/darwin/mac-os/')" \
--file "${archive}"
done
fi
3 changes: 2 additions & 1 deletion build-all
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ unset v

go get github.com/karalabe/xgo
${GOPATH}/bin/xgo -buildmode=c-shared -dest=$(pwd)/dist/ -out=libcalends-${VERSION} -targets=${TARGETS} github.com/danhunsaker/calends/libcalends
${GOPATH}/bin/xgo -dest=$(pwd)/dist/bin/ -out=calends-${VERSION} -targets="*/*,${TARGETS}" github.com/danhunsaker/calends/cli

for h in $(find dist/ -iname '*.h')
for h in $(find dist/ -name '*.h')
do
dir=${h/.h/}
mkdir -p ${dir}
Expand Down
2 changes: 1 addition & 1 deletion calends.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type Calends struct {
}

// Version of the library
var Version = "0.0.4"
var Version = "0.0.5"

// Create is the mechanism for constructing new Calends objects.
/*
Expand Down
40 changes: 40 additions & 0 deletions cli/batch/abuts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package batch

import (
"errors"

"github.com/chzyer/readline"
)

func init() {
completions = append(
completions,
readline.PcItem(
"abuts",
readline.PcItemDynamic(
completionStatesList,
readline.PcItemDynamic(completionStatesList),
),
),
)

commands["abuts"] = func(args []string) error {
if len(args) != 2 {
return errors.New("usage: abuts <source> <compare>")
}

source, compare := args[0], args[1]

if stamp1, ok := state[source]; ok {
if stamp2, ok := state[compare]; ok {
printf("%t\n", stamp1.Abuts(stamp2))
} else {
return errors.New("timestamp '" + compare + "' not set")
}
} else {
return errors.New("timestamp '" + source + "' not set")
}

return nil
}
}
40 changes: 40 additions & 0 deletions cli/batch/add-from-end.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package batch

import (
"errors"

"github.com/chzyer/readline"
)

func init() {
completions = append(
completions,
readline.PcItem(
"add-from-end",
readline.PcItemDynamic(completionCalendarList),
),
)

commands["add-from-end"] = func(args []string) error {
var err error

if len(args) != 4 {
return errors.New("usage: add-from-end <calendar> <offset> <source> <target>")
}

calendar, offset, source, target := args[0], args[1], args[2], args[3]

if stamp, ok := state[source]; ok {
state[target], err = stamp.AddFromEnd(offset, calendar)
if err != nil {
return err
}

printf("%s = %s\n", target, state[target])
} else {
return errors.New("timestamp '" + source + "' not set")
}

return nil
}
}
40 changes: 40 additions & 0 deletions cli/batch/add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package batch

import (
"errors"

"github.com/chzyer/readline"
)

func init() {
completions = append(
completions,
readline.PcItem(
"add",
readline.PcItemDynamic(completionCalendarList),
),
)

commands["add"] = func(args []string) error {
var err error

if len(args) != 4 {
return errors.New("usage: add <calendar> <offset> <source> <target>")
}

calendar, offset, source, target := args[0], args[1], args[2], args[3]

if stamp, ok := state[source]; ok {
state[target], err = stamp.Add(offset, calendar)
if err != nil {
return err
}

printf("%s = %s\n", target, state[target])
} else {
return errors.New("timestamp '" + source + "' not set")
}

return nil
}
}
45 changes: 45 additions & 0 deletions cli/batch/compare.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package batch

import (
"errors"

"github.com/chzyer/readline"
)

func init() {
completions = append(
completions,
readline.PcItem(
"compare",
readline.PcItemDynamic(
completionStatesList,
readline.PcItemDynamic(
completionStatesList,
readline.PcItemDynamic(func(arg string) []string {
return []string{"start", "end", "start-end", "end-start", "duration"}
}),
),
),
),
)

commands["compare"] = func(args []string) error {
if len(args) != 3 {
return errors.New("usage: compare <source> <compare> <mode>")
}

source, compare, mode := args[0], args[1], args[2]

if stamp1, ok := state[source]; ok {
if stamp2, ok := state[compare]; ok {
printf("%d\n", stamp1.Compare(stamp2, mode))
} else {
return errors.New("timestamp '" + compare + "' not set")
}
} else {
return errors.New("timestamp '" + source + "' not set")
}

return nil
}
}
40 changes: 40 additions & 0 deletions cli/batch/contains.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package batch

import (
"errors"

"github.com/chzyer/readline"
)

func init() {
completions = append(
completions,
readline.PcItem(
"contains",
readline.PcItemDynamic(
completionStatesList,
readline.PcItemDynamic(completionStatesList),
),
),
)

commands["contains"] = func(args []string) error {
if len(args) != 2 {
return errors.New("usage: contains <source> <compare>")
}

source, compare := args[0], args[1]

if stamp1, ok := state[source]; ok {
if stamp2, ok := state[compare]; ok {
printf("%t\n", stamp1.Contains(stamp2))
} else {
return errors.New("timestamp '" + compare + "' not set")
}
} else {
return errors.New("timestamp '" + source + "' not set")
}

return nil
}
}
100 changes: 100 additions & 0 deletions cli/batch/core.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package batch

import (
"fmt"
"io"
"log"
"strings"

"github.com/chzyer/readline"
"github.com/danhunsaker/calends"
"github.com/danhunsaker/calends/calendars"
"github.com/mattn/go-shellwords"
"github.com/urfave/cli"
)

// Collections
var completions []readline.PrefixCompleterInterface
var commands = make(map[string]func([]string) error)
var state = make(map[string]calends.Calends)

// Helper functions
var printf func(string, ...interface{}) // Need the readline session to properly define this one
var completionCalendarList = func(arg string) []string {
return calendars.ListRegistered()
}
var completionStatesList = func(arg string) (list []string) {
for name := range state {
list = append(list, name)
}
return
}

// Main logic
var Console = func(c *cli.Context) error {
completions = append(
completions,
readline.PcItem("help"),
readline.PcItem("exit"),
readline.PcItem("quit"),
)
completer := readline.NewPrefixCompleter(completions...)
shellwords.ParseEnv = true
shellwords.ParseBacktick = true

l, err := readline.NewEx(&readline.Config{
Prompt: "\033[35mcalends \033[36m» \033[0m",
HistoryFile: "",
AutoComplete: completer,
InterruptPrompt: "^C",
EOFPrompt: "exit",
HistorySearchFold: true,
})
if err != nil {
panic(err)
}
defer l.Close()

// Normally this helper would be defined entirely outside the main logic
// function, but we need the readline session, first, to make it work...
printf = func(message string, args ...interface{}) {
io.WriteString(l.Stdout(), fmt.Sprintf(message, args...))
}

log.SetOutput(l.Stderr())
for {
line, err := l.Readline()
if err == readline.ErrInterrupt {
if len(line) == 0 {
break
} else {
continue
}
} else if err == io.EOF {
break
}

line = strings.TrimSpace(line)

if line == "" || line == "help" {
printf("commands:\n")
printf(completer.Tree(" "))
continue
} else if line == "quit" || line == "exit" {
break
}

args, err := shellwords.Parse(line)
if err != nil {
log.Printf("%v\n", err)
} else if cmd, ok := commands[args[0]]; ok {
err = cmd(args[1:])
if err != nil {
log.Printf("%v\n", err)
}
} else {
log.Printf("unknown command %q\n", args[0])
}
}
return nil
}
Loading

0 comments on commit 6d95896

Please sign in to comment.