Skip to content

Commit

Permalink
Added top level 'croco' application to the CLI, and updated the CLI s…
Browse files Browse the repository at this point in the history
…o that the __main__.py file doesn't have to be updated when adding cli options. Updated all modules to improve help output (#30)
  • Loading branch information
zachsa committed Apr 19, 2023
1 parent 8778692 commit 52cf6b6
Show file tree
Hide file tree
Showing 14 changed files with 128 additions and 77 deletions.
113 changes: 48 additions & 65 deletions toolkit/__main__.py
Original file line number Diff line number Diff line change
@@ -1,73 +1,56 @@
# To register a new app (i.e. a top level CLI command), add code to the "define",
# "parse", and "applications" folders. Look at other examples in those folders
# for the required signatures. You should not need to update this file to create
# additional CLI commands

import argparse
import os
from cli.define import (
lacce as define_lacce,
mhw as define_mhw,
ops as define_ops,
kerchunk as define_kerchunk,
update as define_update,
pg as define_pg,
)
from cli.parse import (
lacce as parse_lacce,
mhw as parse_mhw,
ops as parse_ops,
kerchunk as parse_kerchunk,
update as parse_update,
pg as parse_pg,
)
from cli.applications import lacce, mhw, ops, kerchunk, update, pg

prog = "somisana"
description = "SOMISANA Toolkit"
version = os.getenv("TOOLKIT_VERSION", "development")
import cli.define as define
import cli.parse as parse
import cli.applications as apps

REGISTERED_APPS = apps.__all__

