Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions data/completion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,8 @@ complete:
desc: A YAML format
- name: '-h'
desc: Shows the help document
- name: '-i'
desc: Start an interactive prompt (requires file= or data=) to configure input, transforms, and output
- name: help=
desc: If true will show the help document or other available -e.g. filters, template-
opts:
Expand Down
4 changes: 4 additions & 0 deletions data/usage.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"Option": "-h",
"Description": "Show this document"
},
{
"Option": "-i",
"Description": "Start an interactive prompt (requires file= or data=) to configure input, transforms, and output"
},
{
"Option": "help",
"Description": "Alternative way to show this document or others (e.g. filters, template)"
Expand Down
1 change: 1 addition & 0 deletions src/docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Takes an input, usually a data structure such as json, and transforms it to an e
| Option | Description |
|--------|-------------|
| -h | Show this document |
| -i | Start an interactive prompt (requires file= or data=) to configure input, transforms, and output |
| help | Alternative way to show this document or others (e.g. filters, template) |
| file | The file to parse (if not provided stdin is used) |
| cmd | Alternative to file and stdin to execute a command (e.g. kubectl, docker) to get the file contents |
Expand Down
67 changes: 65 additions & 2 deletions src/oafp.source.js.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ const showVersion = () => {
if ("undefined" == typeof params.file && "undefined" == typeof params.cmd && "undefined" == typeof params.data && "undefined" == typeof params.url) {
let _found = __
for (let key in params) {
if ("undefined" == typeof _found && params[key] === "" && key != "-debug" && key != "-v" && key != "-examples") {
if ("undefined" == typeof _found && params[key] === "" && key != "-debug" && key != "-v" && key != "-examples" && key != "-i") {
_found = key
break;
}
Expand Down Expand Up @@ -436,6 +436,69 @@ if (params["-examples"] == "" || (isString(params.examples) && params.examples.l
delete params["-examples"]
}

const _askInteractive = () => {
if (isUnDef(askStruct)) _exit(-1, "ERROR: -i requires OpenAF askStruct support.")
if (isUnDef(params.file) && isUnDef(params.data)) _exit(-1, "ERROR: -i requires file= or data=.")

let inputTypes = Array.from(_inputFns.keys()).filter(r => r != "?").sort()
let outputTypes = Array.from(_outputFns.keys()).filter(r => r != "?").sort()
let questions = [
{ name: "inputType", prompt: "Input type (auto to detect)", type: "choose", options: [ "auto" ].concat(inputTypes) },
{ name: "inputOptions", prompt: "Input options (JSON/SLON map; leave empty to skip): ", type: "question" },
{ name: "inputFilters", prompt: "Input filters (JSON/SLON map for ifrom/isql; leave empty to skip): ", type: "question" },
{ name: "transformOptions", prompt: "Transform options (JSON/SLON map; leave empty to skip): ", type: "question" },
{ name: "outputType", prompt: "Output format (default to keep)", type: "choose", options: [ "default" ].concat(outputTypes) },
{ name: "outputOptions", prompt: "Output options (JSON/SLON map; leave empty to skip): ", type: "question" },
{ name: "outputFilters", prompt: "Output filters (JSON/SLON map for path/from/sql/opath; leave empty to skip): ", type: "question" },
{ name: "extraOptions", prompt: "Extra options (JSON/SLON map; leave empty to skip): ", type: "question" }
]

__initializeCon()
__conConsole = true
__con.getTerminal().settings.set("-icanon min 1 -echo")
let answers = askStruct(questions)
__con.getTerminal().settings.set("icanon echo")
print("")

let answersMap = {}
if (isArray(answers)) {
answers.forEach(r => {
if (isMap(r) && isDef(r.name)) answersMap[r.name] = r.answer
})
}

const _applyMap = (label, value) => {
if (!isString(value)) return
let _v = value.trim()
if (_v.length == 0) return
let _m = _fromJSSLON(_v)
if (!isMap(_m)) _exit(-1, "ERROR: " + label + " must be a JSON/SLON map.")
Object.keys(_m).forEach(k => params[k] = _m[k])
}

if (isString(answersMap.inputType)) {
let _t = answersMap.inputType.trim()
if (_t.length > 0 && _t != "auto") params.type = _t
}

if (isString(answersMap.outputType)) {
let _t = answersMap.outputType.trim()
if (_t.length > 0 && _t != "default") params.format = _t
}

_applyMap("Input options", answersMap.inputOptions)
_applyMap("Input filters", answersMap.inputFilters)
_applyMap("Transform options", answersMap.transformOptions)
_applyMap("Output options", answersMap.outputOptions)
_applyMap("Output filters", answersMap.outputFilters)
_applyMap("Extra options", answersMap.extraOptions)

procParams()
delete params["-i"]
}

if (params["-i"] == "" || toBoolean(params["-i"]) || toBoolean(params.interactive)) _askInteractive()

// Read input from stdin or file
var _res = "", noFurtherOutput = false

Expand Down Expand Up @@ -649,4 +712,4 @@ if (isNumber(params.loop)) {
// Close streams
if (typeof global.__oafp_streams !== "undefined") Object.keys(global.__oafp_streams).forEach(s => global.__oafp_streams[s].s.close())
}
oafp(_params)
oafp(_params)
8 changes: 7 additions & 1 deletion src/tests/autoTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@
}
}

exports.testInteractiveRequiresInput = function() {
var _r = $sh([getOpenAFPath() + "/oaf", "-f", "../oafp.source.js", "-e", "-i"]).get(0)
ow.test.assert(_r.exitcode > 0, true, "Problem with -i requires file or data (exitcode)")
ow.test.assert(String(_r.stderr).indexOf("requires file= or data=") >= 0, true, "Problem with -i requires file or data (message)")
}

// Transforms
// ----------
exports.testMerge = function() {
Expand Down Expand Up @@ -320,4 +326,4 @@
var _r2 = $sh([getOpenAFPath() + "/oaf", "-f", "../oafp.source.js", "-e", "in=csv inputcsv=\"(withDelimiter: '|')\" correcttypes=true out=json file=" + _f2]).get(0)
ow.test.assert(compare(jsonParse(_r2.stdout), data1), true, "Problem with csv to json")
}
})()
})()
9 changes: 8 additions & 1 deletion src/tests/autoTest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ todo:
- oafp::NDJSON2JSON
- oafp::NDJSON2JSON_2
- oafp::NDJSON2JSON_2p
- oafp::interactiveRequiresInput

- oafp::merge
- oafp::sortMapKeys
Expand Down Expand Up @@ -140,6 +141,13 @@ jobs:
args:
func: "global.test.testNDJSON2JSON_2p()"

# -------------------------------
- name: oafp::interactiveRequiresInput
to : oJob Test
deps: Load test
args:
func: "global.test.testInteractiveRequiresInput()"

# -----------------
- name: oafp::merge
to : oJob Test
Expand Down Expand Up @@ -223,4 +231,3 @@ jobs:
if (args.results.fail > 0) printErr("There are failed tests")
io.writeFileString("oafp-test.md", ow.test.toMarkdown())
io.writeFileJSON("oafp-test.json", args.results)