Skip to content

feat: Add force mode, improve exception handling, correct debug log and direct command input with testing #365

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
164 changes: 107 additions & 57 deletions FABulous/FABulous.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import argparse
import os
from contextlib import redirect_stdout
from pathlib import Path

from loguru import logger

from FABulous.FABulous_CLI.FABulous_CLI import FABulous_CLI
from FABulous.FABulous_CLI.helper import (
create_project,
install_oss_cad_suite,
setup_global_env_vars,
setup_logger,
setup_project_env_vars,
install_oss_cad_suite,
)


Expand Down Expand Up @@ -50,28 +49,47 @@ def main():
description="The command line interface for FABulous"
)

parser.add_argument(
"project_dir",
help="The directory to the project folder",
)
create_group = parser.add_mutually_exclusive_group()

parser.add_argument(
create_group.add_argument(
"-c",
"--createProject",
default=False,
action="store_true",
help="Create a new project",
)

create_group.add_argument(
"-iocs",
"--install_oss_cad_suite",
help="Install the oss-cad-suite in the directory."
"This will create a new directory called oss-cad-suite in the provided"
"directory and install the oss-cad-suite there."
"If there is already a directory called oss-cad-suite, it will be removed and replaced with a new one."
"This will also automatically add the FAB_OSS_CAD_SUITE env var in the global FABulous .env file. ",
action="store_true",
default=False,
)

script_group = parser.add_mutually_exclusive_group()

parser.add_argument(
"project_dir",
default="",
nargs="?",
help="The directory to the project folder",
)

script_group.add_argument(
"-fs",
"--FABulousScript",
default="",
help="Run FABulous with a FABulous script. A FABulous script is a text file containing only FABulous commands"
"This will automatically exit the CLI once the command finish execution, and the exit will always happen gracefully.",
type=Path,
)
parser.add_argument(

script_group.add_argument(
"-ts",
"--TCLScript",
default="",
Expand All @@ -80,9 +98,16 @@ def main():
type=Path,
)

script_group.add_argument(
"-p",
"--commands",
help="execute <commands> (to chain commands, separate them with semicolon + whitespace: 'cmd1; cmd2')",
)

parser.add_argument(
"-log",
default=False,
default="",
type=Path,
nargs="?",
const="FABulous.log",
help="Log all the output from the terminal",
Expand Down Expand Up @@ -127,39 +152,42 @@ def main():
)

parser.add_argument(
"-iocs",
"--install_oss_cad_suite",
help="Install the oss-cad-suite in the directory."
"This will create a new directory called oss-cad-suite in the provided"
"directory and install the oss-cad-suite there."
"If there is already a directory called oss-cad-suite, it will be removed and replaced with a new one."
"This will also automatically add the FAB_OSS_CAD_SUITE env var in the global FABulous .env file. ",
"--force",
action="store_true",
default=False,
help="Force the command to run and ignore any errors. This feature does not work for the TCLScript argument",
)

parser.add_argument("--debug", action="store_true", help="Enable debug mode")

args = parser.parse_args()

setup_logger(args.verbose)
setup_logger(args.verbose, args.debug, log_file=args.log)

# Start with default value
projectDir = Path().cwd()

# Setup global and project env vars to load .env files
setup_global_env_vars(args)
setup_project_env_vars(args)

projectDir = Path(os.getenv("FAB_PROJ_DIR", args.project_dir)).absolute()
# Check if FAB_PROJ_DIR is set in environment (including from .env files)
if fab_proj_dir := os.getenv("FAB_PROJ_DIR", None):
projectDir = Path(fab_proj_dir).absolute().resolve()

args.top = projectDir.stem

if args.createProject and args.install_oss_cad_suite:
logger.error(
f"You cannot create a new project and install the oss-cad-suite at the same time."
)
exit(1)
# Finally, user provided argument takes highest priority
if args.project_dir:
projectDir = Path(args.project_dir).absolute().resolve()

if args.createProject:
create_project(projectDir, args.writer)
exit(0)

if not (projectDir / ".FABulous").exists():
logger.error(
"The directory provided is not a FABulous project as it does not have a .FABulous folder"
)
exit(1)

if not projectDir.exists():
logger.error(f"The directory provided does not exist: {projectDir}")
exit(1)
Expand All @@ -168,40 +196,62 @@ def main():
install_oss_cad_suite(projectDir, True)
exit(0)

if not (projectDir / ".FABulous").exists():
logger.error(
"The directory provided is not a FABulous project as it does not have a .FABulous folder"
)
exit(1)
else:
setup_project_env_vars(args)

fab_CLI = FABulous_CLI(
os.getenv("FAB_PROJ_LANG"),
projectDir,
Path().cwd(),
FABulousScript=args.FABulousScript,
TCLScript=args.TCLScript,
)
fab_CLI.debug = args.debug
fab_CLI = FABulous_CLI(
os.getenv("FAB_PROJ_LANG"),
projectDir,
Path().cwd(),
force=args.force,
)
fab_CLI.debug = args.debug
fabScript: Path = args.FABulousScript.absolute()
tclScript: Path = args.TCLScript.absolute()
logger.info(f"Setting current working directory to: {projectDir}")
cwd = Path().cwd()
os.chdir(projectDir)
fab_CLI.onecmd_plus_hooks("load_fabric")

if commands := args.commands:
commands = commands.split("; ")
for c in commands:
fab_CLI.onecmd_plus_hooks(c)
if fab_CLI.exit_code and not args.force:
logger.error(
f"Command '{c}' execution failed with exit code {fab_CLI.exit_code}"
)
exit(fab_CLI.exit_code)
else:
logger.info(
f'Commands "{"; ".join(i.strip() for i in commands)}" executed successfully'
)
exit(fab_CLI.exit_code)

elif fabScript != cwd:
fab_CLI.onecmd_plus_hooks(f"run_script {fabScript}")
if fab_CLI.exit_code:
logger.error(
f"FABulous script {args.FABulousScript} execution failed with exit code {fab_CLI.exit_code}"
)
else:
logger.info(f"FABulous script {args.FABulousScript} executed successfully")
exit(fab_CLI.exit_code)

elif tclScript != cwd:
fab_CLI.onecmd_plus_hooks(f"run_tcl {tclScript}")
if fab_CLI.exit_code:
logger.error(
f"TCL script {args.TCLScript} execution failed with exit code {fab_CLI.exit_code}"
)
else:
logger.info(f"TCL script {args.TCLScript} executed successfully")
exit(fab_CLI.exit_code)

else:
fab_CLI.interactive = True
if args.verbose == 2:
fab_CLI.verbose = True
if args.metaDataDir:
if Path(args.metaDataDir).exists():
metaDataDir = args.metaDataDir

if args.log:
with open(args.log, "w") as log:
with redirect_stdout(log):
logger.info("Logging to file: " + args.log)
logger.info(f"Setting current working directory to: {projectDir}")
os.chdir(projectDir)
fab_CLI.cmdloop()
else:
logger.info(f"Setting current working directory to: {projectDir}")
os.chdir(projectDir)
fab_CLI.cmdloop()

fab_CLI.cmdloop()
exit(0)


if __name__ == "__main__":
Expand Down
Loading