Skip to content

Commit

Permalink
add: support for markdown docopts.md
Browse files Browse the repository at this point in the history
  • Loading branch information
michele-sciabarra committed Aug 11, 2024
1 parent 6656185 commit 79d5b61
Show file tree
Hide file tree
Showing 13 changed files with 266 additions and 18 deletions.
2 changes: 1 addition & 1 deletion common.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (
const OPSFILE = "opsfile.yml"
const OPSROOT = "opsroot.json"
const DOCOPTS_TXT = "docopts.txt"
const DOCOPTS_MD = "docopts.txt"
const DOCOPTS_MD = "docopts.md"

const PREREQ = "prereq.yml"
const CONFIGFILE = "config.json"
Expand Down
83 changes: 70 additions & 13 deletions ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ import (
"sort"
"strings"

"github.com/a8m/envsubst/parse"
"github.com/apache/openserverless-cli/tools"
docopt "github.com/docopt/docopt-go"
"github.com/mitchellh/go-homedir"
"golang.org/x/exp/slices"
"gopkg.in/yaml.v3"

envsubst "github.com/nuvolaris/envsubst/cmd/envsubstmain"
)

type TaskNotFoundErr struct {
Expand All @@ -40,18 +40,19 @@ func (e *TaskNotFoundErr) Error() string {
return fmt.Sprintf("no command named %s found", e.input)
}

func help() error {
if os.Getenv("OPS_NO_DOCOPTS") == "" && exists(".", DOCOPTS_TXT) {
os.Args = []string{"envsubst", "-no-unset", "-i", DOCOPTS_TXT}
return envsubst.EnvsubstMain()
func help(helpMessage string) error {

if helpMessage != "" {
fmt.Println(helpMessage)
return nil
}

// In case of syntax error, Task will return an error
list := "-l"
if os.Getenv("OPS_NO_DOCOPTS") != "" {
list = "--list-all"
}
_, err := Task("-t", OPSFILE, list)

return err
}

Expand Down Expand Up @@ -152,6 +153,55 @@ func loadSavedArgs() []string {
return res
}

// read docpts
// return the doppts and the help text
// expand the environment variables
// if the file is markdown expand the markdown
func readDocOpts() (string, string) {
if os.Getenv("OPS_NO_DOCOPTS") != "" {
if exists(".", DOCOPTS_TXT) {
fmt.Printf("Warning: ignoring %s - you have to provide all the options.\n", DOCOPTS_TXT)
}
if exists(".", DOCOPTS_MD) {
fmt.Printf("Warning: ignoring %s - you have to provide all the options.\n", DOCOPTS_MD)
}
return "", ""
}
if exists(".", DOCOPTS_MD) {
text := readfile(DOCOPTS_MD)

// parse embedded variables
restrictions := &parse.Restrictions{false, false, true}
result, err := (&parse.Parser{Name: "string", Env: os.Environ(), Restrict: restrictions, Mode: parse.AllErrors}).Parse(text)
if err != nil {
return "", err.Error()
}
// convert to markdown
help := tools.MarkdownToText(result)
// extract the embedded usage
opts := tools.ExtractUsage(result)

// warn if there is a docopts.txt
if exists(".", DOCOPTS_TXT) {
help = fmt.Sprintf("%s\nWarning: both %s and %s are present, %s ignored.",
help, DOCOPTS_TXT, DOCOPTS_MD, DOCOPTS_TXT)
}
return opts, help
}

if exists(".", DOCOPTS_TXT) {
text := readfile(DOCOPTS_TXT)
restrictions := &parse.Restrictions{false, false, true}
help, err := (&parse.Parser{Name: "string", Env: os.Environ(), Restrict: restrictions, Mode: parse.AllErrors}).Parse(text)
if err != nil {
help = err.Error()
}
return help, help
}

return "", ""
}

// Ops parses args moving into the folder corresponding to args
// then parses them with docopts and invokes the task
func Ops(base string, args []string) error {
Expand Down Expand Up @@ -209,9 +259,12 @@ func Ops(base string, args []string) error {
}
}

// read docopts and help text
opts, helpMessage := readDocOpts()

// print help
if len(rest) == 0 || rest[0] == "help" {
trace("print help")
err := help()
err := help(helpMessage)
if !isSubCmd {
fmt.Println()
return printPluginsHelp()
Expand All @@ -222,18 +275,22 @@ func Ops(base string, args []string) error {
// load saved args
savedArgs := loadSavedArgs()

// parsed args
if os.Getenv("OPS_NO_DOCOPTS") == "" && exists(".", DOCOPTS_TXT) {
// parse options if an opts file is available
trace("DOCOPTS:", opts)
if opts != "" {
debug("PREPARSE:", rest)
opts := readfile(DOCOPTS_TXT)
trace("DOCOPTS: size=", len(opts))

// parse args
parsedArgs := parseArgs(opts, rest)
trace("DOCOPTS: parsedargs=", parsedArgs)

// append -t optfile.yml to the Task cli
prefix := []string{"-t", OPSFILE}
if len(rest) > 0 && rest[0][0] != '-' {
prefix = append(prefix, rest[0])
}

// parse args
parsedArgs = append(savedArgs, parsedArgs...)
parsedArgs = append(prefix, parsedArgs...)
extra := os.Getenv("EXTRA")
Expand Down
4 changes: 2 additions & 2 deletions tests/base64.bats
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ setup() {

@test "-base64 help message" {
run ops -base64
assert_line "Usage: ops -base64 [options] <string>"
assert_line --partial "ops -base64 [options] <string>"

run ops -base64 -h
assert_line "Usage: ops -base64 [options] <string>"
assert_line --partial "ops -base64 [options] <string>"
}

@test "-base64 --encode" {
Expand Down
74 changes: 74 additions & 0 deletions tests/docopts.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

setup() {
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
export NO_COLOR=1
}

@test "legacy docops without markdown" {
# show the legacy docopts.txt
run ops docopts legacy
assert_success
assert_line --partial "legacy simple [-f]"
run ops docopts legacy simple
assert_line --partial "simple without flag"
run ops docopts legacy simple -f
assert_line "simple with flag"
}

@test "docops with markdown" {
run ops docopts
assert_success
assert_line --partial "--------"
assert_line --partial "Synopsis"
assert_line --partial "simple [-f]"

run env OPS_NO_DOCOPTS=1 ops docopts simple _f=false
assert_line --partial "Warning: ignoring docopts.md"
assert_line "simple without flag"
run env OPS_NO_DOCOPTS=1 ops docopts simple _f=true
assert_line --partial "Warning: ignoring docopts.md"
assert_line "simple with flag"

run ops docopts simple
assert_line "simple without flag"

run ops docopts simple -f
assert_line "simple with flag"

run ops docopts simple -g
assert_failure
assert_line "Usage:"
assert_line --partial "docopts simple [-f]"

}

@test "docops with both" {
# show the docopts.txt with a warning
run ops docopts both
assert_success
refute_line "This should be ignored"
assert_line --partial "both simple [-f]"
assert_line "Warning: both docopts.txt and docopts.md are present, docopts.txt ignored."

run ops docopts both simple -f
assert_success
assert_line "simple with flag"
}

12 changes: 12 additions & 0 deletions tests/olaris/docopts/both/docopts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Task `docopts both`

Simple task with flag

## Synopsis

```text
Usage:
both simple [-f]
```


2 changes: 2 additions & 0 deletions tests/olaris/docopts/both/docopts.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

This should be ignored
29 changes: 29 additions & 0 deletions tests/olaris/docopts/both/opsfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
version: "3"

tasks:
simple:
silent: true
desc: simple task in other
cmds:
- |
if {{.__f__}}
then echo simple with flag
else echo simple without flag
fi
10 changes: 10 additions & 0 deletions tests/olaris/docopts/docopts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Task `docopts`

Simple task with flag

## Synopsis

```text
Usage:
docopts simple [-f]
```
6 changes: 6 additions & 0 deletions tests/olaris/docopts/legacy/docopts.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Task: docopts legacy

Simple task with flag

Usage:
legacy simple [-f]
29 changes: 29 additions & 0 deletions tests/olaris/docopts/legacy/opsfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
version: "3"

tasks:
simple:
silent: true
desc: simple task in other
cmds:
- |
if {{._f}}
then echo simple with flag
else echo simple without flag
fi
29 changes: 29 additions & 0 deletions tests/olaris/docopts/opsfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
version: "3"

tasks:
simple:
silent: true
desc: simple task
cmds:
- |
if {{._f}}
then echo simple with flag
else echo simple without flag
fi
2 changes: 1 addition & 1 deletion tests/update.bats
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ setup() {
assert_line "Tasks downloaded successfully"
assert_line --partial "ensuring prerequisite coreutils"

OPS_VERSION=0.0.0 OPS_SKIP_UPDATE_CLI=1 run ops -update
run env OPS_VERSION=0.0.0 OPS_SKIP_UPDATE_CLI=1 ops -update
assert_line --partial "Your ops version (0.0.0) is older than the required version"
assert_success
assert_line "Trying to update ops..."
Expand Down
2 changes: 1 addition & 1 deletion tools/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "fmt"

func Example_markdown2text() {
fmt.Println(len(MarkdownToText(base64usage)))
// Output: 251
// Output: 945
}

func Example_extractUsage() {
Expand Down

0 comments on commit 79d5b61

Please sign in to comment.