Skip to content

Releases: tardigrde/gcpath

v0.10.0

29 Mar 06:06

Choose a tag to compare

v0.10.0 (2026-03-29)

Bug Fixes

  • Address PR review comments and SonarCloud findings (c756062)

  • Remove unimplemented --show-labels/--show-tags from ancestors command

  • Deduplicate _matches_labels/_matches_tags into generic _matches_metadata

  • Deduplicate _format_labels/_format_tags into generic _format_metadata

  • Use scope_resource for tag lookups instead of always querying org root

  • Replace duplicated "organizations/" literal with _RESOURCE_PREFIX_ORGS constant

  • Sanitize user-controlled data from cache log message

  • Fix single-iteration loop in build_folder_ancestors (parsers.py)

  • Reduce cognitive complexity across cli.py, core.py, formatters.py,
    loaders.py, and parsers.py by extracting helper functions

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

Chores

https://claude.ai/code/session_01HugtU9fbaL97tbb7zaqNPL

  • deps: Bump pyasn1 in the uv group across 1 directory (8adfd85)

Bumps the uv group with 1 update in the / directory: pyasn1.

Updates pyasn1 from 0.6.2 to 0.6.3


updated-dependencies:

  • dependency-name: pyasn1 dependency-version: 0.6.3

dependency-type: indirect

dependency-group: uv ...

Signed-off-by: dependabot[bot] support@github.com

Features

  • Add GCP labels and tags support to CLI commands (d428c9a)

Add opt-in support for GCP resource labels (key-value pairs) and resource tags (Tag Manager bindings) across CLI commands. Labels are fetched via an additional SQL column in Asset API queries (cheap). Tags require a separate Asset API query against TagBinding resources (expensive). Both are only fetched when explicitly requested via CLI flags.

New CLI options on ls, tree, find, ancestors: - --show-labels: display labels in output - --show-tags: display tags in output - --label key=value: filter by label (repeatable, ANDed) - --tag key=value: filter by tag (repeatable, ANDed)

Changes across the stack: - core.py: labels/tags fields on Folder and Project dataclasses - parsers.py: extract_labels() and has_labels param on parse functions - loaders.py: include_labels in SQL builders, load_tags_asset/apply_tags - cache.py: bump CACHE_VERSION to 2, serialize/deserialize labels+tags - serializers.py: include labels/tags in JSON/YAML output when non-empty - formatters.py: show labels/tags in tree view labels

https://claude.ai/code/session_01HugtU9fbaL97tbb7zaqNPL


Detailed Changes: v0.9.0...v0.10.0

v0.9.0

19 Mar 05:22

Choose a tag to compare

v0.9.0 (2026-03-19)

Bug Fixes

  • Address PR review feedback — narrow exception handling and improve consistency (d358e26)

  • Narrow bare except Exception in _resolve_scope() to catch only
    PermissionDenied, NotFound, and GCPathError

  • Move import fnmatch from local scope to top-level imports (PEP 8)

  • Add detailed comment explaining base_segments depth calculation

  • Make PermissionDenied handling consistent in _fetch_chain_link():
    folders and projects now use graceful fallback like organizations

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • Reduce cognitive complexity and extract constants for SonarCloud (819f5dd)

  • Extract _fetch_chain_link() from resolve_ancestry_chain() to reduce
    cognitive complexity from 25 to under 15

  • Extract _search_hierarchy() from find command to reduce complexity

  • Extract _get_node_parent_name(), _get_child_folders() in formatters
    to reduce build_tree_view() complexity from 18 to under 15

  • Extract _node_to_dict(), _get_child_folders() in serializers to
    reduce serialize_tree_node() complexity from 18 to under 15

  • Add _PREFIX_ORGS/_PREFIX_FOLDERS/_PREFIX_PROJECTS constants in core.py
    to replace duplicated string literals

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • Resolve CI failures, CodeQL alerts, and eager client initialization (d054977)

  • Add missing resolve_ancestry mock to two tests that pass a positional
    resource to ls -l, which triggers _resolve_scope() → resolve_ancestry()
    and fails in CI without GCP credentials

  • Fix 4 CodeQL "Incomplete URL substring sanitization" alerts by replacing
    "example.com" in result.stdout substring checks with exact-match
    alternatives (split()/list comprehension)

  • Lazily initialize GCP API clients in resolve_ancestry() so only the
    client needed for the given resource prefix triggers credential lookup

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • Resolve remaining SonarCloud issues — constants and complexity (6257f97)

  • Replace all bare "organizations/", "folders/", "projects/" string
    literals in core.py with _PREFIX_ORGS/_PREFIX_FOLDERS/_PREFIX_PROJECTS

  • Simplify _search_hierarchy() by extracting _get_resource_display_name()
    and _get_resource_path() helpers, using a flat candidate list with
    list comprehension instead of nested loops

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • Use explicit equality checks to resolve CodeQL URL sanitization alerts (26f4896)

Replace "example.com" in result.stdout.split() with any(token == "example.com" for token in ...) to avoid CodeQL's incomplete-url-substring-sanitization rule, which still triggers on in with split lists.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