def main():
parser = argparse.ArgumentParser(prog=prog, description=description)
parser.add_argument("-v", "--version", action="version", version=version)
module_parser = parser.add_subparsers(
title="Toolkit modules",
description="Sub-programs that are part of the SOMISANA toolkit",
dest="command",
metavar="Applications",
# Validate that define, parse, applications are all exporting the same modules. This is required to
# build the CLI correctly
if not sorted(define.__all__) == sorted(parse.__all__) == sorted(apps.__all__):
raise Exception(
"Please check the __all__ exports in the top level cli module exports. They should be equivalent"
)

# (1) Build commands
mhw_app = define_mhw.build(module_parser)
ops_app = define_ops.build(module_parser)
lacce_app = define_lacce.build(module_parser)
kerchunk_app = define_kerchunk.build(module_parser)
update_app = define_update.build(module_parser)
pg_app = define_pg.build(module_parser)

# (2) Parse command string
args = parser.parse_args()
prog = "somisana"
description = "SOMISANA Toolkit"
version = os.getenv("TOOLKIT_VERSION", "development")
parser = argparse.ArgumentParser(prog=prog, description=description)
parser.add_argument("-v", "--version", action="version", version=version)
module_parser = parser.add_subparsers(
title="Toolkit modules",
description="Sub-programs that are part of the SOMISANA toolkit",
dest="command",
metavar="Applications",
)

# (3) Select the application by parsing flag options
exe = (
parse_ops.parse(ops_app, args, ops)
if args.command == "ops"
else parse_mhw.parse(mhw_app, args, mhw)
if args.command == "mhw"
else parse_lacce.parse(lacce_app, args, lacce)
if args.command == "lacce"
else parse_kerchunk.parse(kerchunk_app, args, kerchunk)
if args.command == "kerchunk"
else parse_update.parse(update_app, args, update)
if args.command == "update"
else parse_pg.parse(pg_app, args, pg)
if args.command == "pg"
else None
# (1) Build applications
app_objects = {
app: (
getattr(getattr(define, app), "build")(module_parser),
getattr(apps, app),
)

# (4) Execute the application
if not exe:
parser.print_help()
return
else:
exe(args)


if __name__ == "__main__":
main()
for app in REGISTERED_APPS
}

# (2) Parse command string
args = parser.parse_args()

# (3) Retrieve the specific applications function to run from commands and flags
try:
app, data = app_objects[args.command]
exe = getattr(getattr(parse, args.command), "parse")(app, args, data)
except:
exe = None

# (4) Execute the application
if not exe:
parser.print_help()
else:
exe(args)
4 changes: 2 additions & 2 deletions toolkit/cli/applications/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from cli.applications import lacce, mhw, ops, kerchunk, update, pg
from cli.applications import lacce, mhw, ops, kerchunk, update, pg, croco

__all__ = ["lacce", "mhw", "ops", "kerchunk", "update", "pg"]
__all__ = ["lacce", "mhw", "ops", "kerchunk", "update", "pg", "croco"]
3 changes: 3 additions & 0 deletions toolkit/cli/applications/croco/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from cli.applications.croco.process import process

__all__ = ["process"]
3 changes: 3 additions & 0 deletions toolkit/cli/applications/croco/process/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def process(args):
input = args.input
print("CROCO stub", input)
4 changes: 2 additions & 2 deletions toolkit/cli/define/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from cli.define import lacce, mhw, ops, kerchunk, update, pg
from cli.define import lacce, mhw, ops, kerchunk, update, pg, croco

__all__ = ["lacce", "mhw", "ops", "kerchunk", "update", "pg"]
__all__ = ["lacce", "mhw", "ops", "kerchunk", "update", "pg", "croco"]
19 changes: 19 additions & 0 deletions toolkit/cli/define/croco/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
def build(module_parser):
croco = module_parser.add_parser("croco", help="CROCO module")
croco_parser = croco.add_subparsers(
title="CROCO",
description="CROCO-tooling",
dest="croco_command",
metavar="Available commands",
)

# Post processing script(s?)
croco_post_processing = croco_parser.add_parser(
"process", help="Post processing functions"
)
croco_post_processing.add_argument(
"--input",
default=".input",
help="Some input path",
)
return croco
4 changes: 2 additions & 2 deletions toolkit/cli/parse/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from cli.parse import lacce, mhw, ops, kerchunk, update, pg
from cli.parse import lacce, mhw, ops, kerchunk, update, pg, croco

__all__ = ["lacce", "mhw", "ops", "kerchunk", "update", "pg"]
__all__ = ["lacce", "mhw", "ops", "kerchunk", "update", "pg", "croco"]
10 changes: 10 additions & 0 deletions toolkit/cli/parse/croco/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def parse(cmd, args, module):
if args.croco_command == "process":
return module.process
else:

def e(*args):
print(cmd.format_help())
exit()

return e
7 changes: 6 additions & 1 deletion toolkit/cli/parse/kerchunk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@ def parse(cmd, args, module):
if args.kerchunk_command == "run":
return module.run
else:
print(cmd.format_help())

def e(*args):
print(cmd.format_help())
exit()

return e
8 changes: 7 additions & 1 deletion toolkit/cli/parse/lacce/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@ def parse(cmd, args, module):
if input and output:
print("LACCE", input, output)
return lambda: print("Not implemented")
print(cmd.format_help())
else:

def e(*args):
print(cmd.format_help())
exit()

return e
7 changes: 6 additions & 1 deletion toolkit/cli/parse/mhw/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@ def parse(cmd, args, module):
if args.mhw_command == "start":
return module.start
else:
print(cmd.format_help())

def e(*args):
print(cmd.format_help())
exit()

return e
7 changes: 6 additions & 1 deletion toolkit/cli/parse/ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ def parse(cmd, args, module):
elif args.ops_command == "load":
return module.load
else:
print(cmd.format_help())

def e(*args):
print(cmd.format_help())
exit()

return e
8 changes: 7 additions & 1 deletion toolkit/cli/parse/pg/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
def parse(cmd, args, module):
if args.pg_command == "raster2pgsql":
return module.raster2pgsql
print(cmd.format_help())
else:

def e(*args):
print(cmd.format_help())
exit()

return e
8 changes: 7 additions & 1 deletion toolkit/cli/parse/update/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ def parse(cmd, args, module):
raise Exception("Please specify either reset or version flags")
if version or reset:
return module.update_bashrc
print(cmd.format_help())
else:

def e(*args):
print(cmd.format_help())
exit()

return e

0 comments on commit 52cf6b6

Please sign in to comment.