From 5fc6c736905f13f1d6be78fd9d06801898fb1998 Mon Sep 17 00:00:00 2001 From: ganmodokix <1450602+ganmodokix@users.noreply.github.com> Date: Sun, 16 Aug 2026 15:49:36 +0900 Subject: [PATCH] Update docs and messages of ysn tools --- README.md | 32 ++++++++++++++++++++++++++------ bin/find.py | 12 +++++++++--- bin/lf | 2 +- bin/ly | 11 +++++++++++ bin/ysn | 2 +- bin/ysn.py | 40 ++++++++++++++++++++++++++++++++-------- documentation.md | 7 ++++--- pyproject.toml | 1 - setup.sh | 6 +----- 9 files changed, 85 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 0edcc5c..32ca34b 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,11 @@ Requirements: - `g++-15` (for AtCoder-compatible compilation) - `uv` is optional; `setup.sh` falls back to `venv` and `pip` - `tree` is optional for `ly` -- Graphviz `dot` is optional for Graphviz output Run the setup script from the repository root: ``` -$ ./setup.sh +$ bash setup.sh ``` The script creates `.env` and installs the Python dependencies listed in `pyproject.toml`. @@ -29,12 +28,27 @@ $ export PATH="$PWD/bin:$PATH" You may want to put the corresponding absolute path in your shell configuration. ## Usage -Runs `hoge.cpp` (create and copy the base template if not created) by +Create, compile, and run `hoge.cpp` with: + ``` $ ysn hoge ``` +Pass the source path without the `.cpp` extension. If `hoge.cpp` does not +exist, `ysn` creates it from the base template. The compiled executable is +written to `hoge.exe`. + +Compile without running, or force recompilation, with: + +``` +$ ysn hoge --just +$ ysn hoge --force +``` + +The short forms are `-j` and `-f`, respectively. + Install or remove templates as + ``` $ ysn hoge --install modint1e9p7 --remove modint998244353 ``` @@ -43,8 +57,14 @@ or briefly $ ysn hoge -i modint1e9p7 -r modint998244353 ``` -(for debigging) you can see the dependency graph by +Template names are paths relative to `template/`; the `.hpp` extension is +optional. Dependencies included with `#include "..."` are expanded +recursively. Installing or removing templates only rewrites the source, so run +`ysn hoge` afterward to compile and execute it. + +Search or list available templates with: + ``` -$ ysn hoge -i modint1e9p7 -r modint998244353 -d hoge.svg +$ lf modint +$ ly ``` -(`.svg` can be replaced by `.pdf`, `.png` etc) diff --git a/bin/find.py b/bin/find.py index f76b32f..858da33 100644 --- a/bin/find.py +++ b/bin/find.py @@ -7,8 +7,15 @@ ysn_path = Path(__file__).parent.parent template_path = ysn_path / "template" - parser = argparse.ArgumentParser() - parser.add_argument("query", type=str, help="search query") + parser = argparse.ArgumentParser( + prog="lf", + description="Find templates by a case-sensitive substring of their path." + ) + parser.add_argument( + "query", + metavar="QUERY", + help="substring to search for under template/", + ) args = parser.parse_args() query = args.query @@ -17,4 +24,3 @@ item = str(candidate_path.relative_to(template_path)) if query in item: print(item) - diff --git a/bin/lf b/bin/lf index de57ab3..56d6be6 100755 --- a/bin/lf +++ b/bin/lf @@ -6,7 +6,7 @@ PROJ_DIR="$(dirname "$SCRIPT_DIR")" VENV_ACTIVATE="$PROJ_DIR/.env/bin/activate" if [ ! -f "$VENV_ACTIVATE" ]; then - printf 'Python environment is missing. Run ./setup.sh from %s first.\n' "$PROJ_DIR" >&2 + printf 'Python environment is missing. Run bash setup.sh from %s first.\n' "$PROJ_DIR" >&2 exit 1 fi diff --git a/bin/ly b/bin/ly index 5f561fe..f4eeaf0 100755 --- a/bin/ly +++ b/bin/ly @@ -5,6 +5,17 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJ_DIR="$(dirname "$SCRIPT_DIR")" TEMPLATE_DIR="$PROJ_DIR/template" +if [ "$#" -gt 0 ]; then + if [ "$#" -eq 1 ] && { [ "$1" = "-h" ] || [ "$1" = "--help" ]; }; then + printf 'usage: ly\n\nList the template/ directory tree.\n' + exit 0 + fi + + printf 'ly: unexpected argument: %s\n' "$1" >&2 + printf 'usage: ly\n' >&2 + exit 2 +fi + if ! command -v tree >/dev/null 2>&1; then printf 'tree command is missing. Install tree to use ly.\n' >&2 exit 1 diff --git a/bin/ysn b/bin/ysn index 7d42161..dd95ef3 100755 --- a/bin/ysn +++ b/bin/ysn @@ -7,7 +7,7 @@ VENV_ACTIVATE="$PROJ_DIR/.env/bin/activate" # Most paths still need Python, so fail early with a setup hint if the venv is missing. if [ ! -f "$VENV_ACTIVATE" ]; then - printf 'Python environment is missing. Run ./setup.sh from %s first.\n' "$PROJ_DIR" >&2 + printf 'Python environment is missing. Run bash setup.sh from %s first.\n' "$PROJ_DIR" >&2 exit 1 fi diff --git a/bin/ysn.py b/bin/ysn.py index d0323f5..21ed999 100644 --- a/bin/ysn.py +++ b/bin/ysn.py @@ -23,14 +23,38 @@ def normalize_module_name(module_name: str) -> str: if __name__ == "__main__": - parser = argparse.ArgumentParser() - - parser.add_argument("source_path", type=str, help="C++ source file to be templated") - parser.add_argument("--force", "-f", action="store_true", help="compile even though the source is not modified") - parser.add_argument("--just", "-j", action="store_true", help="just compile, not execute") - parser.add_argument("--install", "-i", type=str, nargs="*", help="install template if specified") - parser.add_argument("--remove", "-r", type=str, nargs="*", help="remove template if specified") - parser.add_argument("--dependency-graph", "-d", type=str, help="output dependency graph if specified") + parser = argparse.ArgumentParser( + prog="ysn", + description="Create, compile, run, and rewrite a templated C++ source.", + epilog=( + "Pass SOURCE without the .cpp extension (for example, 'ysn a' uses " + "a.cpp). --install and --remove only rewrite the source; run ysn " + "again without them to compile and execute. Use 'lf QUERY' to find " + "templates and 'ly' to list the template directory tree." + ), + ) + + parser.add_argument( + "source_path", + metavar="SOURCE", + help="source path without the .cpp extension", + ) + parser.add_argument( + "--force", "-f", action="store_true", + help="recompile even when the executable is newer than the source", + ) + parser.add_argument( + "--just", "-j", action="store_true", + help="compile without executing", + ) + parser.add_argument( + "--install", "-i", metavar="MODULE", nargs="*", + help="install templates (paths relative to template/, .hpp optional)", + ) + parser.add_argument( + "--remove", "-r", metavar="MODULE", nargs="*", + help="remove installed templates (.hpp optional)", + ) args = parser.parse_args() diff --git a/documentation.md b/documentation.md index e12cdb3..7561b99 100644 --- a/documentation.md +++ b/documentation.md @@ -51,7 +51,7 @@ ysn ``` 指定した C++ ソースをコンパイルして実行します。 -ソース名の `.cpp` は省略でき、たとえば `ysn a` は `a.cpp` を対象にします。 +ソース名は `.cpp` を付けずに指定し、たとえば `ysn a` は `a.cpp` を対象にします。 ソースが存在しない場合は `bin/__base__.cpp` から新規作成し、テンプレート展開用の領域を初期化します。 実行ファイルはソース名に対応する `.exe` として作成されます。 @@ -66,6 +66,7 @@ ysn -r `--install` は `-i`、`--remove` は `-r` と省略できます。 モジュール名は `template/` からの相対パスで指定し、拡張子を省略した場合は `.hpp` として扱われます。 指定したモジュールが他のヘッダを `#include "..."` している場合、その依存も再帰的に展開されます。 +追加・削除はソースの書き換えだけを行い、コンパイルや実行は行いません。書き換え後は改めて `ysn ` を実行します。 ```text ysn --just @@ -88,7 +89,7 @@ ly ### 内部構成 -`bin/ysn` は `.env` の Python 仮想環境を有効化して `bin/ysn.py` を呼び出す薄いシェルラッパーです。 +`bin/ysn` は、更新済みの実行ファイルを直接起動できる場合は fast path を使い、それ以外では `.env` の Python 仮想環境を有効化して `bin/ysn.py` を呼び出すシェルラッパーです。 `bin/ysn.py` は CLI 引数を解釈し、テンプレート編集が必要なら `engine.py`、コンパイル・実行が必要なら `run.py` に処理を渡します。 `bin/engine.py` はテンプレート展開の中核です。 @@ -106,7 +107,7 @@ ly `setup.sh` は `.env` を作成し、`pyproject.toml` に記述された Python 依存を導入します。 `uv` が使える環境では `uv venv` と `uv pip install` を使い、なければ標準の `venv` と `pip` にフォールバックします。 セットアップ時には `.env/pch/` に `bits/stdc++.h` 用のローカル PCH も作成し、以後の C++ コンパイルで利用します。 -`ly` や Graphviz 出力で使う `tree` と `dot` コマンドが見つからない場合は、追加で必要なシステムコマンドとして案内します。 +`ly` で使う `tree` コマンドが見つからない場合は、追加で必要なシステムコマンドとして案内します。 C++ 側のテストは `CMakeLists.txt` と `vcpkg.json` で管理されます。 `vcpkg.json` では `gtest` を依存として宣言し、`test/` 以下の `.cpp` を GTest 実行ファイルとしてビルドします。 diff --git a/pyproject.toml b/pyproject.toml index bb305fb..cd55a7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,6 +5,5 @@ description = "Template tools for competitive programming" readme = "README.md" requires-python = ">=3.11" dependencies = [ - "graphviz", "networkx", ] diff --git a/setup.sh b/setup.sh index 94d7aeb..d61f8c6 100644 --- a/setup.sh +++ b/setup.sh @@ -45,11 +45,7 @@ if ! command -v tree >/dev/null 2>&1; then missing_commands+=("tree") fi -if ! command -v dot >/dev/null 2>&1; then - missing_commands+=("graphviz") -fi - if [ "${#missing_commands[@]}" -ne 0 ]; then printf 'Missing optional system command(s): %s\n' "${missing_commands[*]}" - printf 'Install them with your system package manager if you use ly or Graphviz output.\n' + printf 'Install them with your system package manager if you use ly.\n' fi