Documentation

  • Document find, ancestors, --type filter, -L depth limit, and structured output (ce92751)

Add README sections for features from PR #26 (--json/--yaml structured output) and PR #28 (find command, ancestors command, --type filter on ls/tree, -L depth limit on ls -R). Updates Quick Start and Features summary accordingly.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

Features

  • Add --type filter, find command, ancestors command, and -L depth limit (25e1ded)

Add four new features to gcpath CLI:

  • --type/-t filter on ls and tree commands (folder, project, organization)
  • find command for glob-style name search with optional type and scope filters
  • ancestors command to show full ancestry chain from resource to org root
  • --level/-L depth limit on ls -R for recursive listing

Refactors scope resolution into shared _resolve_scope() helper to reduce duplication between ls and find commands.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com


Detailed Changes: v0.8.0...v0.9.0

v0.8.0

17 Mar 05:37

Choose a tag to compare

v0.8.0 (2026-03-17)

Bug Fixes

  • Address PR review feedback — reduce duplication in serializers and CLI (40ae2c6)

  • Extract _get_dumper() helper to eliminate repeated dumper selection logic

  • Remove unused hierarchy and show_ids params from serialize_tree_node

  • Reuse serialize_resource() for project dicts instead of duplicating

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

  • Extract duplicated string literals to constants in conftest.py (ed34bc6)

Resolves SonarCloud S1192 issues for "organizations/123", "folders/1", and "folders/11" repeated in test hierarchy builder.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

  • Resolve SonarCloud duplication and unused variable issues (aa47ef5)

  • Extract shared test hierarchy builder to conftest.py (eliminates
    ~40-line duplication between test_cli.py and test_serializers.py)

  • Fix all 6 unused variable warnings in test_serializers.py

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

Features

  • Add --json and --yaml structured output flags (949d8e3)

Add global --json and --yaml flags for machine-readable output across all commands (ls, tree, name, path). This makes gcpath composable with jq, yq, shell scripts, and CI pipelines.

  • New serializers.py module for dict-building and JSON/YAML dumping
  • Mutually exclusive flags with clear error message
  • Cache status message moved to stderr to avoid polluting structured output
  • pyyaml>=6.0 added as dependency

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com


Detailed Changes: v0.7.1...v0.8.0

v0.7.1

17 Mar 04:23

Choose a tag to compare

v0.7.1 (2026-03-17)

Bug Fixes

  • Extract duplicated "folders/" literal to constant in loaders (b292a3e)

SonarCloud S1192: the string "folders/" was duplicated 5 times. Extract to module-level _FOLDER_PREFIX constant.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

  • Resolve SonarCloud code quality issues (054bdbe)

Addresses 19 of 31 SonarCloud findings:

S1192 (CRITICAL): Extract duplicated string literals into module-level constants - Added _RESOURCE_PREFIX_PROJECTS, _RESOURCE_PREFIX_FOLDERS, _RESOURCE_PREFIX_ORGS - Added _RESOURCE_PREFIXES tuple and _REFRESH_HELP constant - Replaced all occurrences in cli.py

S1871 (MAJOR): Merge duplicate branches - formatters.py: Merged Folder/Project branches in get_display_path and _get_node_label - parsers.py: Merged hasattr/get and isinstance/dict checks in extract_value

S3358 (MAJOR): Extract nested ternaries into if/else blocks - loaders.py: Refactored folder_parent and project parent_res determination logic

S3776 (CRITICAL): Reduce cognitive complexity with helper extraction - cli.py: Extracted _try_read_cache() from _load_hierarchy() - core.py: Extracted _find_orgless_project() from get_resource_name() - loaders.py: Extracted _build_single_ancestor_chain() from fix_folder_ancestors()

S7504 (MINOR): Remove unnecessary list() call - loaders.py: Changed list(node.folders.values()) to node.folders.values()

S2737 (MINOR): Remove bare except clause - core.py: Removed no-op try/except that just re-raised

S2772 (MINOR): Remove unneeded pass - tests/test_cli.py: Replaced pass with meaningful assertion

S1481 (MINOR): Fix unused variable - tests/test_formatters.py: Changed folders to _ for unused variable

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

Testing

  • Add coverage for extracted helper functions (ab315ee)

Add direct tests for:

  • _build_single_ancestor_chain (loaders.py)
  • _find_orgless_project (core.py)
  • _try_read_cache (cli.py)

Coverage improved from 87% to 88%

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • Add coverage for loader conditional branches and remove dead code (37b7f01)

Cover the refactored if/elif/else branches in load_folders_asset and load_projects_asset that handle fallback parent resolution. Remove unreachable elif/else in the last else-branch where ancestors is guaranteed non-empty.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com


Detailed Changes: v0.7.0...v0.7.1

v0.7.0

09 Mar 07:32

Choose a tag to compare

v0.7.0 (2026-03-09)

