def copy( ctx: typer.Context, existing_task_spec_name: str, new_task_spec_name=typer.Argument(None), new_title: str = None, destination_dir: Path = None, new_extension: str = None, edit_after_write: bool = False, ): """Copy an old Task Spec to a new one with the provided name""" original_file: Path = task_spec_location(existing_task_spec_name) if original_file is None: warn_missing_file(existing_task_spec_name) return old_task_spec: TaskSpec = deserialize_task_spec_file(original_file) interactive = existing_task_spec_name is not None or new_task_spec_name is not None if interactive: extension_without_dot = original_file.suffix.lstrip(".") defaults = { "default_title": old_task_spec.title, "default_destination": original_file.parent, # TODO use friendly prefix here "default_extension": extension_without_dot, # TODO enum for extensions "edit_after_write": edit_after_write, } ( new_task_spec_name, new_title, destination_dir, new_extension, edit_after_write, ) = prompt_for_copy_args(**defaults) new_filename = f"{new_task_spec_name}.{new_extension}" new_task_spec: TaskSpec = old_task_spec.copy( update={"filename": new_filename, "title": new_title} ) try: writer.write(new_task_spec, destination_dir.expanduser()) except FileExistsError: if confirm_overwrite(new_task_spec_name): writer.write(new_task_spec, destination_dir.expanduser(), force=True) if edit_after_write: ctx.invoke(edit, task_spec_name=new_task_spec_name) success(f"Copy of {existing_task_spec_name} written to {destination_dir.resolve()}")
def new( ctx: typer.Context, task_spec_name: str = typer.Argument(None), destination_dir: Path = config.default_destination_dir, extension: str = "not", expert: bool = False, edit_after_write: bool = config.edit_after_write, overwrite: bool = False, interactive: bool = config.interactive_new, ): """Template out a new Task Spec to the nearest .nothing directory and open with $EDITOR. When no arguments are provided, Task Spec is configured interactively.""" if interactive or task_spec_name is None: defaults = { "default_extension": extension, "default_destination": destination_dir, "expert": expert, "edit_after_write": edit_after_write, } ( task_spec_name, extension, destination_dir, expert, edit_after_write, ) = prompt_for_new_args(**defaults) # XXX how to skip prompt when name is specified? task_spec_filename = f"{task_spec_name}.{extension}" task_spec: TaskSpec = ( TaskSpecCreate(filename=task_spec_filename) if not expert else TaskSpecCreateExpert(filename=task_spec_filename) ) try: writer.write( task_spec, destination_dir.expanduser(), force=interactive or overwrite ) except FileExistsError: if confirm_overwrite(task_spec_name): writer.write(task_spec, destination_dir.expanduser(), force=True) if edit_after_write: ctx.invoke(edit, task_spec_name=task_spec_name) success(f"{task_spec_filename} written to {destination_dir.resolve()}")
def reset( ctx: typer.Context, confirm: bool = typer.Option( ..., prompt="You're about to drop the database and re-create it. Continue?", confirmation_prompt=True, ), ): """Executes all "db" commands in sequence. Args: ctx (typer.Context): The command context confirm (bool): User's confirmation for destructive operation Raises: typer.Abort: If the user does not confirm the operation """ if not confirm: raise typer.Abort() ctx.invoke(db_init.db_init, drop=True) ctx.invoke(db_grid.db_grid) ctx.invoke(db_rankings.db_rankings)
def new( ctx: typer.Context, procedure_name: str = typer.Option( None, "--name", "-N", is_eager=True, help=glot["new_procedure_name_option_help"]), global_: bool = global_flag, skeleton: bool = typer.Option( "", "--skeleton", "-K", help=glot["new_skeleton_option_help"], flag_value="skeleton", callback=_must_be_called_with_name_callback, ), nothing: bool = typer.Option("", "--nothing", "-T", help=glot["new_nothing_flag_help"], flag_value="nothing"), edit_after: bool = edit_after_flag, overwrite: bool = typer.Option(False, "--overwrite", "-O", help=glot["new_overwrite_option_help"]), ): """Subcommand for creating new Procedures""" destination_dir = HOME_DOT_NOTHING_DIR if global_ else CWD_DOT_NOTHING_DIR prompt_display_defaults = { "name": procedure_name, "default_destination": friendly_prefix_for_path(destination_dir), "edit_after": edit_after, } # keep ur eye on the ball, there be mutants here # _which_procedure() needs these declared no matter what title = "" description = "" if not (skeleton or nothing): ( title, description, procedure_name, destination_dir, edit_after, ) = prompt_for_new_args(**prompt_display_defaults) # just in case the user gave a path with a ~ in it destination_dir = Path(destination_dir).expanduser() procedure_filename = f"{procedure_name}{PROCEDURE_EXT}" procedure = _which_procedure( skeleton or nothing, title=title, description=description, destination_dir=destination_dir, procedure_filename=procedure_filename, ) try: writer.write(procedure, force=overwrite) except FileExistsError: if confirm_overwrite(procedure.name): writer.write(procedure, force=True) # pylint: disable=import-outside-toplevel if edit_after: # this is a special occasion! from importlib import reload from . import filesystem # `state` in filesystem needs to be recalculated on account of the new # file in the directories it looks at. importlib does the trick! reload(filesystem) ctx.invoke(edit, procedure_name=procedure.name) success( glot.localized( "file_written", { "filename": procedure_filename, "destination": destination_dir.resolve() }, ))