Milestone 1.
This commit is contained in:
91
cli.py
91
cli.py
@@ -1,7 +1,12 @@
|
||||
import os
|
||||
import sys
|
||||
import click
|
||||
import yaml
|
||||
|
||||
from app import create_app
|
||||
from app.config import load_config
|
||||
from app.services.vault import Vault
|
||||
from app.utils.time import now_iso_utc
|
||||
|
||||
|
||||
@click.group()
|
||||
@@ -17,9 +22,7 @@ def main():
|
||||
@click.option("--debug/--no-debug", default=True, show_default=True, help="Enable/disable debug mode")
|
||||
def runserver(vault_path: str | None, host: str, port: int, debug: bool):
|
||||
"""Run the development server."""
|
||||
# Prefer CLI vault over env
|
||||
cfg = load_config(vault_override=vault_path)
|
||||
# Mirror into environment for consistency if needed
|
||||
if cfg.VAULT_PATH:
|
||||
os.environ["KB_VAULT_PATH"] = cfg.VAULT_PATH
|
||||
os.environ["FLASK_DEBUG"] = "1" if debug else "0"
|
||||
@@ -28,5 +31,89 @@ def runserver(vault_path: str | None, host: str, port: int, debug: bool):
|
||||
app.run(host=host, port=port, debug=debug)
|
||||
|
||||
|
||||
@main.command("init")
|
||||
@click.option(
|
||||
"--vault",
|
||||
"vault_path",
|
||||
required=True,
|
||||
type=click.Path(file_okay=False, dir_okay=True, path_type=str),
|
||||
help="Path to the vault directory to initialize",
|
||||
)
|
||||
@click.option(
|
||||
"--sample/--no-sample",
|
||||
default=True,
|
||||
show_default=True,
|
||||
help="Create a sample welcome note",
|
||||
)
|
||||
@click.option(
|
||||
"--force",
|
||||
is_flag=True,
|
||||
default=False,
|
||||
help="Proceed even if the directory is not empty",
|
||||
)
|
||||
def init_vault(vault_path: str, sample: bool, force: bool):
|
||||
"""
|
||||
Initialize a vault directory with notes/, attachments/, and .kb/.
|
||||
Optionally create a sample note and a .kb/config.yml file.
|
||||
"""
|
||||
vault_path = os.path.abspath(vault_path)
|
||||
exists = os.path.exists(vault_path)
|
||||
|
||||
if exists:
|
||||
# Check emptiness only if directory exists
|
||||
try:
|
||||
entries = [e for e in os.listdir(vault_path) if not e.startswith(".")]
|
||||
except FileNotFoundError:
|
||||
entries = []
|
||||
if entries and not force:
|
||||
click.echo(
|
||||
click.style(
|
||||
f"Directory '{vault_path}' is not empty. Use --force to proceed.",
|
||||
fg="yellow",
|
||||
)
|
||||
)
|
||||
sys.exit(1)
|
||||
else:
|
||||
os.makedirs(vault_path, exist_ok=True)
|
||||
|
||||
v = Vault(vault_path)
|
||||
v.ensure_structure()
|
||||
|
||||
# Write .kb/config.yml if it doesn't exist
|
||||
kb_cfg_path = os.path.join(v.paths.kb, "config.yml")
|
||||
if not os.path.exists(kb_cfg_path):
|
||||
cfg_data = {
|
||||
"version": 1,
|
||||
"created": now_iso_utc(),
|
||||
}
|
||||
with open(kb_cfg_path, "w", encoding="utf-8") as f:
|
||||
yaml.safe_dump(cfg_data, f, sort_keys=True)
|
||||
click.echo(click.style(f"Created {kb_cfg_path}", fg="green"))
|
||||
else:
|
||||
click.echo(click.style(f"Exists {kb_cfg_path}", fg="blue"))
|
||||
|
||||
# Optionally create a sample note using the app context (reuses note writer)
|
||||
if sample:
|
||||
from app.services.notes_fs import create_note # lazy import to avoid app deps if not needed
|
||||
|
||||
# Build a minimal app context so create_note can resolve the vault
|
||||
cfg = load_config(vault_override=vault_path)
|
||||
app = create_app(cfg)
|
||||
with app.app_context():
|
||||
# Try to avoid duplicates by checking for an existing welcome file name
|
||||
title = "Welcome to your vault"
|
||||
body = (
|
||||
"# Welcome to your vault\n\n"
|
||||
"This is your first note. You can edit or delete it.\n\n"
|
||||
"- Notes live under `notes/`\n"
|
||||
"- Attachments go to `attachments/`\n"
|
||||
"- App internals go to `.kb/`\n"
|
||||
)
|
||||
note = create_note(title=title, body=body, tags=["welcome"])
|
||||
click.echo(click.style(f"Created sample note at {os.path.join(v.paths.root, note.rel_path)}", fg="green"))
|
||||
|
||||
click.echo(click.style(f"Vault initialized at {vault_path}", fg="green"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user