From 993306355fd300349d3e0b34f08f73bb23b16e5a Mon Sep 17 00:00:00 2001 From: Aaron Stannard Date: Mon, 14 Sep 2026 18:45:25 -0500 Subject: [PATCH] Add sanitized PowerShell approval corpus --- IMPLEMENTATION_PLAN.md | 11 + SPEC.POWERSHELL.md | 21 +- .../Pwsh/Parsing/PwshStructuralCoordinator.cs | 32 +- .../Corpus/PiiAuditTests.cs | 78 +- ...sumer_repro_leading_comment_pipeline.json} | 4 +- ...consumer_repro_compound_with_comment.json} | 4 +- ...132_freshdesk_ticket_list_status_open.json | 21 - ...32_supportcli_ticket_list_status_open.json | 21 + ...9_v04_live_recursive_directory_filter.json | 566 +++++++++++++++ .../550_v04_live_git_ref_listing.json | 350 +++++++++ .../551_v04_live_git_tree_client_filter.json | 548 ++++++++++++++ ...v04_live_git_tree_client_model_filter.json | 591 +++++++++++++++ .../553_v04_live_git_tree_models_filter.json | 425 +++++++++++ ..._live_git_tree_project_library_filter.json | 548 ++++++++++++++ ...04_live_git_tree_project_library_skip.json | 671 ++++++++++++++++++ ...live_git_show_interface_documentation.json | 185 +++++ .../557_v04_live_git_diff_stat_filter.json | 520 ++++++++++++++ ...558_v04_live_git_tree_instance_filter.json | 425 +++++++++++ ...live_git_tree_alternate_branch_filter.json | 671 ++++++++++++++++++ ...t_tree_remote_alternate_branch_filter.json | 671 ++++++++++++++++++ ...live_git_tree_client_project_segments.json | 597 ++++++++++++++++ ...4_live_git_tree_example_client_filter.json | 455 ++++++++++++ .../PwshExecutionRegionStructuralTests.cs | 37 + tools/PwshCorpusTool/CorpusManifest.cs | 61 ++ 24 files changed, 7443 insertions(+), 70 deletions(-) rename tests/ShellSyntaxTree.Tests/Corpus/bash/{130_netclaw_repro_leading_comment_pipeline.json => 130_consumer_repro_leading_comment_pipeline.json} (76%) rename tests/ShellSyntaxTree.Tests/Corpus/bash/{131_netclaw_repro_compound_with_comment.json => 131_consumer_repro_compound_with_comment.json} (81%) delete mode 100644 tests/ShellSyntaxTree.Tests/Corpus/bash/132_freshdesk_ticket_list_status_open.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/bash/132_supportcli_ticket_list_status_open.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/549_v04_live_recursive_directory_filter.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/550_v04_live_git_ref_listing.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/551_v04_live_git_tree_client_filter.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/552_v04_live_git_tree_client_model_filter.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/553_v04_live_git_tree_models_filter.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/554_v04_live_git_tree_project_library_filter.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/555_v04_live_git_tree_project_library_skip.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/556_v04_live_git_show_interface_documentation.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/557_v04_live_git_diff_stat_filter.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/558_v04_live_git_tree_instance_filter.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/559_v04_live_git_tree_alternate_branch_filter.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/560_v04_live_git_tree_remote_alternate_branch_filter.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/561_v04_live_git_tree_client_project_segments.json create mode 100644 tests/ShellSyntaxTree.Tests/Corpus/powershell/562_v04_live_git_tree_example_client_filter.json diff --git a/IMPLEMENTATION_PLAN.md b/IMPLEMENTATION_PLAN.md index f28ac36..b376185 100644 --- a/IMPLEMENTATION_PLAN.md +++ b/IMPLEMENTATION_PLAN.md @@ -181,6 +181,17 @@ priorities. and pins the official package. Netclaw policy PR #2177 is also merged; its local gates and all required GitHub checks passed. No new Netclaw beta was cut. +- [x] **Harvest post-deployment PowerShell approval prompts.** Review every + shell call from the two sessions created after the deployed + `0.27.0-beta.4` daemon started. Fourteen of 28 shell calls prompted. + Add one sanitized, generator-owned corpus case for each prompt shape and + remove product-specific labels from the older Bash corpus. Thirteen + prompt shapes already produce complete command projections and therefore + remain downstream policy evidence. The remaining split/index/join + projection now has a narrow no-command recognizer with positive and + adversarial tests; dynamic and executable variants still fail closed. + The PII audit now scans every JSON string and filename with exact, + synthetic-only placeholder exceptions. ## Completed v0.3.0 host integration and release acceptance diff --git a/SPEC.POWERSHELL.md b/SPEC.POWERSHELL.md index f17f9d9..1d35311 100644 --- a/SPEC.POWERSHELL.md +++ b/SPEC.POWERSHELL.md @@ -85,6 +85,15 @@ Pipeline-produced objects and unsupported expressions remain unknown without execution. `while`, `if`, `elseif`, `else`, `do`, `switch`, definitions, and arbitrary script evaluation stay outside the supported grammar. +The v0.4 grammar also recognizes one bounded projection expression inside a +cataloged script-block execution region: +`($_ -split )[] -join ` +(with `$PSItem` accepted in place of `$_`). Recognition proves only that the +authored region contains no nested command. It does not evaluate the +expression, predict its value, or claim that runtime conversion is +side-effect-free. Every dynamic operand and every other unsupported expression +still fails closed. + --- ## 2. Public API Surface @@ -678,7 +687,12 @@ expression body: doing so could preserve a stale exact or finite binding for a later command. Ordinary property reads and comparison/filter expressions remain supported empty bodies. That structure proves only that no authored simple command was hidden; it does not prove that a runtime property getter is -side-effect-free. +side-effect-free. The same empty-body rule applies to the bounded v0.4 +split/index/join projection from §1. Its delimiters must be non-interpolating +quoted literals without dollar signs, backticks, or newlines; its selector must +be one static integer or integer range; and the body may contain no statement +separator, member call, assignment, subexpression, splat, or additional +operator. When a balanced increment/decrement expression statement is separated from otherwise parsed siblings by a parser-owned semicolon or newline boundary, the @@ -2063,8 +2077,9 @@ v0.2.0 ships when **all** of these hold: - `function`/`filter`/`class`/`enum` definitions, `param()`/`begin`/`process`/`end` blocks, `trap`, and `DATA`. - `.ps1` script-file parsing. -- General PowerShell expression evaluation, `$_` / `$PSItem` semantics, .NET - method calls, object-to-string prediction, and runtime pipeline evaluation. +- General PowerShell expression evaluation, `$_` / `$PSItem` semantics beyond + the bounded no-command structural recognition in §1, .NET method calls, + object-to-string prediction, and runtime pipeline evaluation. - Desired State Configuration (DSC). - A real `Push-Location` / `Pop-Location` directory-stack model (§9). - Per-element path extraction from a comma-separated array diff --git a/src/ShellSyntaxTree/Internal/Pwsh/Parsing/PwshStructuralCoordinator.cs b/src/ShellSyntaxTree/Internal/Pwsh/Parsing/PwshStructuralCoordinator.cs index 1449b72..bb0021b 100644 --- a/src/ShellSyntaxTree/Internal/Pwsh/Parsing/PwshStructuralCoordinator.cs +++ b/src/ShellSyntaxTree/Internal/Pwsh/Parsing/PwshStructuralCoordinator.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Runtime.CompilerServices; +using System.Text.RegularExpressions; using ShellSyntaxTree.Internal.Parsing; using ShellSyntaxTree.Internal.Pwsh.Lexing; using ShellSyntaxTree.Internal.Resolving; @@ -1287,18 +1288,21 @@ private bool TryParseScriptBlockBody( return false; } + var isSupportedProjectionExpression = + significant.Count > 0 && IsSupportedProjectionExpression(source); if (significant.Count > 0 && - IsUnsupportedSubstitutionBody(source, significant) && + (isSupportedProjectionExpression || IsUnsupportedSubstitutionBody(source, significant)) && !ContainsIncrementOrDecrementMutation(significant)) { foreach (var expressionToken in significant) { - if (HasPowerShellSubexpression(expressionToken) - || expressionToken.Kind is PwshTokenKind.Subexpression - or PwshTokenKind.ScriptBlock - or PwshTokenKind.Splat - || expressionToken.IsStatementSeparator - || expressionToken.Kind == PwshTokenKind.Operator) + if (!isSupportedProjectionExpression && + (HasPowerShellSubexpression(expressionToken) + || expressionToken.Kind is PwshTokenKind.Subexpression + or PwshTokenKind.ScriptBlock + or PwshTokenKind.Splat + || expressionToken.IsStatementSeparator + || expressionToken.Kind == PwshTokenKind.Operator)) { body = new ShellBlockSyntax(); error = "unsupported execution-bearing PowerShell script-block expression"; @@ -1625,6 +1629,20 @@ private bool TryCollectCommandSubstitutions( return true; } + private static readonly Regex SupportedProjectionExpressionPattern = + new( + @"^[ \t]*\([ \t]*(?:\$_|\$PSItem)[ \t]+-split[ \t]+" + + @"(?:'[^'`$\r\n]*'|\x22[^\x22`$\r\n]*\x22)[ \t]*\)" + + @"[ \t]*\[[ \t]*[+-]?\d+(?:[ \t]*\.\.[ \t]*[+-]?\d+)?[ \t]*\]" + + @"[ \t]+-join[ \t]+(?:'[^'`$\r\n]*'|\x22[^\x22`$\r\n]*\x22)[ \t]*$", + RegexOptions.CultureInvariant | RegexOptions.IgnoreCase, + TimeSpan.FromMilliseconds(50)); + + // This is structural recognition only: it publishes no value and + // proves only that this exact script-block body hides no authored command. + private static bool IsSupportedProjectionExpression(string source) => + SupportedProjectionExpressionPattern.IsMatch(source); + private static bool IsUnsupportedSubstitutionBody( string source, IReadOnlyList tokens) diff --git a/tests/ShellSyntaxTree.Tests/Corpus/PiiAuditTests.cs b/tests/ShellSyntaxTree.Tests/Corpus/PiiAuditTests.cs index 7eddf01..62696b6 100644 --- a/tests/ShellSyntaxTree.Tests/Corpus/PiiAuditTests.cs +++ b/tests/ShellSyntaxTree.Tests/Corpus/PiiAuditTests.cs @@ -16,7 +16,7 @@ namespace ShellSyntaxTree.Tests.Corpus; /// /// PII audit gate per SPEC §14 / SPEC.POWERSHELL.md §14. Scans every JSON -/// entry under the executable corpus and the pre-implementation design corpus +/// string under the executable corpus and the pre-implementation design corpus /// for the forbidden patterns listed in the sanitization table. The audit /// reads from the build-output copies so CI runs against the same bytes a /// developer's local dotnet test would. @@ -24,11 +24,8 @@ namespace ShellSyntaxTree.Tests.Corpus; /// /// Scanning policy: /// -/// Only input, notes, and raw string fields -/// are scanned. Synthetic resolved paths and the -/// <dynamic-cwd> sentinel surface in other fields and -/// would generate noise (e.g. /work/foo from -/// WorkingDirectory pinning). +/// Every JSON string is scanned, including expected projections and +/// metadata, so sensitive text cannot hide in an unscanned field. /// A small allowlist of generic placeholder usernames is honored: /// user, test, foo, dev, runner, gh-actions, ci. Anything /// else under /home/ or /Users/ trips the audit. @@ -70,25 +67,25 @@ public class PiiAuditTests new(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", RegexOptions.Compiled); private static readonly Regex LongKeyPattern = - new(@"[A-Za-z0-9]{32,}", RegexOptions.Compiled); + new(@"[A-Za-z0-9]{20,}", RegexOptions.Compiled); // The home/users patterns capture the username segment; we then allow-list it. private static readonly Regex HomePattern = - new(@"/home/([a-zA-Z0-9_.-]+)/", RegexOptions.Compiled); + new(@"/home/([a-zA-Z0-9_.-]+)(?:/|$)", RegexOptions.Compiled); private static readonly Regex UsersPattern = - new(@"/Users/([a-zA-Z0-9_.-]+)/", RegexOptions.Compiled); + new(@"/Users/([a-zA-Z0-9_.-]+)(?:/|$)", RegexOptions.Compiled); // Repository-path pattern: /home//repositories///... where // isn't one of the public-corpus placeholders. private static readonly Regex RepoPathPattern = - new(@"/home/[^/]+/repositories/[^/]+/([a-zA-Z0-9_.-]+)/", RegexOptions.Compiled); + new(@"/home/[^/]+/repositories/[^/]+/([a-zA-Z0-9_.-]+)(?:/|$)", RegexOptions.Compiled); // SPEC.POWERSHELL.md §14: a concrete C:\Users\\ path (mixed // slashes allowed). A literal $env:USERNAME / $env:USERPROFILE reference // is not PII and is not matched here. private static readonly Regex WindowsUserPattern = - new(@"[A-Za-z]:[\\/]Users[\\/]([A-Za-z0-9_.-]+)[\\/]", RegexOptions.Compiled); + new(@"[A-Za-z]:[\\/]Users[\\/]([A-Za-z0-9_.-]+)(?:[\\/]|$)", RegexOptions.Compiled); // SPEC.POWERSHELL.md §14: a UNC \\\share path. private static readonly Regex UncHostPattern = @@ -97,6 +94,31 @@ public class PiiAuditTests private static readonly HashSet AllowedUncHosts = new(StringComparer.Ordinal) { "internal-host.example" }; + private static readonly HashSet AllowedSyntheticHomeSegments = + new(StringComparer.Ordinal) + { + "test.json", + "test.txt", + "user.Length", + "user.json", + "user.txt", + }; + + private static bool IsAllowedPlaceholderPathSegment( + string segment, + HashSet allowlist) + { + if (allowlist.Contains(segment)) + { + return true; + } + + // A few resolver projections append a known synthetic suffix to the + // placeholder home. Keep this list exact so a dotted real username + // cannot pass merely because its prefix resembles a placeholder. + return AllowedSyntheticHomeSegments.Contains(segment); + } + [Fact] public void Corpus_contains_no_pii_per_spec_section_14() { @@ -115,6 +137,9 @@ public void Corpus_contains_no_pii_per_spec_section_14() { var name = Path.GetRelativePath(AppContext.BaseDirectory, file) .Replace('\\', '/'); + // Filenames are part of the committed corpus surface too; + // scan their slug so identifiers cannot be hidden in paths. + ScanString(Path.GetFileNameWithoutExtension(file), name, "", hits); try { using var doc = JsonDocument.Parse(File.ReadAllText(file)); @@ -160,10 +185,7 @@ private static void Walk(JsonElement element, string fileName, string fieldPath, break; case JsonValueKind.String: - if (ShouldScan(fieldPath)) - { - ScanString(element.GetString() ?? string.Empty, fileName, fieldPath, hits); - } + ScanString(element.GetString() ?? string.Empty, fileName, fieldPath, hits); break; } } @@ -188,22 +210,6 @@ private static bool IsLowEntropyRun(string token) return true; } - /// - /// Decide whether a JSON string at is in - /// scope for the audit. SPEC §14: scan input, notes, - /// and any raw nested under args. Skip synthetic fields like - /// resolved, target, etc. — those carry parser-produced - /// paths (e.g. /home/test/file) that we explicitly want to allow. - /// - private static bool ShouldScan(string fieldPath) - { - if (fieldPath == "input") return true; - if (fieldPath == "notes") return true; - if (fieldPath.EndsWith(".command", StringComparison.Ordinal)) return true; - if (fieldPath.EndsWith(".raw", StringComparison.Ordinal)) return true; - return false; - } - private static void ScanString(string value, string fileName, string fieldPath, List hits) { if (string.IsNullOrEmpty(value)) @@ -239,7 +245,9 @@ private static void ScanString(string value, string fileName, string fieldPath, { foreach (Match m in LongKeyPattern.Matches(value)) { - if (IsLowEntropyRun(m.Value)) + if (IsLowEntropyRun(m.Value) + || !m.Value.Any(char.IsDigit) + || !m.Value.Any(char.IsLetter)) { continue; } @@ -252,7 +260,7 @@ private static void ScanString(string value, string fileName, string fieldPath, foreach (Match m in HomePattern.Matches(value)) { var user = m.Groups[1].Value; - if (!AllowedHomeUsernames.Contains(user)) + if (!IsAllowedPlaceholderPathSegment(user, AllowedHomeUsernames)) { hits.Add($"{fileName} ({fieldPath}): /home/{user}/ — not in allowed-placeholder list (SPEC §14)"); } @@ -262,7 +270,7 @@ private static void ScanString(string value, string fileName, string fieldPath, foreach (Match m in UsersPattern.Matches(value)) { var user = m.Groups[1].Value; - if (!AllowedUsersUsernames.Contains(user)) + if (!IsAllowedPlaceholderPathSegment(user, AllowedUsersUsernames)) { hits.Add($"{fileName} ({fieldPath}): /Users/{user}/ — not in allowed-placeholder list (SPEC §14)"); } @@ -282,7 +290,7 @@ private static void ScanString(string value, string fileName, string fieldPath, foreach (Match m in WindowsUserPattern.Matches(value)) { var user = m.Groups[1].Value; - if (!AllowedUsersUsernames.Contains(user)) + if (!IsAllowedPlaceholderPathSegment(user, AllowedUsersUsernames)) { hits.Add($"{fileName} ({fieldPath}): Windows user path 'Users\\{user}\\' — not in allowed-placeholder list (SPEC.POWERSHELL.md §14)"); } diff --git a/tests/ShellSyntaxTree.Tests/Corpus/bash/130_netclaw_repro_leading_comment_pipeline.json b/tests/ShellSyntaxTree.Tests/Corpus/bash/130_consumer_repro_leading_comment_pipeline.json similarity index 76% rename from tests/ShellSyntaxTree.Tests/Corpus/bash/130_netclaw_repro_leading_comment_pipeline.json rename to tests/ShellSyntaxTree.Tests/Corpus/bash/130_consumer_repro_leading_comment_pipeline.json index b6b235b..1ed32a2 100644 --- a/tests/ShellSyntaxTree.Tests/Corpus/bash/130_netclaw_repro_leading_comment_pipeline.json +++ b/tests/ShellSyntaxTree.Tests/Corpus/bash/130_consumer_repro_leading_comment_pipeline.json @@ -1,5 +1,5 @@ { - "name": "Netclaw repro: leading comment + git worktree list | awk | tr | sort pipeline", + "name": "Consumer repro: leading comment + git worktree list | awk | tr | sort pipeline", "input": "# Extract all unique branch names from worktrees\ngit -C /home/user/repos/sample-repo worktree list | awk '{print $NF}' | tr -d '[]' | sort -u", "expected": { "isUnparseable": false, @@ -48,5 +48,5 @@ } ] }, - "notes": "Issue #25 — original Netclaw repro, paths sanitized per SPEC §14. Without the v0.1.3 comment-skip fix, Clause 0's verb parsed as `[#, Extract]`. Updated for issue #27 / v0.1.4-alpha: the greedy heuristic now walks past the consumed `-C /repo` flag-value pair and captures `worktree list` as part of the verb chain instead of leaving `list` as a stranded positional arg." + "notes": "Issue #25 consumer repro, paths sanitized per SPEC §14. Without the v0.1.3 comment-skip fix, Clause 0's verb parsed as `[#, Extract]`. Updated for issue #27 / v0.1.4-alpha: the greedy heuristic now walks past the consumed `-C /repo` flag-value pair and captures `worktree list` as part of the verb chain instead of leaving `list` as a stranded positional arg." } diff --git a/tests/ShellSyntaxTree.Tests/Corpus/bash/131_netclaw_repro_compound_with_comment.json b/tests/ShellSyntaxTree.Tests/Corpus/bash/131_consumer_repro_compound_with_comment.json similarity index 81% rename from tests/ShellSyntaxTree.Tests/Corpus/bash/131_netclaw_repro_compound_with_comment.json rename to tests/ShellSyntaxTree.Tests/Corpus/bash/131_consumer_repro_compound_with_comment.json index 3acb312..b3a89cc 100644 --- a/tests/ShellSyntaxTree.Tests/Corpus/bash/131_netclaw_repro_compound_with_comment.json +++ b/tests/ShellSyntaxTree.Tests/Corpus/bash/131_consumer_repro_compound_with_comment.json @@ -1,5 +1,5 @@ { - "name": "Netclaw repro: leading comment + curl|jq pipeline with ||-fallback", + "name": "Consumer repro: leading comment + curl|jq pipeline with ||-fallback", "input": "# Get open PRs from the upstream repo\ncurl -s \"https://api.github.com/repos/sample-org/sample-repo/pulls?state=open\" | jq -r '.[] | \"PR\"' 2>/dev/null || echo \"API failed, trying alternative...\"", "expected": { "isUnparseable": false, @@ -40,5 +40,5 @@ } ] }, - "notes": "Issue #25 follow-up: leading comment + `||`-fallback that surfaced the approval-state desync cascade (verb-chain extracted as `# Get` at persistence time → cache miss at retry-authorization → tool fails after user clicked Approve). The quoted URL wildcard marker is literal. Paths and org names sanitized per SPEC §14." + "notes": "Issue #25 follow-up: leading comment + `||`-fallback that surfaced an approval-state desync cascade (verb-chain extracted as `# Get` at persistence time → cache miss at retry-authorization → tool fails after user clicked Approve). The quoted URL wildcard marker is literal. Paths and org names sanitized per SPEC §14." } diff --git a/tests/ShellSyntaxTree.Tests/Corpus/bash/132_freshdesk_ticket_list_status_open.json b/tests/ShellSyntaxTree.Tests/Corpus/bash/132_freshdesk_ticket_list_status_open.json deleted file mode 100644 index 0a8fc53..0000000 --- a/tests/ShellSyntaxTree.Tests/Corpus/bash/132_freshdesk_ticket_list_status_open.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "Greedy verb chain: freshdesk ticket list --status open (unknown CLI)", - "input": "freshdesk ticket list --status open", - "expected": { - "isUnparseable": false, - "clauses": [ - { - "operator": "None", - "verb": ["freshdesk", "ticket", "list"], - "args": [ - { "raw": "--status", "kind": "Literal", "isPath": false, "isFlag": true }, - { "raw": "open", "kind": "Literal", "isPath": false, "resolved": "__NULL__" } - ], - "redirects": [], - "isSubshell": false, - "isCommandStringWrapped": false - } - ] - }, - "notes": "Issue #27 headline: unknown/private CLIs (freshdesk, internal tools) used to truncate to a 1-token verb chain. The greedy heuristic walks verb-like Word tokens (lowercase[a-z0-9._-]) and stops at the first flag, so the canonical subcommand stack `freshdesk ticket list` extracts fully without requiring a curated table entry." -} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/bash/132_supportcli_ticket_list_status_open.json b/tests/ShellSyntaxTree.Tests/Corpus/bash/132_supportcli_ticket_list_status_open.json new file mode 100644 index 0000000..40b316b --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/bash/132_supportcli_ticket_list_status_open.json @@ -0,0 +1,21 @@ +{ + "name": "Greedy verb chain: supportcli ticket list --status open (synthetic CLI)", + "input": "supportcli ticket list --status open", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": ["supportcli", "ticket", "list"], + "args": [ + { "raw": "--status", "kind": "Literal", "isPath": false, "isFlag": true }, + { "raw": "open", "kind": "Literal", "isPath": false, "resolved": "__NULL__" } + ], + "redirects": [], + "isSubshell": false, + "isCommandStringWrapped": false + } + ] + }, + "notes": "Issue #27 headline: unknown/private CLIs used to truncate to a 1-token verb chain. The greedy heuristic walks verb-like Word tokens (lowercase[a-z0-9._-]) and stops at the first flag, so the canonical subcommand stack `supportcli ticket list` extracts fully without requiring a curated table entry." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/549_v04_live_recursive_directory_filter.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/549_v04_live_recursive_directory_filter.json new file mode 100644 index 0000000..8b69386 --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/549_v04_live_recursive_directory_filter.json @@ -0,0 +1,566 @@ +{ + "name": "V04 live recursive directory filter", + "input": "Get-ChildItem -Path C:\\Users\\user -Recurse -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -like \u0022*sample*\u0022 -or $_.Name -like \u0022*project*\u0022 } | Select-Object -First 30 FullName", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "Get-ChildItem" + ], + "args": [ + { + "raw": "-Path", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\Users\\user", + "kind": "Literal", + "isPath": true, + "resolved": "C:/Users/user" + }, + { + "raw": "-Recurse", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-Directory", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-ErrorAction", + "kind": "Literal", + "isPath": false + }, + { + "raw": "SilentlyContinue", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Get-ChildItem", + "value": "Get-ChildItem", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Path", + "value": "-Path", + "role": "Argument", + "sourceStart": 14, + "sourceLength": 5, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\Users\\user", + "value": "C:\\Users\\user", + "role": "Argument", + "sourceStart": 20, + "sourceLength": 13, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/Users/user" + }, + { + "raw": "-Recurse", + "value": "-Recurse", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "-Directory", + "value": "-Directory", + "role": "Argument", + "sourceStart": 43, + "sourceLength": 10, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "-ErrorAction", + "value": "-ErrorAction", + "role": "Argument", + "sourceStart": 54, + "sourceLength": 12, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "SilentlyContinue", + "value": "SilentlyContinue", + "role": "Argument", + "sourceStart": 67, + "sourceLength": 16, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Where-Object" + ], + "args": [ + { + "raw": "{ $_.Name -like \u0022*sample*\u0022 -or $_.Name -like \u0022*project*\u0022 }", + "kind": "DynamicSkip", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Where-Object", + "value": "Where-Object", + "role": "Verb", + "sourceStart": 86, + "sourceLength": 12, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "{ $_.Name -like \u0022*sample*\u0022 -or $_.Name -like \u0022*project*\u0022 }", + "value": "{ $_.Name -like \u0022*sample*\u0022 -or $_.Name -like \u0022*project*\u0022 }", + "role": "Argument", + "sourceStart": 99, + "sourceLength": 58, + "precedingVerbElementCount": 1, + "kind": "DynamicSkip", + "isFlag": false, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-Object" + ], + "args": [ + { + "raw": "-First", + "kind": "Literal", + "isPath": false + }, + { + "raw": "30", + "kind": "Literal", + "isPath": false + }, + { + "raw": "FullName", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-Object", + "value": "Select-Object", + "role": "Verb", + "sourceStart": 160, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-First", + "value": "-First", + "role": "Argument", + "sourceStart": 174, + "sourceLength": 6, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "30", + "value": "30", + "role": "Argument", + "sourceStart": 181, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "FullName", + "value": "FullName", + "role": "Argument", + "sourceStart": 184, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 192, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 192, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 83, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 86, + "sourceLength": 71, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + }, + { + "kind": "ExecutionRegion", + "parentIndex": 3, + "region": "ExecutionRegion", + "childIndex": 0, + "sourceStart": 99, + "sourceLength": 58, + "clauseIndex": null, + "groupKind": null, + "listOperator": null, + "executionOrigin": "CommandArgument", + "hostClauseElementIndex": 1, + "executionPhase": "Filter", + "executionTiming": "Synchronous", + "executionCardinality": "OncePerInputObject" + }, + { + "kind": "Block", + "parentIndex": 4, + "region": "ExecutionRegion", + "childIndex": 0, + "sourceStart": 100, + "sourceLength": 56, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 160, + "sourceLength": 32, + "clauseIndex": 2, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 192 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 192 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Path" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\Users\\user" + ], + "pattern": null, + "coveringDirectory": null + }, + "authoredFileSystemValue": { + "kind": "Exact", + "values": [ + "C:/Users/user" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-Recurse" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-Directory" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "-ErrorAction" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 5, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "SilentlyContinue" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + }, + "fileSystemTreeAccesses": [ + { + "rootArgumentIndex": 1, + "root": { + "kind": "Exact", + "values": [ + "C:/Users/user" + ], + "pattern": null, + "coveringDirectory": null + }, + "traversal": "RecursiveWithoutFollowingLinks" + } + ] + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 192 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 192 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 2, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 192 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 0, + "sourceLength": 192 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-First" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "30" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "FullName" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: recursive directory filtering and bounded projection." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/550_v04_live_git_ref_listing.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/550_v04_live_git_ref_listing.json new file mode 100644 index 0000000..d499863 --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/550_v04_live_git_ref_listing.json @@ -0,0 +1,350 @@ +{ + "name": "V04 live git ref listing", + "input": "git -C C:\\WORK\\PROJECT for-each-ref --sort=-committerdate --format=\u0027%(committerdate:iso8601) %(refname:short)\u0027 refs/heads refs/remotes --count=40", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "for-each-ref" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "--sort", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-committerdate", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--format", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0027%(committerdate:iso8601) %(refname:short)\u0027", + "kind": "Literal", + "isPath": false + }, + { + "raw": "refs/heads", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/refs/heads" + }, + { + "raw": "refs/remotes", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/refs/remotes" + }, + { + "raw": "--count", + "kind": "Literal", + "isPath": false + }, + { + "raw": "40", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "for-each-ref", + "value": "for-each-ref", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 12, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "--sort=-committerdate", + "value": "--sort=-committerdate", + "role": "Argument", + "sourceStart": 36, + "sourceLength": 21, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--format=\u0027%(committerdate:iso8601) %(refname:short)\u0027", + "value": "--format=%(committerdate:iso8601) %(refname:short)", + "role": "Argument", + "sourceStart": 58, + "sourceLength": 52, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "refs/heads", + "value": "refs/heads", + "role": "Argument", + "sourceStart": 111, + "sourceLength": 10, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/refs/heads" + }, + { + "raw": "refs/remotes", + "value": "refs/remotes", + "role": "Argument", + "sourceStart": 122, + "sourceLength": 12, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/refs/remotes" + }, + { + "raw": "--count=40", + "value": "--count=40", + "role": "Argument", + "sourceStart": 135, + "sourceLength": 10, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 145, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 145, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "Ordinary", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 145 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "--sort" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-committerdate" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--format" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 5, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--format=%(committerdate:iso8601) %(refname:short)" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 6, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "refs/heads" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 7, + "clauseElementIndex": 7, + "value": { + "kind": "Exact", + "values": [ + "refs/remotes" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 8, + "clauseElementIndex": 8, + "value": { + "kind": "Exact", + "values": [ + "--count" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 9, + "clauseElementIndex": 8, + "value": { + "kind": "Exact", + "values": [ + "40" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: bounded ref listing with authored format." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/551_v04_live_git_tree_client_filter.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/551_v04_live_git_tree_client_filter.json new file mode 100644 index 0000000..019a51e --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/551_v04_live_git_tree_client_filter.json @@ -0,0 +1,548 @@ +{ + "name": "V04 live git tree client filter", + "input": "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | Select-String -Pattern \u0022client\u0022 -CaseSensitive:$false | Select-Object -First 60", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "ls-tree" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "-r", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--name-only", + "kind": "Literal", + "isPath": false + }, + { + "raw": "feature/sample-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "ls-tree", + "value": "ls-tree", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-r", + "value": "-r", + "role": "Argument", + "sourceStart": 31, + "sourceLength": 2, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--name-only", + "value": "--name-only", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 11, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "feature/sample-branch", + "value": "feature/sample-branch", + "role": "Argument", + "sourceStart": 46, + "sourceLength": 21, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022client\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 70, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 84, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022client\u0022", + "value": "client", + "role": "Argument", + "sourceStart": 93, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 102, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-Object" + ], + "args": [ + { + "raw": "-First", + "kind": "Literal", + "isPath": false + }, + { + "raw": "60", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-Object", + "value": "Select-Object", + "role": "Verb", + "sourceStart": 126, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-First", + "value": "-First", + "role": "Argument", + "sourceStart": 140, + "sourceLength": 6, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "60", + "value": "60", + "role": "Argument", + "sourceStart": 147, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 149, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 149, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 67, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 70, + "sourceLength": 53, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 126, + "sourceLength": 23, + "clauseIndex": 2, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 149 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 149 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-r" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--name-only" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "feature/sample-branch" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 149 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 149 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "client" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 2, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 149 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 0, + "sourceLength": 149 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-First" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "60" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: tree listing with bounded client filter." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/552_v04_live_git_tree_client_model_filter.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/552_v04_live_git_tree_client_model_filter.json new file mode 100644 index 0000000..e22a95b --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/552_v04_live_git_tree_client_model_filter.json @@ -0,0 +1,591 @@ +{ + "name": "V04 live git tree client model filter", + "input": "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | Select-String -Pattern \u0022client\u0022 -CaseSensitive:$false | Select-String -Pattern \u0022model|dto|shared\u0022 -CaseSensitive:$false", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "ls-tree" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "-r", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--name-only", + "kind": "Literal", + "isPath": false + }, + { + "raw": "feature/sample-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "ls-tree", + "value": "ls-tree", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-r", + "value": "-r", + "role": "Argument", + "sourceStart": 31, + "sourceLength": 2, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--name-only", + "value": "--name-only", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 11, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "feature/sample-branch", + "value": "feature/sample-branch", + "role": "Argument", + "sourceStart": 46, + "sourceLength": 21, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022client\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 70, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 84, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022client\u0022", + "value": "client", + "role": "Argument", + "sourceStart": 93, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 102, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022model|dto|shared\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 126, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 140, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022model|dto|shared\u0022", + "value": "model|dto|shared", + "role": "Argument", + "sourceStart": 149, + "sourceLength": 18, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 168, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 189, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 67, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 70, + "sourceLength": 53, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 126, + "sourceLength": 63, + "clauseIndex": 2, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-r" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--name-only" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "feature/sample-branch" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "client" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 2, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "model|dto|shared" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: tree listing with chained model filter." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/553_v04_live_git_tree_models_filter.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/553_v04_live_git_tree_models_filter.json new file mode 100644 index 0000000..6736441 --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/553_v04_live_git_tree_models_filter.json @@ -0,0 +1,425 @@ +{ + "name": "V04 live git tree models filter", + "input": "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | Select-String -Pattern \u0022models/.*application|models/.*instance\u0022 -CaseSensitive:$false", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "ls-tree" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "-r", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--name-only", + "kind": "Literal", + "isPath": false + }, + { + "raw": "feature/sample-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "ls-tree", + "value": "ls-tree", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-r", + "value": "-r", + "role": "Argument", + "sourceStart": 31, + "sourceLength": 2, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--name-only", + "value": "--name-only", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 11, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "feature/sample-branch", + "value": "feature/sample-branch", + "role": "Argument", + "sourceStart": 46, + "sourceLength": 21, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022models/.*application|models/.*instance\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 70, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 84, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022models/.*application|models/.*instance\u0022", + "value": "models/.*application|models/.*instance", + "role": "Argument", + "sourceStart": 93, + "sourceLength": 40, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 134, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 155, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 155, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 67, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 70, + "sourceLength": 85, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 155 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 155 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-r" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--name-only" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "feature/sample-branch" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 155 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 155 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "models/.*application|models/.*instance" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: tree listing with bounded model path filter." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/554_v04_live_git_tree_project_library_filter.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/554_v04_live_git_tree_project_library_filter.json new file mode 100644 index 0000000..b34691e --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/554_v04_live_git_tree_project_library_filter.json @@ -0,0 +1,548 @@ +{ + "name": "V04 live git tree project library filter", + "input": "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | Select-String -Pattern \u0022projects/example/common/src/lib\u0022 | Select-String -Pattern \u0022model\u0022 -CaseSensitive:$false", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "ls-tree" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "-r", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--name-only", + "kind": "Literal", + "isPath": false + }, + { + "raw": "feature/sample-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "ls-tree", + "value": "ls-tree", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-r", + "value": "-r", + "role": "Argument", + "sourceStart": 31, + "sourceLength": 2, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--name-only", + "value": "--name-only", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 11, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "feature/sample-branch", + "value": "feature/sample-branch", + "role": "Argument", + "sourceStart": 46, + "sourceLength": 21, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022projects/example/common/src/lib\u0022", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 70, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 84, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022projects/example/common/src/lib\u0022", + "value": "projects/example/common/src/lib", + "role": "Argument", + "sourceStart": 93, + "sourceLength": 33, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022model\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 129, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 143, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022model\u0022", + "value": "model", + "role": "Argument", + "sourceStart": 152, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 160, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 181, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 181, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 67, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 70, + "sourceLength": 56, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 129, + "sourceLength": 52, + "clauseIndex": 2, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 181 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 181 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-r" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--name-only" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "feature/sample-branch" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 181 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 181 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "projects/example/common/src/lib" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 2, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 181 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 0, + "sourceLength": 181 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "model" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: tree listing with project-library model filter." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/555_v04_live_git_tree_project_library_skip.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/555_v04_live_git_tree_project_library_skip.json new file mode 100644 index 0000000..d9a6fc5 --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/555_v04_live_git_tree_project_library_skip.json @@ -0,0 +1,671 @@ +{ + "name": "V04 live git tree project library skip", + "input": "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | Select-String -Pattern \u0022projects/example/common/src/lib\u0022 | Select-String -Pattern \u0022model\u0022 -CaseSensitive:$false | Select-Object -Skip 20", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "ls-tree" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "-r", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--name-only", + "kind": "Literal", + "isPath": false + }, + { + "raw": "feature/sample-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "ls-tree", + "value": "ls-tree", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-r", + "value": "-r", + "role": "Argument", + "sourceStart": 31, + "sourceLength": 2, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--name-only", + "value": "--name-only", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 11, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "feature/sample-branch", + "value": "feature/sample-branch", + "role": "Argument", + "sourceStart": 46, + "sourceLength": 21, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022projects/example/common/src/lib\u0022", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 70, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 84, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022projects/example/common/src/lib\u0022", + "value": "projects/example/common/src/lib", + "role": "Argument", + "sourceStart": 93, + "sourceLength": 33, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022model\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 129, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 143, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022model\u0022", + "value": "model", + "role": "Argument", + "sourceStart": 152, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 160, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-Object" + ], + "args": [ + { + "raw": "-Skip", + "kind": "Literal", + "isPath": false + }, + { + "raw": "20", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-Object", + "value": "Select-Object", + "role": "Verb", + "sourceStart": 184, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Skip", + "value": "-Skip", + "role": "Argument", + "sourceStart": 198, + "sourceLength": 5, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "20", + "value": "20", + "role": "Argument", + "sourceStart": 204, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 206, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 206, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 67, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 70, + "sourceLength": 56, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 129, + "sourceLength": 52, + "clauseIndex": 2, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 3, + "sourceStart": 184, + "sourceLength": 22, + "clauseIndex": 3, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 206 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 206 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-r" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--name-only" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "feature/sample-branch" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 206 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 206 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "projects/example/common/src/lib" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 2, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 206 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 0, + "sourceLength": 206 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "model" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 3, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 206 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 3, + "sourceStart": 0, + "sourceLength": 206 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Skip" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "20" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: tree listing with skipped result prefix." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/556_v04_live_git_show_interface_documentation.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/556_v04_live_git_show_interface_documentation.json new file mode 100644 index 0000000..338ebf7 --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/556_v04_live_git_show_interface_documentation.json @@ -0,0 +1,185 @@ +{ + "name": "V04 live git show interface documentation", + "input": "git -C C:\\WORK\\PROJECT show feature/sample-branch:src/client/documentation/interfaces/application-models.md", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "show" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "feature/sample-branch:src/client/documentation/interfaces/application-models.md", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/feature/sample-branch:src/client/documentation/interfaces/application-models.md" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "show", + "value": "show", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 4, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "feature/sample-branch:src/client/documentation/interfaces/application-models.md", + "value": "feature/sample-branch:src/client/documentation/interfaces/application-models.md", + "role": "Argument", + "sourceStart": 28, + "sourceLength": 79, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/feature/sample-branch:src/client/documentation/interfaces/application-models.md" + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 107, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 107, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "Ordinary", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 107 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "feature/sample-branch:src/client/documentation/interfaces/application-models.md" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: exact repository documentation retrieval." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/557_v04_live_git_diff_stat_filter.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/557_v04_live_git_diff_stat_filter.json new file mode 100644 index 0000000..a7710ee --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/557_v04_live_git_diff_stat_filter.json @@ -0,0 +1,520 @@ +{ + "name": "V04 live git diff stat filter", + "input": "git -C C:\\WORK\\PROJECT diff --stat origin/dev...feature/sample-branch | Select-String -Pattern \u0022client|model|dto\u0022 -CaseSensitive:$false | Select-Object -First 60", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "diff" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "--stat", + "kind": "Literal", + "isPath": false + }, + { + "raw": "origin/dev...feature/sample-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/origin/dev...feature/sample-branch" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "diff", + "value": "diff", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 4, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "--stat", + "value": "--stat", + "role": "Argument", + "sourceStart": 28, + "sourceLength": 6, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "origin/dev...feature/sample-branch", + "value": "origin/dev...feature/sample-branch", + "role": "Argument", + "sourceStart": 35, + "sourceLength": 34, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/origin/dev...feature/sample-branch" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022client|model|dto\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 72, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 86, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022client|model|dto\u0022", + "value": "client|model|dto", + "role": "Argument", + "sourceStart": 95, + "sourceLength": 18, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 114, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-Object" + ], + "args": [ + { + "raw": "-First", + "kind": "Literal", + "isPath": false + }, + { + "raw": "60", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-Object", + "value": "Select-Object", + "role": "Verb", + "sourceStart": 138, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-First", + "value": "-First", + "role": "Argument", + "sourceStart": 152, + "sourceLength": 6, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "60", + "value": "60", + "role": "Argument", + "sourceStart": 159, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 161, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 161, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 69, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 72, + "sourceLength": 63, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 138, + "sourceLength": 23, + "clauseIndex": 2, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 161 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 161 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "--stat" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "origin/dev...feature/sample-branch" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 161 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 161 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "client|model|dto" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 2, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 161 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 0, + "sourceLength": 161 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-First" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "60" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: bounded diff-stat filtering." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/558_v04_live_git_tree_instance_filter.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/558_v04_live_git_tree_instance_filter.json new file mode 100644 index 0000000..bfe37c0 --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/558_v04_live_git_tree_instance_filter.json @@ -0,0 +1,425 @@ +{ + "name": "V04 live git tree instance filter", + "input": "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | Select-String -Pattern \u0022instance\u0022 -CaseSensitive:$false", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "ls-tree" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "-r", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--name-only", + "kind": "Literal", + "isPath": false + }, + { + "raw": "feature/sample-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "ls-tree", + "value": "ls-tree", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-r", + "value": "-r", + "role": "Argument", + "sourceStart": 31, + "sourceLength": 2, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--name-only", + "value": "--name-only", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 11, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "feature/sample-branch", + "value": "feature/sample-branch", + "role": "Argument", + "sourceStart": 46, + "sourceLength": 21, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022instance\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 70, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 84, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022instance\u0022", + "value": "instance", + "role": "Argument", + "sourceStart": 93, + "sourceLength": 10, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 104, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 125, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 125, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 67, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 70, + "sourceLength": 55, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 125 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 125 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-r" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--name-only" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "feature/sample-branch" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 125 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 125 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "instance" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: tree listing with instance filter." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/559_v04_live_git_tree_alternate_branch_filter.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/559_v04_live_git_tree_alternate_branch_filter.json new file mode 100644 index 0000000..fbbdffa --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/559_v04_live_git_tree_alternate_branch_filter.json @@ -0,0 +1,671 @@ +{ + "name": "V04 live git tree alternate branch filter", + "input": "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/alternate-branch | Select-String -Pattern \u0022src/client\u0022 | Select-String -Pattern \u0022model\u0022 -CaseSensitive:$false | Select-Object -First 40", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "ls-tree" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "-r", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--name-only", + "kind": "Literal", + "isPath": false + }, + { + "raw": "feature/alternate-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/feature/alternate-branch" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "ls-tree", + "value": "ls-tree", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-r", + "value": "-r", + "role": "Argument", + "sourceStart": 31, + "sourceLength": 2, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--name-only", + "value": "--name-only", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 11, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "feature/alternate-branch", + "value": "feature/alternate-branch", + "role": "Argument", + "sourceStart": 46, + "sourceLength": 24, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/feature/alternate-branch" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022src/client\u0022", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 73, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 87, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022src/client\u0022", + "value": "src/client", + "role": "Argument", + "sourceStart": 96, + "sourceLength": 12, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022model\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 111, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 125, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022model\u0022", + "value": "model", + "role": "Argument", + "sourceStart": 134, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 142, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-Object" + ], + "args": [ + { + "raw": "-First", + "kind": "Literal", + "isPath": false + }, + { + "raw": "40", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-Object", + "value": "Select-Object", + "role": "Verb", + "sourceStart": 166, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-First", + "value": "-First", + "role": "Argument", + "sourceStart": 180, + "sourceLength": 6, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "40", + "value": "40", + "role": "Argument", + "sourceStart": 187, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 189, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 70, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 73, + "sourceLength": 35, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 111, + "sourceLength": 52, + "clauseIndex": 2, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 3, + "sourceStart": 166, + "sourceLength": 23, + "clauseIndex": 3, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-r" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--name-only" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "feature/alternate-branch" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "src/client" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 2, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "model" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 3, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 3, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-First" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "40" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: alternate-branch tree filtering." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/560_v04_live_git_tree_remote_alternate_branch_filter.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/560_v04_live_git_tree_remote_alternate_branch_filter.json new file mode 100644 index 0000000..fa313c0 --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/560_v04_live_git_tree_remote_alternate_branch_filter.json @@ -0,0 +1,671 @@ +{ + "name": "V04 live git tree remote alternate branch filter", + "input": "git -C C:\\WORK\\PROJECT ls-tree -r --name-only origin/feature/alternate-branch | Select-String -Pattern \u0022src/client\u0022 | Select-String -Pattern \u0022model\u0022 -CaseSensitive:$false | Select-Object -First 40", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "ls-tree" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "-r", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--name-only", + "kind": "Literal", + "isPath": false + }, + { + "raw": "origin/feature/alternate-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/origin/feature/alternate-branch" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "ls-tree", + "value": "ls-tree", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-r", + "value": "-r", + "role": "Argument", + "sourceStart": 31, + "sourceLength": 2, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--name-only", + "value": "--name-only", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 11, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "origin/feature/alternate-branch", + "value": "origin/feature/alternate-branch", + "role": "Argument", + "sourceStart": 46, + "sourceLength": 31, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/origin/feature/alternate-branch" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022src/client\u0022", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 80, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 94, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022src/client\u0022", + "value": "src/client", + "role": "Argument", + "sourceStart": 103, + "sourceLength": 12, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022model\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 118, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 132, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022model\u0022", + "value": "model", + "role": "Argument", + "sourceStart": 141, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 149, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-Object" + ], + "args": [ + { + "raw": "-First", + "kind": "Literal", + "isPath": false + }, + { + "raw": "40", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-Object", + "value": "Select-Object", + "role": "Verb", + "sourceStart": 173, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-First", + "value": "-First", + "role": "Argument", + "sourceStart": 187, + "sourceLength": 6, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "40", + "value": "40", + "role": "Argument", + "sourceStart": 194, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 196, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 196, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 77, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 80, + "sourceLength": 35, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 118, + "sourceLength": 52, + "clauseIndex": 2, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 3, + "sourceStart": 173, + "sourceLength": 23, + "clauseIndex": 3, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 196 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 196 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-r" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--name-only" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "origin/feature/alternate-branch" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 196 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 196 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "src/client" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 2, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 196 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 0, + "sourceLength": 196 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "model" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 3, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 196 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 3, + "sourceStart": 0, + "sourceLength": 196 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-First" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "40" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: remote alternate-branch tree filtering." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/561_v04_live_git_tree_client_project_segments.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/561_v04_live_git_tree_client_project_segments.json new file mode 100644 index 0000000..29a36c4 --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/561_v04_live_git_tree_client_project_segments.json @@ -0,0 +1,597 @@ +{ + "name": "V04 live git tree client project segments", + "input": "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | Select-String -Pattern \u0022src/client/projects\u0022 | ForEach-Object { ($_ -split \u0027/\u0027)[0..3] -join \u0027/\u0027 } | Sort-Object -Unique", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "ls-tree" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "-r", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--name-only", + "kind": "Literal", + "isPath": false + }, + { + "raw": "feature/sample-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "ls-tree", + "value": "ls-tree", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-r", + "value": "-r", + "role": "Argument", + "sourceStart": 31, + "sourceLength": 2, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--name-only", + "value": "--name-only", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 11, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "feature/sample-branch", + "value": "feature/sample-branch", + "role": "Argument", + "sourceStart": 46, + "sourceLength": 21, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022src/client/projects\u0022", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 70, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 84, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022src/client/projects\u0022", + "value": "src/client/projects", + "role": "Argument", + "sourceStart": 93, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "ForEach-Object" + ], + "args": [ + { + "raw": "{ ($_ -split \u0027/\u0027)[0..3] -join \u0027/\u0027 }", + "kind": "DynamicSkip", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "ForEach-Object", + "value": "ForEach-Object", + "role": "Verb", + "sourceStart": 117, + "sourceLength": 14, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "{ ($_ -split \u0027/\u0027)[0..3] -join \u0027/\u0027 }", + "value": "{ ($_ -split \u0027/\u0027)[0..3] -join \u0027/\u0027 }", + "role": "Argument", + "sourceStart": 132, + "sourceLength": 35, + "precedingVerbElementCount": 1, + "kind": "DynamicSkip", + "isFlag": false, + "isPath": false + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Sort-Object" + ], + "args": [ + { + "raw": "-Unique", + "kind": "Literal", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Sort-Object", + "value": "Sort-Object", + "role": "Verb", + "sourceStart": 170, + "sourceLength": 11, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Unique", + "value": "-Unique", + "role": "Argument", + "sourceStart": 182, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 189, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 67, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 70, + "sourceLength": 44, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 117, + "sourceLength": 50, + "clauseIndex": 2, + "groupKind": null, + "listOperator": null + }, + { + "kind": "ExecutionRegion", + "parentIndex": 4, + "region": "ExecutionRegion", + "childIndex": 0, + "sourceStart": 132, + "sourceLength": 35, + "clauseIndex": null, + "groupKind": null, + "listOperator": null, + "executionOrigin": "CommandArgument", + "hostClauseElementIndex": 1, + "executionPhase": "Process", + "executionTiming": "Synchronous", + "executionCardinality": "OncePerInputObject" + }, + { + "kind": "Block", + "parentIndex": 5, + "region": "ExecutionRegion", + "childIndex": 0, + "sourceStart": 133, + "sourceLength": 33, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 3, + "sourceStart": 170, + "sourceLength": 19, + "clauseIndex": 3, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-r" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--name-only" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "feature/sample-branch" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "src/client/projects" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 2, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 2, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 3, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 189 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 3, + "sourceStart": 0, + "sourceLength": 189 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Unique" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: unique projected tree segments." +} diff --git a/tests/ShellSyntaxTree.Tests/Corpus/powershell/562_v04_live_git_tree_example_client_filter.json b/tests/ShellSyntaxTree.Tests/Corpus/powershell/562_v04_live_git_tree_example_client_filter.json new file mode 100644 index 0000000..45e14c9 --- /dev/null +++ b/tests/ShellSyntaxTree.Tests/Corpus/powershell/562_v04_live_git_tree_example_client_filter.json @@ -0,0 +1,455 @@ +{ + "name": "V04 live git tree example client filter", + "input": "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch \u0022examples/Example.App.Client/src/app\u0022 | Select-String -Pattern \u0022model|dto\u0022 -CaseSensitive:$false", + "expected": { + "isUnparseable": false, + "clauses": [ + { + "operator": "None", + "verb": [ + "git", + "ls-tree" + ], + "args": [ + { + "raw": "-C", + "kind": "Literal", + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "kind": "Literal", + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "-r", + "kind": "Literal", + "isPath": false + }, + { + "raw": "--name-only", + "kind": "Literal", + "isPath": false + }, + { + "raw": "feature/sample-branch", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + }, + { + "raw": "\u0022examples/Example.App.Client/src/app\u0022", + "kind": "Literal", + "isPath": true, + "resolved": "C:/work/examples/Example.App.Client/src/app" + } + ], + "redirects": [], + "elements": [ + { + "raw": "git", + "value": "git", + "role": "Verb", + "sourceStart": 0, + "sourceLength": 3, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-C", + "value": "-C", + "role": "Argument", + "sourceStart": 4, + "sourceLength": 2, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "C:\\WORK\\PROJECT", + "value": "C:\\WORK\\PROJECT", + "role": "Argument", + "sourceStart": 7, + "sourceLength": 15, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/WORK/PROJECT" + }, + { + "raw": "ls-tree", + "value": "ls-tree", + "role": "Verb", + "sourceStart": 23, + "sourceLength": 7, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-r", + "value": "-r", + "role": "Argument", + "sourceStart": 31, + "sourceLength": 2, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "--name-only", + "value": "--name-only", + "role": "Argument", + "sourceStart": 34, + "sourceLength": 11, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "feature/sample-branch", + "value": "feature/sample-branch", + "role": "Argument", + "sourceStart": 46, + "sourceLength": 21, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/feature/sample-branch" + }, + { + "raw": "\u0022examples/Example.App.Client/src/app\u0022", + "value": "examples/Example.App.Client/src/app", + "role": "Argument", + "sourceStart": 68, + "sourceLength": 37, + "precedingVerbElementCount": 2, + "kind": "Literal", + "isFlag": false, + "isPath": true, + "resolved": "C:/work/examples/Example.App.Client/src/app" + } + ] + }, + { + "operator": "Pipe", + "verb": [ + "Select-String" + ], + "args": [ + { + "raw": "-Pattern", + "kind": "Literal", + "isPath": false + }, + { + "raw": "\u0022model|dto\u0022", + "kind": "Literal", + "isPath": false + }, + { + "raw": "-CaseSensitive", + "kind": "Literal", + "isPath": false + }, + { + "raw": "$false", + "kind": "EnvVar", + "isPath": false + } + ], + "redirects": [], + "elements": [ + { + "raw": "Select-String", + "value": "Select-String", + "role": "Verb", + "sourceStart": 108, + "sourceLength": 13, + "precedingVerbElementCount": 0, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-Pattern", + "value": "-Pattern", + "role": "Argument", + "sourceStart": 122, + "sourceLength": 8, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": true, + "isPath": false + }, + { + "raw": "\u0022model|dto\u0022", + "value": "model|dto", + "role": "Argument", + "sourceStart": 131, + "sourceLength": 11, + "precedingVerbElementCount": 1, + "kind": "Literal", + "isFlag": false, + "isPath": false + }, + { + "raw": "-CaseSensitive:$false", + "value": "-CaseSensitive:$false", + "role": "Argument", + "sourceStart": 143, + "sourceLength": 21, + "precedingVerbElementCount": 1, + "kind": "EnvVar", + "isFlag": true, + "isPath": false + } + ] + } + ], + "syntax": [ + { + "kind": "Block", + "parentIndex": null, + "region": "Unknown", + "childIndex": null, + "sourceStart": 0, + "sourceLength": 164, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "Pipeline", + "parentIndex": 0, + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 164, + "clauseIndex": null, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 105, + "clauseIndex": 0, + "groupKind": null, + "listOperator": null + }, + { + "kind": "SimpleCommand", + "parentIndex": 1, + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 108, + "sourceLength": 56, + "clauseIndex": 1, + "groupKind": null, + "listOperator": null + } + ], + "commands": [ + { + "clauseIndex": 0, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 164 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 164 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-C" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "C:\\WORK\\PROJECT" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 4, + "value": { + "kind": "Exact", + "values": [ + "-r" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 5, + "value": { + "kind": "Exact", + "values": [ + "--name-only" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 4, + "clauseElementIndex": 6, + "value": { + "kind": "Exact", + "values": [ + "feature/sample-branch" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 5, + "clauseElementIndex": 7, + "value": { + "kind": "Exact", + "values": [ + "examples/Example.App.Client/src/app" + ], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + }, + { + "clauseIndex": 1, + "immediateRole": "PipelineStage", + "isComplete": true, + "ancestry": [ + { + "ancestorKind": "Block", + "region": "Root", + "childIndex": 0, + "sourceStart": 0, + "sourceLength": 164 + }, + { + "ancestorKind": "Pipeline", + "region": "PipelineStage", + "childIndex": 1, + "sourceStart": 0, + "sourceLength": 164 + } + ], + "arguments": [ + { + "clauseArgumentIndex": 0, + "clauseElementIndex": 1, + "value": { + "kind": "Exact", + "values": [ + "-Pattern" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 1, + "clauseElementIndex": 2, + "value": { + "kind": "Exact", + "values": [ + "model|dto" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 2, + "clauseElementIndex": 3, + "value": { + "kind": "Exact", + "values": [ + "-CaseSensitive" + ], + "pattern": null, + "coveringDirectory": null + } + }, + { + "clauseArgumentIndex": 3, + "clauseElementIndex": 3, + "value": { + "kind": "Unknown", + "values": [], + "pattern": null, + "coveringDirectory": null + } + } + ], + "workingDirectory": { + "kind": "Exact", + "values": [ + "C:/work" + ], + "pattern": null, + "coveringDirectory": null + }, + "workingDirectoryEffect": { + "kind": "Unchanged" + } + } + ] + }, + "notes": "Sanitized deployed-consumer approval prompt: scoped example-client model filter." +} diff --git a/tests/ShellSyntaxTree.Tests/Parsing/PwshExecutionRegionStructuralTests.cs b/tests/ShellSyntaxTree.Tests/Parsing/PwshExecutionRegionStructuralTests.cs index fa9dc91..bd8b2cd 100644 --- a/tests/ShellSyntaxTree.Tests/Parsing/PwshExecutionRegionStructuralTests.cs +++ b/tests/ShellSyntaxTree.Tests/Parsing/PwshExecutionRegionStructuralTests.cs @@ -1230,6 +1230,43 @@ public void Pure_output_expressions_do_not_invent_command_occurrences(string sou Assert.True(result.Commands[0].IsComplete); } + [Theory] + [InlineData(PwshDialect.PowerShell7, "ForEach-Object { ($_ -split '/')[0..3] -join '/' }")] + [InlineData(PwshDialect.PowerShell7, "ForEach-Object { ($PSItem -split \"/\")[2] -join \"/\" }")] + [InlineData(PwshDialect.PowerShell7, "ForEach-Object { ($_ -SPLIT '/')[0] -JOIN '/' }")] + [InlineData(PwshDialect.WindowsPowerShell51, "ForEach-Object { ($_ -split '/')[0..3] -join '/' }")] + public void Static_split_index_join_projection_contains_no_authored_commands( + PwshDialect dialect, + string source) + { + var result = ParseIsolatedRaw(source, dialect); + + Assert.False(result.IsUnparseable, result.UnparseableReason); + Assert.Single(result.Commands); + Assert.True(result.Commands[0].IsComplete); + Assert.Empty(Assert.Single( + Assert.IsType(Assert.Single(result.Syntax.Statements)) + .ExecutionRegions).Body.Statements); + } + + [Theory] + [InlineData("ForEach-Object { ($_ -split '/')[0..$(Get-Date)] -join '/' }")] + [InlineData("ForEach-Object { ($_ -split $separator)[0] -join '/' }")] + [InlineData("ForEach-Object { ($_ -split '/')[0] -join $(Get-Date) }")] + [InlineData("ForEach-Object { ($_ -split '/')[0].ToString() -join '/' }")] + [InlineData("ForEach-Object { ($_ -split '/')[0] -join '/'; Get-Date }")] + [InlineData("ForEach-Object { $value = ($_ -split '/')[0] -join '/' }")] + [InlineData("ForEach-Object { ($_ -split '/')\n[0..3] -join '/' }")] + [InlineData("ForEach-Object { ($_ -split '/')[0] -join '/'\nGet-Date }")] + public void Unsupported_split_index_join_projection_shapes_fail_closed(string source) + { + var result = ParseIsolatedRaw(source, PwshDialect.PowerShell7); + + Assert.True(result.IsUnparseable); + Assert.Empty(result.Commands); + Assert.Empty(result.Clauses); + } + [Theory] [InlineData( "Get-ChildItem . | Where-Object { $_.Length -gt 0 }", diff --git a/tools/PwshCorpusTool/CorpusManifest.cs b/tools/PwshCorpusTool/CorpusManifest.cs index 3610aba..d761193 100644 --- a/tools/PwshCorpusTool/CorpusManifest.cs +++ b/tools/PwshCorpusTool/CorpusManifest.cs @@ -1554,5 +1554,66 @@ private static string NestIex(string inner, int depth) VIE("v04_gci_dynamic_follow_unknown_tree_access", "Get-ChildItem -Path C:\\WORK\\PROJECT -Recurse -FollowSymlink:$follow", "Pins the all-Unknown tree-access marker for an unproved link-follow value."), + VE("v04_live_recursive_directory_filter", + "Get-ChildItem -Path C:\\Users\\user -Recurse -Directory -ErrorAction SilentlyContinue | " + + "Where-Object { $_.Name -like \"*sample*\" -or $_.Name -like \"*project*\" } | " + + "Select-Object -First 30 FullName", + "Sanitized deployed-consumer approval prompt: recursive directory filtering and bounded projection."), + VE("v04_live_git_ref_listing", + "git -C C:\\WORK\\PROJECT for-each-ref --sort=-committerdate --format='%(committerdate:iso8601) %(refname:short)' refs/heads refs/remotes --count=40", + "Sanitized deployed-consumer approval prompt: bounded ref listing with authored format."), + VE("v04_live_git_tree_client_filter", + "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | " + + "Select-String -Pattern \"client\" -CaseSensitive:$false | Select-Object -First 60", + "Sanitized deployed-consumer approval prompt: tree listing with bounded client filter."), + VE("v04_live_git_tree_client_model_filter", + "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | " + + "Select-String -Pattern \"client\" -CaseSensitive:$false | " + + "Select-String -Pattern \"model|dto|shared\" -CaseSensitive:$false", + "Sanitized deployed-consumer approval prompt: tree listing with chained model filter."), + VE("v04_live_git_tree_models_filter", + "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | " + + "Select-String -Pattern \"models/.*application|models/.*instance\" -CaseSensitive:$false", + "Sanitized deployed-consumer approval prompt: tree listing with bounded model path filter."), + VE("v04_live_git_tree_project_library_filter", + "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | " + + "Select-String -Pattern \"projects/example/common/src/lib\" | " + + "Select-String -Pattern \"model\" -CaseSensitive:$false", + "Sanitized deployed-consumer approval prompt: tree listing with project-library model filter."), + VE("v04_live_git_tree_project_library_skip", + "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | " + + "Select-String -Pattern \"projects/example/common/src/lib\" | " + + "Select-String -Pattern \"model\" -CaseSensitive:$false | Select-Object -Skip 20", + "Sanitized deployed-consumer approval prompt: tree listing with skipped result prefix."), + VE("v04_live_git_show_interface_documentation", + "git -C C:\\WORK\\PROJECT show feature/sample-branch:src/client/documentation/interfaces/application-models.md", + "Sanitized deployed-consumer approval prompt: exact repository documentation retrieval."), + VE("v04_live_git_diff_stat_filter", + "git -C C:\\WORK\\PROJECT diff --stat origin/dev...feature/sample-branch | " + + "Select-String -Pattern \"client|model|dto\" -CaseSensitive:$false | Select-Object -First 60", + "Sanitized deployed-consumer approval prompt: bounded diff-stat filtering."), + VE("v04_live_git_tree_instance_filter", + "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | " + + "Select-String -Pattern \"instance\" -CaseSensitive:$false", + "Sanitized deployed-consumer approval prompt: tree listing with instance filter."), + VE("v04_live_git_tree_alternate_branch_filter", + "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/alternate-branch | " + + "Select-String -Pattern \"src/client\" | Select-String -Pattern \"model\" -CaseSensitive:$false | " + + "Select-Object -First 40", + "Sanitized deployed-consumer approval prompt: alternate-branch tree filtering."), + VE("v04_live_git_tree_remote_alternate_branch_filter", + "git -C C:\\WORK\\PROJECT ls-tree -r --name-only origin/feature/alternate-branch | " + + "Select-String -Pattern \"src/client\" | Select-String -Pattern \"model\" -CaseSensitive:$false | " + + "Select-Object -First 40", + "Sanitized deployed-consumer approval prompt: remote alternate-branch tree filtering."), + VE("v04_live_git_tree_client_project_segments", + "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch | " + + "Select-String -Pattern \"src/client/projects\" | " + + "ForEach-Object { ($_ -split '/')[0..3] -join '/' } | Sort-Object -Unique", + "Sanitized deployed-consumer approval prompt: unique projected tree segments."), + VE("v04_live_git_tree_example_client_filter", + "git -C C:\\WORK\\PROJECT ls-tree -r --name-only feature/sample-branch \"examples/Example.App.Client/src/app\" | " + + "Select-String -Pattern \"model|dto\" -CaseSensitive:$false", + "Sanitized deployed-consumer approval prompt: scoped example-client model filter."), }; }