diff options
| author | Opportunity <[email protected]> | 2020-01-15 14:58:36 +0800 |
|---|---|---|
| committer | Opportunity <[email protected]> | 2020-01-15 14:58:36 +0800 |
| commit | d7662a8916400389fca579772bfdaedadd5e640e (patch) | |
| tree | df62285c16883e1ac98101507cf90178b7c78941 | |
| parent | f4e30b5e7879d4dbfbe4424f5f9156cb6cfdaf50 (diff) | |
Improve basic parse
| -rw-r--r-- | xmake/core/base/option.lua | 64 | ||||
| -rw-r--r-- | xmake/core/base/task.lua | 56 | ||||
| -rw-r--r-- | xmake/core/main.lua | 44 |
3 files changed, 95 insertions, 69 deletions
diff --git a/xmake/core/base/option.lua b/xmake/core/base/option.lua index 8e5377667..c02a29659 100644 --- a/xmake/core/base/option.lua +++ b/xmake/core/base/option.lua @@ -183,40 +183,35 @@ function option.init(menu) local context = option.save() assert(context) - -- parse _ARGV - local argv = table.copy(xmake._ARGV) - local task_arg = "build" - if argv[1] and not argv[1]:startswith('-') then - -- regard it as command name - task_arg = argv[1] - table.remove(argv, 1) - end + -- check command + if xmake._COMMAND then - -- find the current task - for taskname, taskinfo in pairs(main.tasks) do + -- find the current task + for taskname, taskinfo in pairs(main.tasks) do - -- ok? - if taskname == task_arg or taskinfo.shortname == task_arg then - -- save this task - context.taskname = taskname - break + -- ok? + if taskname == xmake._COMMAND or taskinfo.shortname == xmake._COMMAND then + -- save this task + context.taskname = taskname + break + end end - end - -- not found? - if not context.taskname or not menu[context.taskname] then + -- not found? + if not context.taskname or not menu[context.taskname] then - -- print the main menu - option.show_main() + -- print the main menu + option.show_main() - -- invalid task - return false, "invalid task: " .. task_arg + -- invalid task + return false, "invalid task: " .. xmake._COMMAND + end end local options = table.wrap(option.taskmenu().options) -- parse remain parts - local results, err = option.parse(argv, options, {populate_defaults = false}) + local results, err = option.parse(xmake._COMMAND_ARGV, options, { populate_defaults = false }) if not results then option.show_menu(context.taskname) return false, err @@ -281,7 +276,11 @@ function option.parse(argv, options, opt) if match_opt and ((arg.type == "option" and match_opt[3] ~= "k") or (arg.type == "flag" and match_opt[3] == "k")) then results[match_opt[2] or match_opt[1]] = option.boolean(arg.value) else - return nil, string.format("Invalid %s: %s", arg.type, arg) + if opt.allow_unknown then + results[arg.key] = option.boolean(arg.value) + else + return nil, string.format("Invalid %s: %s", arg.type, arg) + end end elseif arg.type == "arg" then @@ -333,6 +332,23 @@ function option.parse(argv, options, opt) else -- failed + if opt.allow_unknown then + if arg.key then + results[arg.key] = arg.value + else + -- the option + local o = results["$ARGS"] + if not o then + results["$ARGS"] = {} + o = results["$ARGS"] + end + + -- append value + table.insert(o, arg.value) + end + else + return nil, string.format("Invalid %s: %s", arg.type, arg) + end return nil, "invalid argument: " .. arg.value end end diff --git a/xmake/core/base/task.lua b/xmake/core/base/task.lua index 03b87982d..97c8cec25 100644 --- a/xmake/core/base/task.lua +++ b/xmake/core/base/task.lua @@ -32,6 +32,37 @@ local sandbox = require("sandbox/sandbox") local config = require("project/config") local sandbox_os = require("sandbox/modules/os") +function task.common_options() + if not task._COMMON_OPTIONS then + task._COMMON_OPTIONS = + { + {'q', "quiet", "k", nil, "Quiet operation." } + , {'y', "yes", "k", nil, "Input yes by default if need user confirm." } + , {nil, "confirm", "kv", nil, "Input the given result if need user confirm.", + " - y|yes", + " - n|no", + " - d|def"} + , {'v', "verbose", "k", nil, "Print lots of verbose information for users." } + , {nil, "root", "k", nil, "Allow to run xmake as root." } + , {'D', "diagnosis", "k", nil, "Print lots of diagnosis information (backtrace, check info ..) only for developers." + , "And we can append -v to get more whole information." + , " e.g. $ xmake -v -D"} + , {nil, "profile", "k", nil, "Print performance data only for developers." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + , {} + , {'F', "file", "kv", nil, "Read a given xmake.lua file." } + , {'P', "project", "kv", nil, "Change to the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + , {category = "action"} + } + end + return task._COMMON_OPTIONS +end + -- the directories of tasks function task._directories() @@ -127,28 +158,9 @@ function task._translate_menu(menu) -- add common options, we need avoid repeat because the main/build task will be inserted twice if not menu._common_options then - table.insert(options, 1, {'q', "quiet", "k", nil, "Quiet operation." }) - table.insert(options, 2, {'y', "yes", "k", nil, "Input yes by default if need user confirm." }) - table.insert(options, 3, {nil, "confirm", "kv", nil, "Input the given result if need user confirm.", - " - y|yes", - " - n|no", - " - d|def"}) - table.insert(options, 4, {'v', "verbose", "k", nil, "Print lots of verbose information for users." }) - table.insert(options, 5, {nil, "root", "k", nil, "Allow to run xmake as root." }) - table.insert(options, 6, {'D', "diagnosis", "k", nil, "Print lots of diagnosis information (backtrace, check info ..) only for developers." - , "And we can append -v to get more whole information." - , " e.g. $ xmake -v -D"}) - table.insert(options, 7, {nil, "profile", "k", nil, "Print performance data only for developers." }) - table.insert(options, 8, {nil, "version", "k", nil, "Print the version number and exit." }) - table.insert(options, 9, {'h', "help", "k", nil, "Print this help message and exit." }) - table.insert(options, 10, {}) - table.insert(options, 11, {'F', "file", "kv", nil, "Read a given xmake.lua file." }) - table.insert(options, 12, {'P', "project", "kv", nil, "Change to the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" }) - table.insert(options, 13, {category = "action"}) + for i, v in ipairs(task.common_options()) do + table.insert(options, i, v) + end menu._common_options = true end end diff --git a/xmake/core/main.lua b/xmake/core/main.lua index a4517d0ca..e0504a376 100644 --- a/xmake/core/main.lua +++ b/xmake/core/main.lua @@ -118,34 +118,32 @@ function main._find_root(projectfile) return projectfile end --- the init function for main -function main._init() +function main._basicparse() - local argv = table.copy(xmake._ARGV) - if argv[1] and not argv[1]:startswith('-') then + -- check command + if xmake._ARGV[1] and not xmake._ARGV[1]:startswith('-') then -- regard it as command name - table.remove(argv, 1) + xmake._COMMAND = xmake._ARGV[1] + xmake._COMMAND_ARGV = table.move(xmake._ARGV, 2, -1, 1, {}) + else + xmake._COMMAND_ARGV = xmake._ARGV end - local pargv = cli.parsev(argv) - -- get project directory and project file from the argument option - local opt_projectdir, opt_projectfile - for _, arg in ipairs(pargv) do - if arg.type == 'option' then - if (arg.short and arg.key == 'P') or arg.key == 'project' then - if opt_projectdir then - return nil, "Duplicate arguments for PROJECT" - end - opt_projectdir = arg.value - elseif (arg.short and arg.key == 'F') or arg.key == 'file' then - if opt_projectfile then - return nil, "Duplicate arguments for FILE" - end - opt_projectfile = arg.value - end - end + -- parse options + local options, err = option.parse(xmake._COMMAND_ARGV, task.common_options(), { allow_unknown = true }) + if not options then + utils.error(err) end + return options.project, options.file +end + +-- the init function for main +function main._init() + + -- get project directory and project file from the argument option + local opt_projectdir, opt_projectfile = main._basicparse() + -- init the project directory local projectdir = opt_projectdir or xmake._PROJECT_DIR if projectdir and not path.is_absolute(projectdir) then @@ -166,7 +164,7 @@ function main._init() -- find the root project file if not os.isfile(projectfile) or (not opt_projectdir and not opt_projectfile) then - projectfile = main._find_root(projectfile) + projectfile = main._find_root(projectfile) end -- update and enter project |