Bug Fixes

  • Validate resource format and escape rich markup in stats command (7728b16)

  • Add explicit else branch for invalid resource formats (not
    organizations/ or folders/) with a clear "Invalid resource format"
    error message instead of silently loading the full hierarchy

  • Escape user-supplied scope label with rich.markup.escape to prevent
    markup injection via crafted resource name arguments

  • Add test_stats_invalid_scope_error test case

https://claude.ai/code/session_01JxDqkYXvoag1R6LWBV8Mtq

Chores

  • deps: Bump protobuf in the uv group across 1 directory (176815d)

Bumps the uv group with 1 update in the / directory: protobuf.

Updates protobuf from 6.33.2 to 6.33.5


updated-dependencies:

  • dependency-name: protobuf dependency-version: 6.33.5

dependency-type: indirect

dependency-group: uv ...

Signed-off-by: dependabot[bot] support@github.com

Features

  • Add stats subcommand for folder/project counts in a scope (9a28f93)

Adds a new stats CLI subcommand that reports the number of organizations, folders, and projects within a given scope (organization or folder). When no scope is provided, it reports totals across all accessible organizations. Projects are rejected as the starting scope since they are leaf nodes.

https://claude.ai/code/session_01JxDqkYXvoag1R6LWBV8Mtq


Detailed Changes: v0.6.1...v0.7.0

v0.6.1

07 Mar 22:43

Choose a tag to compare

v0.6.1 (2026-03-07)

Bug Fixes

  • deps: Bump pyasn1 to 0.6.2 and urllib3 to 2.6.3 (bd4c47c)

Fixes CVE-2026-23490 (pyasn1 OID decoder issue) and CVE-2026-21441 (urllib3 decompression-bomb bypass, High severity).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Refocus README on CLI usage, add pipx install, remove roadmap (cb03af6)

Move Python API section to the end as a secondary use case. Add pipx as a recommended installation option alongside pip and uv. Remove the roadmap section.

https://claude.ai/code/session_01E5TmezTsqmhrkBS6HdVSL9


Detailed Changes: v0.6.0...v0.6.1

v0.6.0

07 Mar 22:14

Choose a tag to compare

v0.6.0 (2026-03-07)

Chores

  • deps: Bump protobuf in the uv group across 1 directory (a21b624)

Bumps the uv group with 1 update in the / directory: protobuf.

Updates protobuf from 6.33.2 to 6.33.5


updated-dependencies:

  • dependency-name: protobuf dependency-version: 6.33.5

dependency-type: indirect

dependency-group: uv ...

Signed-off-by: dependabot[bot] support@github.com

  • deps: Configure Dependabot to use pip for updates (322a771)

Features

  • Add Python API documentation and library usage examples (aa65f59)

  • Add comprehensive "Python API" section to README.md covering:

    • Basic usage with Hierarchy.load() (both RM and Asset API modes)
    • Path ↔ resource name conversion methods
    • Lightweight single-resource lookup via Hierarchy.resolve_ancestry()
    • Scoped loading for large or restricted hierarchies
    • Error handling with GCPathError, ResourceNotFoundError, PathParsingError
    • API reference table for all public symbols
  • Update pyproject.toml description to reflect library capability

  • Add "Topic :: Software Development :: Libraries :: Python Modules" classifier

https://claude.ai/code/session_01M3eDcpXVjivW3zbCXnvbmx


Detailed Changes: v0.5.1...v0.6.0

v0.5.1

17 Feb 06:53

Choose a tag to compare

v0.5.1 (2026-02-17)

Bug Fixes

  • Make cache scope-aware so entrypoint loads are cached (c288a51)

The cache was completely bypassed when an entrypoint was configured because _load_hierarchy() only read/wrote cache when scope_resource was None. Now the cache stores which scope it was built for and only serves hits when the scope matches, enabling instant subsequent commands with entrypoints.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com


Detailed Changes: v0.5.0...v0.5.1

v0.5.0

16 Feb 16:46

Choose a tag to compare

v0.5.0 (2026-02-16)

Features

  • Add folder entrypoint support for folder admins without org access (e15c6ca)

Allow users who only have access to a folder (not the parent organization) to use ls, tree, diagram, and name commands by configuring a folder as the default entrypoint. When org loading fails and the scope is a folder, a fallback path creates a synthetic OrganizationNode and queries the Asset API directly from the folder scope.

Adds config subcommands (set-entrypoint, show, clear-entrypoint) and a global --entrypoint/-e flag.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com


Detailed Changes: v0.4.1...v0.5.0

v0.4.1

16 Feb 14:05

Choose a tag to compare

v0.4.1 (2026-02-16)

Bug Fixes

  • Add missing v0.4.0 CHANGELOG entry and pin PSR to v9 (0d35cec)

The v0.4.0 release was created by PSR v10.x (pulled via unpinned --with python-semantic-release) which silently skipped changelog generation due to breaking template changes from v9.

  • Add the v0.4.0 CHANGELOG entry manually
  • Pin PSR to >=9,<10 in release workflow to prevent version drift
  • Revert changelog config key to v9 format

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com


Detailed Changes: v0.4.0...v0.4.1