From e6a68813b7548f0e9820f814d002e16bf73c15b8 Mon Sep 17 00:00:00 2001 From: Thomas Walker Lynch Date: Wed, 19 Nov 2025 16:12:54 +0000 Subject: [PATCH] introduces the tool --- tool/skeleton_compaare | 1 + .../A_minus_B | 0 .../CLI.py | 2 +- .../GitIgnore.py | 0 .../Harmony.py | 0 .../Harmony_where | 0 .../check | 0 .../command.py | 0 .../doc.py | 82 ++++++++++--------- .../in_between_and_below | 0 .../load_command_module.py | 0 .../make_Harmony_tree_dict | 0 .../meta.py | 2 +- .../newer | 0 .../older | 0 .../skeleton.py | 40 +++++++-- .../temp.txt | 0 17 files changed, 77 insertions(+), 50 deletions(-) create mode 120000 tool/skeleton_compaare rename tool/{skeleton => skeleton_compare_source}/A_minus_B (100%) rename tool/{skeleton => skeleton_compare_source}/CLI.py (99%) rename tool/{skeleton => skeleton_compare_source}/GitIgnore.py (100%) rename tool/{skeleton => skeleton_compare_source}/Harmony.py (100%) rename tool/{skeleton => skeleton_compare_source}/Harmony_where (100%) rename tool/{skeleton => skeleton_compare_source}/check (100%) rename tool/{skeleton => skeleton_compare_source}/command.py (100%) rename tool/{skeleton => skeleton_compare_source}/doc.py (57%) rename tool/{skeleton => skeleton_compare_source}/in_between_and_below (100%) rename tool/{skeleton => skeleton_compare_source}/load_command_module.py (100%) rename tool/{skeleton => skeleton_compare_source}/make_Harmony_tree_dict (100%) rename tool/{skeleton => skeleton_compare_source}/meta.py (99%) rename tool/{skeleton => skeleton_compare_source}/newer (100%) rename tool/{skeleton => skeleton_compare_source}/older (100%) rename tool/{skeleton => skeleton_compare_source}/skeleton.py (92%) rename tool/{skeleton => skeleton_compare_source}/temp.txt (100%) diff --git a/tool/skeleton_compaare b/tool/skeleton_compaare new file mode 120000 index 0000000..bd0d011 --- /dev/null +++ b/tool/skeleton_compaare @@ -0,0 +1 @@ +skeleton_compare_source/CLI.py \ No newline at end of file diff --git a/tool/skeleton/A_minus_B b/tool/skeleton_compare_source/A_minus_B similarity index 100% rename from tool/skeleton/A_minus_B rename to tool/skeleton_compare_source/A_minus_B diff --git a/tool/skeleton/CLI.py b/tool/skeleton_compare_source/CLI.py similarity index 99% rename from tool/skeleton/CLI.py rename to tool/skeleton_compare_source/CLI.py index 46e810b..f7fb0b0 100755 --- a/tool/skeleton/CLI.py +++ b/tool/skeleton_compare_source/CLI.py @@ -50,7 +50,7 @@ import Harmony import meta import skeleton -meta.debug_set("print_command_lists") +# meta.debug_set("print_command_lists") # Command tag sets (classification universe) HELP_COMMANDS: set[str] = set([ diff --git a/tool/skeleton/GitIgnore.py b/tool/skeleton_compare_source/GitIgnore.py similarity index 100% rename from tool/skeleton/GitIgnore.py rename to tool/skeleton_compare_source/GitIgnore.py diff --git a/tool/skeleton/Harmony.py b/tool/skeleton_compare_source/Harmony.py similarity index 100% rename from tool/skeleton/Harmony.py rename to tool/skeleton_compare_source/Harmony.py diff --git a/tool/skeleton/Harmony_where b/tool/skeleton_compare_source/Harmony_where similarity index 100% rename from tool/skeleton/Harmony_where rename to tool/skeleton_compare_source/Harmony_where diff --git a/tool/skeleton/check b/tool/skeleton_compare_source/check similarity index 100% rename from tool/skeleton/check rename to tool/skeleton_compare_source/check diff --git a/tool/skeleton/command.py b/tool/skeleton_compare_source/command.py similarity index 100% rename from tool/skeleton/command.py rename to tool/skeleton_compare_source/command.py diff --git a/tool/skeleton/doc.py b/tool/skeleton_compare_source/doc.py similarity index 57% rename from tool/skeleton/doc.py rename to tool/skeleton_compare_source/doc.py index a8d5351..3198b96 100644 --- a/tool/skeleton/doc.py +++ b/tool/skeleton_compare_source/doc.py @@ -49,7 +49,6 @@ Where: :: structure | import | export | suspicious | addendum | all """ - def _help_text(prog: str) -> str: return f"""\ {prog} - Harmony skeleton integrity and metadata checker @@ -71,73 +70,76 @@ Argument rules (informal): are ignored. 2. We assume {prog} is run within the Harmony skeleton, or a skeleton - derived from it. This is the 'default skeleton', or more simply, 'A'. + derived directly from it. This is the 'default skeleton', or simply 'A'. 3. The path is the directory of a project that is assumed to be built upon the default skeleton. This second project root is - referred to as 'B'. + called 'B'. - 4. If none of the commands require an path argument, then it - should not be given. Otherwise it is required. A command that - requires an path argument is called a command. + 4. If none of the commands require an path, then + must not be given. If at least one command requires , then + is required. Commands that require a path are called + commands. - 5. Implementation detail: all arguments except the last are first - treated as commands. If any of those are , the last - argument is interpreted as the path. If no - appears before the last argument, the last argument is treated as - another command. + 5. Implementation detail: + All arguments except the final one are interpreted strictly as + command tokens. If any of those are , the final argument + is taken as . If none of the earlier tokens are , + the final argument is also treated as a command token. Roots: - A = Skeleton project root (auto-detected). Currently this is the - Harmony skeleton, but {prog} is not limited to Harmony. - - B = project root (path argument when required). + A = Skeleton project root (auto-detected). Usually the Harmony skeleton. + B = project root (supplied when required). -{prog} is used to ask questions about how has changed relative -to the current default skeleton. Changes may come from edits to the -skeleton itself, edits to skeleton files in , or files and -directories added to . Stated briefly, {prog} compares A with B. +{prog} compares A with B. Differences may come from: + - edits to the skeleton itself, + - edits to skeleton files inside B, + - or new files/directories added to B. Conceptually, A and B are any two non-overlapping directory trees. Command semantics: structure - Report directory-structure differences: - directories present in A that are missing in B or not directories - in B. - - Output: a table of such directories. + directories present in A that are missing in B or not + directories in B. + - Output: table of such directories. import - - Suggest shell copy commands to update A from B: - * files in B that are newer than A at the same relative path - * files that exist in B but not in A + - Update A from B using only "in-between newer" files: + * files in B that lie in the 'in-between' region relative to A, and + * are newer than A or absent from A. + - Also emits: + * directories to create in A, + * files to copy (B -> A), + * nodes that cannot be handled automatically (type mismatches, + constrained nodes, non-file/dir nodes). - Direction: B -> A - - Output: 'cp --parents -a' commands (to be reviewed/edited before use). export - - Suggest shell copy commands to update B from A: - * files where the A copy is newer than B at the same path - * files that exist in A but not in B + - Update B from A: + * files in A newer than B at the same path, + * files present in A but missing in B. + - Also emits: + * directories to create in B, + * files to copy (A -> B), + * nodes that cannot be handled automatically. - Direction: A -> B - - Output: 'cp --parents -a' commands (to be reviewed/edited before use). suspicious - - Report nodes in B that lie "in between" the Harmony skeleton: - under a directory present in A, but not under any leaf directory - in A. - - Intended to highlight questionable placements that may indicate - misuse of the skeleton or candidates for new skeleton structure. + - Report B nodes that lie "in-between" Harmony leaves: + under a directory from A, but not under any leaf directory of A. + - Indicates questionable placements or missing skeleton structure. addendum - - Report nodes in B that lie "below" Harmony leaf directories: - work added in the intended extension points (tools, tests, etc.). - - Intended to show project-specific additions made in proper places. + - Report B nodes located "below" Harmony leaf directories: + project-specific additions placed in proper extension points. all - Run: structure, import, export, suspicious, addendum (in that order). Notes: - - Directory and file listings respect a simplified .gitignore model - plus some always-ignored patterns (such as '.git' directories). + - tree_dict traversal respects a simplified .gitignore model plus + always-ignored patterns (e.g. '.git'). - Timestamps are formatted via the Z helper in UTC (ISO 8601). """ diff --git a/tool/skeleton/in_between_and_below b/tool/skeleton_compare_source/in_between_and_below similarity index 100% rename from tool/skeleton/in_between_and_below rename to tool/skeleton_compare_source/in_between_and_below diff --git a/tool/skeleton/load_command_module.py b/tool/skeleton_compare_source/load_command_module.py similarity index 100% rename from tool/skeleton/load_command_module.py rename to tool/skeleton_compare_source/load_command_module.py diff --git a/tool/skeleton/make_Harmony_tree_dict b/tool/skeleton_compare_source/make_Harmony_tree_dict similarity index 100% rename from tool/skeleton/make_Harmony_tree_dict rename to tool/skeleton_compare_source/make_Harmony_tree_dict diff --git a/tool/skeleton/meta.py b/tool/skeleton_compare_source/meta.py similarity index 99% rename from tool/skeleton/meta.py rename to tool/skeleton_compare_source/meta.py index fc014f6..5c8da89 100644 --- a/tool/skeleton/meta.py +++ b/tool/skeleton_compare_source/meta.py @@ -27,7 +27,7 @@ _Z_MODULE = load_command_module("Z") # Meta module version _major = 1 -_minor = 5 +_minor = 7 def version_print() -> None: """ Print the meta module version as MAJOR.MINOR. diff --git a/tool/skeleton/newer b/tool/skeleton_compare_source/newer similarity index 100% rename from tool/skeleton/newer rename to tool/skeleton_compare_source/newer diff --git a/tool/skeleton/older b/tool/skeleton_compare_source/older similarity index 100% rename from tool/skeleton/older rename to tool/skeleton_compare_source/older diff --git a/tool/skeleton/skeleton.py b/tool/skeleton_compare_source/skeleton.py similarity index 92% rename from tool/skeleton/skeleton.py rename to tool/skeleton_compare_source/skeleton.py index b8ffa70..4f51d48 100644 --- a/tool/skeleton/skeleton.py +++ b/tool/skeleton_compare_source/skeleton.py @@ -500,10 +500,28 @@ def in_between_newer( Return the subset of B's nodes that: - 1. Are in the 'in_between' region with respect to A's topology, and - 2. Are "newer" than A at the same path, or absent from A. - - Only file nodes in B are considered. + 1. Are in the 'in_between' region with respect to A's topology: + - under some directory that exists in A + - NOT under any leaf directory in A + (as defined by tree_dict_in_between_and_below), and + + 2. For file nodes: + - are "newer" than A at the same path, or + - are absent from A. + + More precisely: + - If A has no entry for that path -> include. + - If A has a non-file and B has a file -> include. + - If both are files and B.mtime > A.mtime -> include. + + 3. For constrained nodes: + - are always included, so that higher-level commands (e.g. + 'import') can surface them as "not handled automatically". + + Notes: + - Only file nodes participate in mtime comparisons. + - Nodes with node_type == 'constrained' are passed through without + mtime checks, so that callers can report them separately. """ in_between, _below = tree_dict_in_between_and_below(A, B) @@ -512,26 +530,32 @@ def in_between_newer( for path, b_info in in_between.items(): b_type = b_info.get("node_type") - # Only consider files for "newer" semantics + # Constrained nodes: always surface so the caller can list them + # under "not handled automatically". + if b_type == "constrained": + result[path] = b_info + continue + + # We only do "newer" semantics for regular files. if b_type != "file": continue b_mtime = b_info.get("mtime") a_info = A.get(path) - # Case 1: path not in A + # Case 1: path not in A at all -> include (new file in in-between) if a_info is None: result[path] = b_info continue a_type = a_info.get("node_type") - # Case 2: A has non-file, B has file + # Case 2: A has non-file, B has file -> include if a_type != "file": result[path] = b_info continue - # Case 3: both files, compare mtime + # Case 3: both are files; compare mtime a_mtime = a_info.get("mtime") if ( isinstance(a_mtime, (int, float)) diff --git a/tool/skeleton/temp.txt b/tool/skeleton_compare_source/temp.txt similarity index 100% rename from tool/skeleton/temp.txt rename to tool/skeleton_compare_source/temp.txt -- 2.20.1