Conversation
- Add `tags` parsing capability for blocks with start and end symbols (`[`, `]`). - Introduce `ParsingErrors::MalFormedTags` to handle tag-related parsing errors. - Update `Block` structure to include tags using `IndexSet`. - Extend `Block` creation methods to support tag initialization. - Enhance `Display` implementation to format tags properly. - Modify hashing and equality checks to account for tags. - Update block parser to validate and handle tags.
- Introduce TODO note for handling encrypted block tags with constant `ENCRYPTED_BLOCK_TAG`. - Add TODOs for testing tag operations including uniqueness, addition, and display behavior.
There was a problem hiding this comment.
Pull request overview
This PR introduces block tags to extend envmn’s block model from a single dimension (block name) to a two-dimensional identity (name + tag set), enabling tag-aware listing, picking with slide semantics, and a new lint rule that checks variable-key symmetry across tag groups. It also adds support for a reserved __encrypted__ tag to mark blocks whose values are ciphertext while keys remain plaintext.
Changes:
- Add tag parsing/validation and incorporate tags into block identity and display (
name [tag1, tag2]). - Update
pickto be tag-aware (including--tag/-t) with “slide within group” behavior and stderr summaries. - Extend
lintto emit advisory symmetry warnings for tagged groups; add extensive unit/E2E test coverage and README documentation.
Reviewed changes
Copilot reviewed 20 out of 24 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/tags_tests.rs | New end-to-end tests covering tagged list/pick/slide/no-op/errors and encrypted round-trips. |
| tests/pick_tests.rs | Minor formatting fix in existing pick tests. |
| tests/list_tests.rs | Minor formatting fix in existing list tests. |
| tests/lint_tests.rs | Adds tests for symmetry warnings and encrypted-key symmetry behavior. |
| tests/format_tests.rs | Minor whitespace/formatting cleanup in format tests. |
| tests/common/mod.rs | Minor formatting fix. |
| src/parser/validators/tag_validator.rs | New tag validation (syntax rules + reserved tag handling). |
| src/parser/validators/mod.rs | Exposes tag validator APIs. |
| src/parser/tokens/document.rs | Implements tag-aware lookup, active-by-tag tracking, and sliding pick destination logic. |
| src/parser/tokens/block.rs | Adds tags to Block, identifier formatting, resource-tag filtering, and tag-aware equality/hash. |
| src/parser/parser.rs | Parses optional [tag1, tag2] syntax in block headers and validates tags. |
| src/parser/mod.rs | Module ordering/exports adjustment. |
| src/parser/engine/pick.rs | Updates CLI pick processing to accept tags and report activation changes on stderr. |
| src/parser/engine/mod.rs | Wires in new lint implementation and updated pick signature. |
| src/parser/engine/list.rs | Makes list print full block identifiers including tags. |
| src/parser/engine/lint.rs | New symmetry lint implementation for tagged blocks. |
| src/parser/constants.rs | Adds tag delimiter constants and __encrypted__ tag constant. |
| src/error/parsing.rs | Adds malformed-tags parse error. |
| src/error/naming.rs | Adds tag-related naming errors, including unknown reserved tags. |
| src/cli/mod.rs | Minor module ordering change. |
| src/cli/cli.rs | Extends Pick command to carry tag filters. |
| src/cli/args.rs | Adds --tag/-t (repeatable) to the pick subcommand. |
| README.md | Documents tags, tagged picking semantics, reserved tags, and symmetry lint behavior. |
| .gitignore | Ignores .env* files. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds tags to block definitions, turning envmn's flat block list into a two-dimensional model: the block name is the environment (
local,remote), and tags describe the resource (db,smtp). Everything else in the PR builds on that: tag-aware picking with slide semantics, a variable-symmetry lint, and a plaintext-keys format for encrypted blocks.Syntax & validation
#@ name [tag1, tag2]. Two blocks may share a name as long as their tags differ (block identity = name + tag set).[a-z_][a-z0-9_]*). Dunder-form tags (__x__) are reserved; the only recognized one is__encrypted__. Malformed brackets, invalid characters, and unknown reserved tags are parse errors with line numbers.Picking
Blocks sharing a resource tag form a group competing for the same variables; the last block of a group is the active one (last-wins). Picking no longer shuffles blocks to the bottom of the file:
pick <name>picks all blocks with that name (atomic environment switch, each within its own group);--tag/-t(repeatable) narrows to specific resources.#@ remote [db, cache]) means "these switch together": it slides after all blocks it shares a tag with..envfiles are unaffected.Lint: variable symmetry
lint(previously parse-only) now checks that blocks sharing a resource tag define the same variable keys. Single-tag blocks are the ground truth for their tag; multi-tag blocks are checked against the union of their tags (extra keys are only flagged when every tag has a ground truth). Findings are advisory: warnings on stderr, exit code 0.Encrypted blocks
__encrypted__marks a block whose values are ciphertext while keys stay plaintext (keys are rarely the secret, values are). Encrypted blocks therefore parse, list, format, pick, and lint like any other block. Actual encrypt/decrypt commands are future work.Recommended layout (advisory)
The README documents the opinionated style: one resource tag per block, using shared names to bundle resources into environments.
pick remoteswitches the whole environment; later fine-grained picks (pick other --tag cache) compose any mix via last-wins. Multi-tag blocks remain supported for deliberate all-or-nothing bundles.Notes
pick(block identity includes tags, but lookup constructed a tagless probe).dbg!in the parser.list,format,lint, andpickwork exactly as before.Testing
list,pick --tag, environment-wide pick, stderr summaries, encrypted round-trip viaformat, and lint warnings..env.taggedand an untagged.env.