{"id":22499198,"url":"https://github.com/kurt-steiner/ArgumentParser.jl","last_synced_at":"2025-10-16T18:30:29.943Z","repository":{"id":232443608,"uuid":"744955096","full_name":"nesteiner/ArgumentParser.jl","owner":"nesteiner","description":"simple command line argument parser written in Julia lang","archived":false,"fork":false,"pushed_at":"2024-07-19T04:59:41.000Z","size":21,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-07-19T12:35:22.784Z","etag":null,"topics":["command-line","command-line-tool","julia"],"latest_commit_sha":null,"homepage":"","language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nesteiner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-18T10:50:01.000Z","updated_at":"2024-07-19T04:59:44.000Z","dependencies_parsed_at":"2024-04-09T22:38:50.034Z","dependency_job_id":"73c110a1-e551-4218-81bd-15b5c3136477","html_url":"https://github.com/nesteiner/ArgumentParser.jl","commit_stats":null,"previous_names":["nesteiner/argumentparser.jl"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nesteiner%2FArgumentParser.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nesteiner%2FArgumentParser.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nesteiner%2FArgumentParser.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nesteiner%2FArgumentParser.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nesteiner","download_url":"https://codeload.github.com/nesteiner/ArgumentParser.jl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236738687,"owners_count":19196962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["command-line","command-line-tool","julia"],"created_at":"2024-12-06T22:12:24.460Z","updated_at":"2025-10-16T18:30:24.660Z","avatar_url":"https://github.com/nesteiner.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ArgumentParser.jl\n\n## Introduction\n\neh, this is a project-based-learning project, for building a simple command line argument parser.\nI don't know why there is not a lot of tutorial about how to build a library in of command line argument parser, so I create one with my own understanding.\nthis project is very simple, but I need issue and feedback to improve it, can you help me out ?\n\n## Usage\n\nthere are 4 arguments:\n\n```julia\nArgumentType = Union{String, \u003c:Number, Vector{String}, Vector{\u003c:Number}}\n\n@kwdef struct Argument{T \u003c: ArgumentType}\n    name::String\n    require::Bool = true\n    short::Union{Nothing, String} = nothing\n    long::Union{Nothing, String} = nothing\nend\n\nArgument(\n    T::Type{\u003c:ArgumentType};\n    name::String,\n    require::Bool = true,\n    short::Union{Nothing, String} = nothing,\n    long::Union{Nothing, String} = nothing) = Argument{T}(name = name, require = require, short = short, long = long)\n\n\neltype(::Argument{T}) where T = T\n```\n\n```julia\n@kwdef struct Flag\n    name::String\n    defaultValue::Bool\n    short::Union{Nothing, String} = nothing\n    long::Union{Nothing, String} = nothing\nend\n\nfunction Flag(; name::String, defaultValue::Bool, short::Union{Nothing, String} = nothing, long::Union{Nothing, String} = nothing) \n    if isnothing(short) \u0026\u0026 isnothing(long)\n        throw(DefinitionException(\"short and long cannot both be null\"))\n    end\n\n    Flag(name, defaultValue, short, long)\nend\n```\n\n```julia\nPositionedType = Union{String, \u003c:Number}\n\nstruct Positioned{T \u003c: PositionedType}\n    name::String\n    index::Int\n    require::Bool\nend\n\nPositioned(\n    T::Type{\u003c:PositionedType};\n    name::String,\n    index::Int,\n    require::Bool = true) = Positioned{T}(name, index, require)\n\n\neltype(::Positioned{T}) where T = T\n```\n\n```julia\n@kwdef struct SubCommand\n    name::String\n    require::Bool = true\nend\n```\n\nand there are some predicate function\n\n```julia\nhasargument(target::Vector{String}, argument::Argument{T}) where T \u003c: ArgumentType = any(x -\u003e matchShort(x, argument.short) || matchLong(x, argument.long) || matchName(x, argument.name), target)\n```\n\n```julia\nhasflag(target::Vector{String}, flag::Flag) = any(x -\u003e matchShort(x, flag.short) || matchShort(x, flag.long), target)\n```\n\n```julia\nhaspositioned(target::Vector{String}, positioned::Positioned{T}) where T \u003c: PositionedType = target[positioned.index] == position.name\n```\n\n```julia\nhassubcommand(target::Vector{String}, subcommand::SubCommand) = first(target) == subcommand.name\n```\n\nthe main idea for parsing the arguments is\n\n1. split the argv into `Vector{String}`\n2. use 4 types of arguments to construct parsing rules\n3. get result from `parseArguments`\n\n\n### simple usage\n\n1. `myapp -v`\n2. `myapp --version`\n\n```julia\nlet args = [\"-v\"]\n    flag = Flag(name = \"verbose\", short = \"-v\", long = \"--verbose\", defaultValue = false)\n    parseArguments(target = args, flags = [flag])\nend\n```\n\n### calculate \n\n1. `calculate 5 + 3`, expect ouput 8, **but I cannot describe it now**\n2. `calculate`, expect error\n\n### use argument\n\n1. `config-editor --set username admin --set password scretpassword`\n2. `config-editor --get username`, expect output `admin`\n3. `config-editor --set`, expect error for lack of pair of `--set`\n\n```julia\n# 1. \"config-editor --set username admin\"\n# 2. \"config-editor --set password password\"\nlet args1 = [\"--set\", \"username\", \"admin\"]\n    subcommand = SubCommand(name = \"--set\")\n    result = nothing\n    if hassubcommand(args1, subcommand)\n        argument = Argument(String, name = \"username\")\n        result = parseArguments(target = args1, subcommand = subcommand, arguments = [argument])\n    end\n\n    args2 = [\"--set\", \"password\", \"password\"]\n    if hassubcommand(args2, subcommand)\n        argument = Argument(String, name = \"password\")\n        merge!(result, parseArguments(target = args2, subcommand = subcommand, arguments = [argument]))\n    end\nend\n\nlet args = [\"--set\"]\n    subcommand = SubCommand(name = \"--set\")\n    argument = Argument(String, name = \"username\")\n    parseArguments(target = args, subcommand = subcommand, arguments = [argument])\nend\n```\n\n### operation on file\n\n1. `file-analyzer --file example.txt --count-lines`\n2. `file-analyzer --file non_existent_file.txt` expect error for file not exist\n\n```julia\n# 1. \"file-analyzer --file existfile.txt --count-lines\"\n# 2. \"file-analyzer --file non_existent_file.txt\"\nlet args1 = [\"--file\", \"/home/steiner/workspace/julia-scratch/ArgumentParser.jl/examples/examples.jl\", \"--count-lines\"]\n    argument = Argument(String, name = \"file\", long = \"--file\")\n    flag = Flag(name = \"count-lines\", long = \"--count-lines\", defaultValue = false)\n    parseArguments(target = args1, arguments = [argument], flags = [flag]) |\u003e println\n\n    args2 = [\"--file\", \"hello-world\", \"--count-lines\"]\n    result = parseArguments(target = args2, arguments = [argument], flags = [flag])\n\n    filepath = get(result, argument.name, nothing)\n    if !isnothing(filepath)\n        if !isfile(filepath)\n            throw(\"this file $filepath does not exist\")\n        end\n    end\nend\n```\n\n\n### complex arguments\n\n`search-tool -r /path/to/search -e \".txt,.docx\" -n \"keyword\"`\n\n```julia\nlet args = [\"-r\", \"examples.jl\", \"-e\", \".txt,docx\", \"-n\", \"keyword\"]\n    arguments = [\n        Argument(String, name = \"resource\", short = \"-r\"),\n        Argument(String, name = \"export\", short = \"-e\"),\n        Argument(String, name = \"n\", short = \"-n\")\n    ]\n\n    parseArguments(target = args, arguments = arguments)\nend\n```\n\n### for redirecting standard input / standard output\n\n1. `cat input.txt | text-filter --uppercase`\n2. `echo \"hello world\" | text-filter --reverse`\n\n### subcommand\n\n1. `git commit -m \"initial commit\"`\n2. `git branch new-feature`\n3. `git invalid-command`\n\n```julia\nlet args = [\"commit\", \"-m\", \"\\\"inital commit\\\"\"]\n    subcommand = SubCommand(name = \"commit\")\n    argument = Argument(String, name = \"message\", short = \"-m\")\n\n    parseArguments(target = args, subcommand = subcommand, arguments = [argument])\nend\n\nlet args = [\"branch\", \"new-feature\"]\n    subcommand = SubCommand(name = \"branch\")\n    positioned = Positioned(String, name = \"branch-name\", index = 2)\n    parseArguments(target = args, subcommand = subcommand, positions = [positioned])\nend\n```\n\n## Feature\n\n- [ ] multiple flags, for example `-abc`\n- [ ] handle `program 1 2 3 4`\n- [ ] handle `program 1 + 2`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkurt-steiner%2FArgumentParser.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkurt-steiner%2FArgumentParser.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkurt-steiner%2FArgumentParser.jl/lists"}