Skip to content

Commit c294ece

Browse files
committed
dftech add command
Fixes #25
1 parent 57da6d6 commit c294ece

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

dfetch/__main__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from rich.console import Console
1111

12+
import dfetch.commands.add
1213
import dfetch.commands.check
1314
import dfetch.commands.diff
1415
import dfetch.commands.environment
@@ -43,6 +44,7 @@ def create_parser() -> argparse.ArgumentParser:
4344
parser.set_defaults(func=_help)
4445
subparsers = parser.add_subparsers(help="commands")
4546

47+
dfetch.commands.add.Add.create_menu(subparsers)
4648
dfetch.commands.check.Check.create_menu(subparsers)
4749
dfetch.commands.diff.Diff.create_menu(subparsers)
4850
dfetch.commands.environment.Environment.create_menu(subparsers)

dfetch/commands/add.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
"""*Dfetch* can add projects through the cli to the manifest.
2+
3+
Sometimes you want to add a project to your manifest, but you don't want to
4+
edit the manifest by hand. With ``dfetch add`` you can add a project to your manifest
5+
through the command line. This will add the project to your manifest and fetch it
6+
to your disk. You can also specify a version to add, or it will be added with the
7+
latest version available.
8+
9+
"""
10+
11+
import argparse
12+
from pathlib import Path
13+
14+
import yaml
15+
from rich.console import Console
16+
from rich.prompt import Prompt
17+
from rich.table import Table
18+
19+
import dfetch.commands.command
20+
import dfetch.manifest.project
21+
import dfetch.project
22+
from dfetch.log import get_logger
23+
from dfetch.manifest.manifest import ManifestDumper
24+
from dfetch.manifest.project import ProjectEntry, ProjectEntryDict
25+
from dfetch.project import create_sub_project, create_super_project
26+
from dfetch.util.util import in_directory
27+
28+
console = Console()
29+
30+
logger = get_logger(__name__)
31+
32+
33+
class Add(dfetch.commands.command.Command):
34+
"""Add a new project to the manifest.
35+
36+
Add a new project to the manifest.
37+
"""
38+
39+
@staticmethod
40+
def create_menu(subparsers: dfetch.commands.command.SubparserActionType) -> None:
41+
"""Add the parser menu for this action."""
42+
parser = dfetch.commands.command.Command.parser(subparsers, Add)
43+
44+
parser.add_argument(
45+
"remote_url",
46+
metavar="<remote_url>",
47+
type=str,
48+
nargs=1,
49+
help="Remote URL of project to add",
50+
)
51+
52+
def __call__(self, args: argparse.Namespace) -> None:
53+
"""Perform the add."""
54+
superproject = create_super_project()
55+
56+
with in_directory(superproject.root_directory):
57+
58+
project_entry = ProjectEntry(
59+
ProjectEntryDict(name="project-to-be-added", url=args.remote_url[0])
60+
)
61+
62+
subproject = create_sub_project(project_entry)
63+
64+
manifest = superproject.manifest
65+
66+
if project_entry.name in [p.name for p in manifest.projects]:
67+
raise RuntimeError(
68+
f"Project with name {project_entry.name} already exists in manifest!"
69+
)
70+
71+
project_entry = ProjectEntry(
72+
ProjectEntryDict(
73+
name=project_entry.name,
74+
url=project_entry.remote_url,
75+
branch=subproject.get_default_branch(),
76+
)
77+
)
78+
79+
if not confirm(project_entry):
80+
console.print("[yellow]Aborted[/yellow]")
81+
return
82+
83+
with Path(manifest.path).open("a", encoding="utf-8") as manifest_file:
84+
85+
new_entry = yaml.dump(
86+
[project_entry.as_yaml()],
87+
Dumper=ManifestDumper,
88+
sort_keys=False,
89+
# line_break=os.linesep,
90+
indent=2,
91+
)
92+
manifest_file.write("\n")
93+
for line in new_entry.splitlines():
94+
manifest_file.write(f" {line}\n")
95+
96+
console.print("[bold green]✔ Project added successfully[/bold green]")
97+
98+
99+
def confirm(project: ProjectEntry) -> bool:
100+
"""Show a confirmation prompt to the user before adding the project."""
101+
table = Table(title="Confirm dfetch add", show_lines=True)
102+
table.add_column("Field", style="bold")
103+
table.add_column("Value", style="cyan")
104+
105+
for k, v in project.as_yaml().items():
106+
table.add_row(k, str(v))
107+
108+
console.clear()
109+
console.print(table)
110+
111+
return Prompt.ask("Proceed?", choices=["y", "n"], default="y") == "y"

0 commit comments

Comments
 (0)