awsquery 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. {awsquery-0.1.0 → awsquery-0.2.0}/.claude/settings.local.json +3 -1
  2. awsquery-0.2.0/.dockerignore +52 -0
  3. {awsquery-0.1.0 → awsquery-0.2.0}/.gitignore +6 -0
  4. {awsquery-0.1.0 → awsquery-0.2.0}/CLAUDE.md +76 -1
  5. {awsquery-0.1.0 → awsquery-0.2.0}/Dockerfile +19 -13
  6. {awsquery-0.1.0 → awsquery-0.2.0}/Dockerfile.prod +10 -8
  7. {awsquery-0.1.0 → awsquery-0.2.0}/Makefile +16 -0
  8. {awsquery-0.1.0 → awsquery-0.2.0}/PKG-INFO +81 -15
  9. {awsquery-0.1.0 → awsquery-0.2.0}/README.md +79 -14
  10. {awsquery-0.1.0 → awsquery-0.2.0}/docker-compose.yml +0 -20
  11. awsquery-0.2.0/docs/mutation-testing.md +75 -0
  12. {awsquery-0.1.0 → awsquery-0.2.0}/pyproject.toml +8 -2
  13. awsquery-0.2.0/pytest.ini +13 -0
  14. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/cli.py +243 -63
  15. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/config.py +17 -9
  16. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/core.py +106 -63
  17. awsquery-0.2.0/src/awsquery/default_filters.yaml +2707 -0
  18. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/filters.py +102 -24
  19. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/formatters.py +137 -66
  20. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/security.py +25 -12
  21. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/utils.py +8 -5
  22. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/PKG-INFO +81 -15
  23. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/SOURCES.txt +18 -4
  24. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/requires.txt +1 -0
  25. awsquery-0.2.0/tests/__init__.py +1 -0
  26. {awsquery-0.1.0 → awsquery-0.2.0}/tests/conftest.py +7 -7
  27. awsquery-0.2.0/tests/integration/test_autocomplete_resilience.py +141 -0
  28. {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/test_end_to_end.py +40 -49
  29. {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/test_feature_combinations.py +57 -54
  30. {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/test_keys_behavior.py +41 -45
  31. {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/test_multi_level.py +91 -110
  32. awsquery-0.2.0/tests/integration/test_multi_level_calls.py +368 -0
  33. {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/test_session_management.py +20 -26
  34. awsquery-0.2.0/tests/unit/test_cli_arg_processing.py +418 -0
  35. awsquery-0.2.0/tests/unit/test_cli_flags.py +299 -0
  36. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_cli_parser.py +143 -49
  37. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_cli_session_args.py +28 -34
  38. awsquery-0.2.0/tests/unit/test_column_ordering.py +212 -0
  39. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_config_loading.py +4 -5
  40. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_core.py +62 -71
  41. awsquery-0.2.0/tests/unit/test_core_inference.py +172 -0
  42. awsquery-0.2.0/tests/unit/test_core_string_handling.py +193 -0
  43. awsquery-0.2.0/tests/unit/test_critical_mutations.py +216 -0
  44. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_default_column_filters.py +51 -49
  45. awsquery-0.2.0/tests/unit/test_filter_edge_cases.py +258 -0
  46. awsquery-0.2.0/tests/unit/test_filter_implementation.py +309 -0
  47. awsquery-0.2.0/tests/unit/test_filter_matching.py +280 -0
  48. awsquery-0.2.0/tests/unit/test_filter_parameter_extraction.py +212 -0
  49. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_filters.py +3 -6
  50. awsquery-0.2.0/tests/unit/test_filters_pattern_matching.py +282 -0
  51. awsquery-0.2.0/tests/unit/test_formatter_edge_cases.py +325 -0
  52. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_formatters.py +5 -14
  53. awsquery-0.2.0/tests/unit/test_formatters_data_processing.py +355 -0
  54. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_keys_display_fix.py +51 -57
  55. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_messaging_enhancements.py +58 -64
  56. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_security.py +16 -64
  57. awsquery-0.2.0/tests/unit/test_security_edge_cases.py +190 -0
  58. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_tags_transformation.py +6 -11
  59. awsquery-0.1.0/.dockerignore +0 -27
  60. awsquery-0.1.0/awsquery.py +0 -21
  61. awsquery-0.1.0/pytest.ini +0 -21
  62. awsquery-0.1.0/src/awsquery/default_filters.yaml +0 -76
  63. awsquery-0.1.0/tests/unit/test_flag_positioning.py +0 -245
  64. awsquery-0.1.0/tests/unit/test_flags_after_separator.py +0 -266
  65. awsquery-0.1.0/tests/unit/test_parser_regression.py +0 -202
  66. {awsquery-0.1.0 → awsquery-0.2.0}/.claude/agents/code-reviewer.md +0 -0
  67. {awsquery-0.1.0 → awsquery-0.2.0}/.claude/agents/makefile-optimizer.md +0 -0
  68. {awsquery-0.1.0 → awsquery-0.2.0}/.claude/agents/python-infra-automator.md +0 -0
  69. {awsquery-0.1.0 → awsquery-0.2.0}/.claude/agents/test-writer.md +0 -0
  70. {awsquery-0.1.0 → awsquery-0.2.0}/.coveragerc +0 -0
  71. {awsquery-0.1.0 → awsquery-0.2.0}/.devcontainer/devcontainer.json +0 -0
  72. {awsquery-0.1.0 → awsquery-0.2.0}/.flake8 +0 -0
  73. {awsquery-0.1.0 → awsquery-0.2.0}/.github/workflows/quality.yml +0 -0
  74. {awsquery-0.1.0 → awsquery-0.2.0}/.github/workflows/release.yml +0 -0
  75. {awsquery-0.1.0 → awsquery-0.2.0}/.github/workflows/test.yml +0 -0
  76. {awsquery-0.1.0 → awsquery-0.2.0}/LICENSE +0 -0
  77. {awsquery-0.1.0 → awsquery-0.2.0}/Todo.md +0 -0
  78. {awsquery-0.1.0 → awsquery-0.2.0}/docs/DOCKER.md +0 -0
  79. {awsquery-0.1.0 → awsquery-0.2.0}/policy.json +0 -0
  80. {awsquery-0.1.0 → awsquery-0.2.0}/requirements.txt +0 -0
  81. {awsquery-0.1.0 → awsquery-0.2.0}/setup.cfg +0 -0
  82. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/__init__.py +0 -0
  83. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/policy.json +0 -0
  84. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/dependency_links.txt +0 -0
  85. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/entry_points.txt +0 -0
  86. {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/top_level.txt +0 -0
  87. {awsquery-0.1.0 → awsquery-0.2.0}/tests/fixtures/__init__.py +0 -0
  88. {awsquery-0.1.0 → awsquery-0.2.0}/tests/fixtures/aws_responses.py +0 -0
  89. {awsquery-0.1.0 → awsquery-0.2.0}/tests/fixtures/policy_samples.py +0 -0
  90. {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/__init__.py +0 -0
  91. {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/__init__.py +0 -0
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "permissions": {
3
3
  "allow": [
4
- "Bash(python3 -m pytest tests/ --cov=src/awsquery --cov-report=term-missing -q)"
4
+ "Bash(python3 -m pytest tests/ --cov=src/awsquery --cov-report=term-missing -q)",
5
+ "Bash(mutmut show:*)",
6
+ "Bash(mutmut:*)"
5
7
  ],
6
8
  "deny": [],
7
9
  "ask": []
@@ -0,0 +1,52 @@
1
+ # Ignore sample responses directory during build
2
+ sample-responses/
3
+
4
+ # Ignore temporary files and caches
5
+ *.pyc
6
+ __pycache__/
7
+ .pytest_cache/
8
+ *.egg-info/
9
+ .mutmut-cache/
10
+ htmlcov/
11
+ .coverage
12
+ coverage.xml
13
+
14
+ # Ignore git and IDE files
15
+ .git/
16
+ .gitignore
17
+ .vscode/
18
+ .idea/
19
+ .claude/
20
+
21
+ # Ignore development and analysis files
22
+ scripts/
23
+ mutants/
24
+ docs/
25
+ awsinfo/
26
+ *.log
27
+ *.csv
28
+
29
+ # Ignore temporary/development files
30
+ core
31
+ Name
32
+ *.backup
33
+ *.backup.md
34
+ test_*.md
35
+ *Plan*.md
36
+ Todo.md
37
+ Initial.md
38
+ FixPlan.md
39
+ .envrc
40
+
41
+ # Ignore documentation (except essential README)
42
+ *.md
43
+ !README.md
44
+
45
+ # Ignore Docker files themselves
46
+ Dockerfile
47
+ Dockerfile.prod
48
+ docker-compose.yml
49
+ .dockerignore
50
+
51
+ # Ignore setup scripts that aren't needed in container
52
+ setup-autocomplete.sh
@@ -159,6 +159,12 @@ venv.bak/
159
159
  .dmypy.json
160
160
  dmypy.json
161
161
 
162
+ # mutmut
163
+ .mutmut-cache
164
+ .mutmutrc
165
+ html/
166
+ mutants
167
+
162
168
  # Pyre type checker
163
169
  .pyre/
164
170
 
@@ -65,10 +65,85 @@ The tool enforces security through a comprehensive `policy.json` file that defin
65
65
 
66
66
  ### Testing Structure
67
67
  - Unit tests in `tests/unit/` with `@pytest.mark.unit`
68
- - Integration tests in `tests/integration/` with `@pytest.mark.integration`
68
+ - Integration tests in `tests/integration/` with `@pytest.mark.integration`
69
69
  - Critical path tests marked with `@pytest.mark.critical`
70
70
  - AWS mocks using moto library marked with `@pytest.mark.aws`
71
71
 
72
+ ### STRICT Testing Requirements - MUST FOLLOW
73
+
74
+ #### 🚫 PROHIBITED: Test Anti-Patterns
75
+ **NEVER CREATE:**
76
+ 1. **Duplicate Test Files**: Before creating ANY test file, search for existing tests covering the same functionality
77
+ - Flag tests: Use `test_cli_flags.py` ONLY
78
+ - Parser tests: Use `test_cli_parser.py` ONLY
79
+ - Filter tests: Use `test_filter_implementation.py` for real tests, `test_filter_matching.py` for patterns
80
+ 2. **Over-Mocked Tests**: Tests that mock the very functions they claim to test
81
+ 3. **Mock Assertion Tests**: Tests that only verify `mock.assert_called()` without testing actual behavior
82
+ 4. **Nested Mock Contexts**: More than 2 levels of `with patch()` indicates over-mocking
83
+
84
+ #### ✅ REQUIRED: Test Best Practices
85
+ **ALWAYS:**
86
+ 1. **Test Real Implementation**:
87
+ ```python
88
+ # GOOD: Tests actual function
89
+ result = filter_resources(real_data, ["filter"])
90
+ assert len(result) == expected
91
+
92
+ # BAD: Only tests mock
93
+ mock_filter.return_value = []
94
+ mock_filter.assert_called_once()
95
+ ```
96
+
97
+ 2. **Minimal Mocking**: Only mock external dependencies (boto3, file I/O, network)
98
+ ```python
99
+ # GOOD: Only mock AWS
100
+ @patch("boto3.client")
101
+ def test_feature(mock_client):
102
+ # Test real code with mocked AWS
103
+
104
+ # BAD: Mock everything
105
+ @patch("filter_resources")
106
+ @patch("format_output")
107
+ @patch("parse_args")
108
+ ```
109
+
110
+ 3. **Consolidate Related Tests**: Group similar tests in one file
111
+ - All flag position tests → `test_cli_flags.py`
112
+ - All parser tests → `test_cli_parser.py`
113
+ - All filter implementation → `test_filter_implementation.py`
114
+
115
+ 4. **Test Edge Cases**: Include malformed input, Unicode, empty values
116
+ ```python
117
+ # Test edge cases
118
+ test_cases = ["", None, "^$", "ˆ", "$^", "^^$$"]
119
+ ```
120
+
121
+ 5. **Verify Actual Output**: Check real results, not mock calls
122
+ ```python
123
+ # GOOD: Verify actual JSON
124
+ output = format_json_output(data, filters)
125
+ parsed = json.loads(output) # Ensures valid JSON
126
+
127
+ # BAD: Only check mock called
128
+ mock_json.assert_called_once()
129
+ ```
130
+
131
+ #### 📋 Test Review Checklist
132
+ Before committing ANY test:
133
+ 1. ❓ Does a test file for this feature already exist?
134
+ 2. ❓ Am I testing real code or just mocks?
135
+ 3. ❓ Do assertions verify actual behavior?
136
+ 4. ❓ Is mocking limited to external dependencies only?
137
+ 5. ❓ Are edge cases covered?
138
+
139
+ #### 🔍 Finding Duplicate Tests
140
+ ```bash
141
+ # Check for existing tests before creating new ones
142
+ grep -r "test.*flag.*position" tests/
143
+ grep -r "test.*parser" tests/
144
+ grep -r "test.*filter" tests/
145
+ ```
146
+
72
147
  ### Test Documentation Requirements
73
148
  - **Minimal Comments**: Remove all unnecessary verbose comments from test files
74
149
  - **Essential Only**: Keep comments only for complex test logic, specific assertions, or edge cases
@@ -1,5 +1,10 @@
1
1
  FROM python:3.11-slim
2
2
 
3
+ # Development Dockerfile optimized for volume mounts
4
+ # Only copies essential files needed for package installation
5
+ # Development files (scripts/, docs/, test analysis files) are excluded
6
+ # and will be available via volume mounts in docker-compose
7
+
3
8
  # Install system dependencies
4
9
  RUN apt-get update && apt-get install -y \
5
10
  make \
@@ -27,27 +32,28 @@ RUN ARCH=$(uname -m) \
27
32
  # Set working directory
28
33
  WORKDIR /app
29
34
 
30
- # Copy project configuration files
35
+ # Copy only essential files for package installation
31
36
  COPY pyproject.toml .
32
- COPY pytest.ini .
33
- COPY .coveragerc .
34
- COPY Makefile .
35
37
  COPY policy.json .
36
38
 
37
- # Copy source code and tests
39
+ # Copy source code (minimal for installation)
38
40
  COPY src/ ./src/
39
- COPY tests/ ./tests/
40
- COPY awsquery.py .
41
41
 
42
- # Install the package with all dependencies (production + dev for testing)
42
+ # Install the package with all dependencies
43
+ # Note: This installs from the copied source, but in development
44
+ # the volume mount will override this with live code
43
45
  RUN pip install --no-cache-dir -e ".[dev]"
44
46
 
45
- # Make original awsquery.py executable for backward compatibility
46
- RUN chmod +x awsquery.py
47
+ # Copy additional configuration files needed for testing/CI
48
+ # These will be overridden by volume mounts in development
49
+ COPY pytest.ini .
50
+ COPY .coveragerc .
51
+ COPY Makefile .
47
52
 
48
- # Create symlinks for both access methods
49
- RUN ln -sf /app/awsquery.py /usr/local/bin/awsquery-legacy \
50
- && ln -sf /usr/local/bin/awsquery /usr/local/bin/awsquery-cli
53
+ # Configure bash autocomplete for awsquery
54
+ RUN echo '# Enable awsquery autocomplete' >> /root/.bashrc \
55
+ && echo 'eval "$(register-python-argcomplete awsquery)"' >> /root/.bashrc \
56
+ && echo 'echo "awsquery autocomplete enabled. Try: awsquery <TAB>"' >> /root/.bashrc
51
57
 
52
58
  # Set default command to bash for interactive use
53
59
  ENTRYPOINT ["/bin/bash"]
@@ -1,5 +1,9 @@
1
1
  FROM python:3.11-slim as production
2
2
 
3
+ # Production Dockerfile with minimal file copying
4
+ # Only includes essential files needed for production deployment
5
+ # Excludes all development, testing, and analysis files
6
+
3
7
  # Install system dependencies
4
8
  RUN apt-get update && apt-get install -y \
5
9
  curl \
@@ -29,20 +33,18 @@ WORKDIR /app
29
33
  COPY pyproject.toml .
30
34
  COPY policy.json .
31
35
  COPY src/ ./src/
32
- COPY awsquery.py .
33
36
 
34
37
  # Install only production dependencies
35
38
  RUN pip install --no-cache-dir .
36
39
 
37
- # Make original awsquery.py executable for backward compatibility
38
- RUN chmod +x awsquery.py
39
-
40
- # Create symlinks for access methods
41
- RUN ln -sf /app/awsquery.py /usr/local/bin/awsquery-legacy \
42
- && ln -sf /usr/local/bin/awsquery /usr/local/bin/awsquery-cli
43
-
44
40
  # Create non-root user for security
45
41
  RUN useradd -m -u 1000 awsquery
42
+
43
+ # Configure bash autocomplete for awsquery user
44
+ RUN echo '# Enable awsquery autocomplete' >> /home/awsquery/.bashrc \
45
+ && echo 'eval "$(register-python-argcomplete awsquery)"' >> /home/awsquery/.bashrc \
46
+ && chown awsquery:awsquery /home/awsquery/.bashrc
47
+
46
48
  USER awsquery
47
49
 
48
50
  # Set default command to the CLI tool
@@ -57,6 +57,22 @@ coverage: ## Run tests with coverage report
57
57
  coverage-report: coverage ## Generate and show coverage report location
58
58
  @echo "$(GREEN)Coverage report available at: htmlcov/index.html$(NC)"
59
59
 
60
+ mutmut: ## Run mutation testing on the codebase
61
+ @echo "$(BLUE)Running mutation testing with mutmut$(NC)"
62
+ mutmut run
63
+
64
+ mutmut-results: ## Show mutation testing results
65
+ @echo "$(BLUE)Mutation testing results:$(NC)"
66
+ mutmut results
67
+
68
+ mutmut-html: ## Generate HTML report for mutation testing
69
+ mutmut html
70
+ @echo "$(GREEN)Mutation testing report available at: html/index.html$(NC)"
71
+
72
+ mutmut-clean: ## Clean mutation testing cache
73
+ rm -f .mutmut-cache
74
+ @echo "$(GREEN)Mutation testing cache cleaned$(NC)"
75
+
60
76
  lint: ## Run linting checks
61
77
  flake8 src/ tests/ --count --statistics --show-source
62
78
  pylint src/awsquery
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: awsquery
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Advanced CLI tool for querying AWS APIs with flexible filtering and automatic parameter resolution
5
5
  Author-email: Florian Motlik <flo@flomotlik.me>
6
6
  License: MIT
@@ -54,6 +54,7 @@ Requires-Dist: interrogate>=1.5.0; extra == "dev"
54
54
  Requires-Dist: tox>=4.0.0; extra == "dev"
55
55
  Requires-Dist: twine>=4.0.0; extra == "dev"
56
56
  Requires-Dist: build>=0.10.0; extra == "dev"
57
+ Requires-Dist: mutmut>=2.4.0; extra == "dev"
57
58
  Provides-Extra: docs
58
59
  Requires-Dist: sphinx>=7.0.0; extra == "docs"
59
60
  Requires-Dist: sphinx-rtd-theme>=1.3.0; extra == "docs"
@@ -107,6 +108,52 @@ cd awsquery
107
108
  pip install -e ".[dev]"
108
109
  ```
109
110
 
111
+ ### Enable Shell Autocomplete
112
+
113
+ awsquery supports tab completion for AWS services and actions through argcomplete.
114
+
115
+ #### Quick Setup (Automatic)
116
+ ```bash
117
+ # Run the setup script
118
+ ./setup-autocomplete.sh
119
+
120
+ # Then reload your shell configuration
121
+ source ~/.bashrc # or ~/.zshrc, etc.
122
+ ```
123
+
124
+ #### Manual Setup
125
+
126
+ ##### Bash
127
+ ```bash
128
+ # Add to ~/.bashrc or ~/.bash_profile
129
+ eval "$(register-python-argcomplete awsquery)"
130
+ ```
131
+
132
+ ##### Zsh
133
+ ```bash
134
+ # Add to ~/.zshrc
135
+ autoload -U bashcompinit && bashcompinit
136
+ eval "$(register-python-argcomplete awsquery)"
137
+ ```
138
+
139
+ ##### Fish
140
+ ```bash
141
+ # Add to ~/.config/fish/config.fish
142
+ register-python-argcomplete --shell fish awsquery | source
143
+ ```
144
+
145
+ After adding the appropriate line to your shell configuration, restart your shell or source the file:
146
+ ```bash
147
+ source ~/.bashrc # or ~/.zshrc, etc.
148
+ ```
149
+
150
+ Now you can use tab completion:
151
+ ```bash
152
+ awsquery <TAB> # Shows available services
153
+ awsquery ec2 <TAB> # Shows available ec2 actions
154
+ awsquery s3 list-<TAB> # Shows s3 list actions
155
+ ```
156
+
110
157
  ## Usage
111
158
 
112
159
  ### Basic Query
@@ -328,40 +375,59 @@ make release # Create a new release with version bump
328
375
 
329
376
  ## Advanced Usage
330
377
 
331
- ### Partial Matching Behavior
378
+ ### Filter Matching Behavior
379
+
380
+ All filters in awsquery use **case-insensitive matching** with optional anchoring:
332
381
 
333
- All filters in awsquery use **case-insensitive partial matching**:
382
+ #### Filter Operators
383
+ - `^` at the start: matches values that START WITH the pattern (prefix match)
384
+ - Both `^` (U+005E) and `ˆ` (U+02C6) are supported for keyboard compatibility
385
+ - `$` at the end: matches values that END WITH the pattern (suffix match)
386
+ - `^...$`: matches values that EXACTLY equal the pattern (exact match)
387
+ - No operators: matches values that CONTAIN the pattern (partial match)
334
388
 
335
389
  #### Value Filters (before `--`)
336
390
  - Match against ANY field in the response data
337
391
  - ALL specified filters must match (AND logic)
338
- - Case-insensitive substring matching
392
+ - Case-insensitive matching with optional anchoring
339
393
 
340
394
  ```bash
341
- # "prod" matches: "production", "prod-server", "my-prod-app"
395
+ # "prod" matches: "production", "prod-server", "my-prod-app" (contains)
342
396
  awsquery ec2 describe-instances prod
343
397
 
344
- # Both "prod" AND "web" must appear (in any fields)
345
- awsquery ec2 describe-instances prod web
398
+ # "^prod" matches: "production", "prod-server" (starts with)
399
+ awsquery ec2 describe-instances ^prod
400
+
401
+ # "prod$" matches: "my-prod", "dev-prod" (ends with)
402
+ awsquery ec2 describe-instances prod$
346
403
 
347
- # "i-123" matches any instance ID starting with "i-123"
348
- awsquery ec2 describe-instances i-123
404
+ # "^prod$" matches: only exactly "prod" (exact match)
405
+ awsquery ec2 describe-instances ^prod$
406
+
407
+ # Both filters must match (AND logic)
408
+ awsquery ec2 describe-instances ^prod web$
349
409
  ```
350
410
 
351
411
  #### Column Filters (after `--`)
352
412
  - Match against column/field names in the output
353
- - Partial, case-insensitive matching on column names
413
+ - Case-insensitive matching with optional anchoring
354
414
  - Multiple columns can be specified
355
415
 
356
416
  ```bash
357
- # "Instance" matches: "InstanceId", "InstanceType", "InstanceName"
417
+ # "Instance" matches: "InstanceId", "InstanceType", "InstanceName" (contains)
358
418
  awsquery ec2 describe-instances -- Instance
359
419
 
360
- # Shows columns containing "Tag", "State", or "IP"
361
- awsquery ec2 describe-instances -- Tag State IP
420
+ # "^Instance" matches: "InstanceId", "InstanceType" (starts with)
421
+ awsquery ec2 describe-instances -- ^Instance
422
+
423
+ # "Name$" matches: "InstanceName", "GroupName", "Tags.Name" (ends with)
424
+ awsquery ec2 describe-instances -- Name$
425
+
426
+ # "^State.Name$" matches: only exactly "State.Name" (exact match)
427
+ awsquery ec2 describe-instances -- ^State.Name$
362
428
 
363
- # Nested field matching
364
- awsquery ec2 describe-instances -- State.Name Tags.Environment
429
+ # Multiple patterns
430
+ awsquery ec2 describe-instances -- ^Instance Name$ State
365
431
  ```
366
432
 
367
433
  ### Multi-Level API Calls
@@ -45,6 +45,52 @@ cd awsquery
45
45
  pip install -e ".[dev]"
46
46
  ```
47
47
 
48
+ ### Enable Shell Autocomplete
49
+
50
+ awsquery supports tab completion for AWS services and actions through argcomplete.
51
+
52
+ #### Quick Setup (Automatic)
53
+ ```bash
54
+ # Run the setup script
55
+ ./setup-autocomplete.sh
56
+
57
+ # Then reload your shell configuration
58
+ source ~/.bashrc # or ~/.zshrc, etc.
59
+ ```
60
+
61
+ #### Manual Setup
62
+
63
+ ##### Bash
64
+ ```bash
65
+ # Add to ~/.bashrc or ~/.bash_profile
66
+ eval "$(register-python-argcomplete awsquery)"
67
+ ```
68
+
69
+ ##### Zsh
70
+ ```bash
71
+ # Add to ~/.zshrc
72
+ autoload -U bashcompinit && bashcompinit
73
+ eval "$(register-python-argcomplete awsquery)"
74
+ ```
75
+
76
+ ##### Fish
77
+ ```bash
78
+ # Add to ~/.config/fish/config.fish
79
+ register-python-argcomplete --shell fish awsquery | source
80
+ ```
81
+
82
+ After adding the appropriate line to your shell configuration, restart your shell or source the file:
83
+ ```bash
84
+ source ~/.bashrc # or ~/.zshrc, etc.
85
+ ```
86
+
87
+ Now you can use tab completion:
88
+ ```bash
89
+ awsquery <TAB> # Shows available services
90
+ awsquery ec2 <TAB> # Shows available ec2 actions
91
+ awsquery s3 list-<TAB> # Shows s3 list actions
92
+ ```
93
+
48
94
  ## Usage
49
95
 
50
96
  ### Basic Query
@@ -266,40 +312,59 @@ make release # Create a new release with version bump
266
312
 
267
313
  ## Advanced Usage
268
314
 
269
- ### Partial Matching Behavior
315
+ ### Filter Matching Behavior
316
+
317
+ All filters in awsquery use **case-insensitive matching** with optional anchoring:
270
318
 
271
- All filters in awsquery use **case-insensitive partial matching**:
319
+ #### Filter Operators
320
+ - `^` at the start: matches values that START WITH the pattern (prefix match)
321
+ - Both `^` (U+005E) and `ˆ` (U+02C6) are supported for keyboard compatibility
322
+ - `$` at the end: matches values that END WITH the pattern (suffix match)
323
+ - `^...$`: matches values that EXACTLY equal the pattern (exact match)
324
+ - No operators: matches values that CONTAIN the pattern (partial match)
272
325
 
273
326
  #### Value Filters (before `--`)
274
327
  - Match against ANY field in the response data
275
328
  - ALL specified filters must match (AND logic)
276
- - Case-insensitive substring matching
329
+ - Case-insensitive matching with optional anchoring
277
330
 
278
331
  ```bash
279
- # "prod" matches: "production", "prod-server", "my-prod-app"
332
+ # "prod" matches: "production", "prod-server", "my-prod-app" (contains)
280
333
  awsquery ec2 describe-instances prod
281
334
 
282
- # Both "prod" AND "web" must appear (in any fields)
283
- awsquery ec2 describe-instances prod web
335
+ # "^prod" matches: "production", "prod-server" (starts with)
336
+ awsquery ec2 describe-instances ^prod
337
+
338
+ # "prod$" matches: "my-prod", "dev-prod" (ends with)
339
+ awsquery ec2 describe-instances prod$
284
340
 
285
- # "i-123" matches any instance ID starting with "i-123"
286
- awsquery ec2 describe-instances i-123
341
+ # "^prod$" matches: only exactly "prod" (exact match)
342
+ awsquery ec2 describe-instances ^prod$
343
+
344
+ # Both filters must match (AND logic)
345
+ awsquery ec2 describe-instances ^prod web$
287
346
  ```
288
347
 
289
348
  #### Column Filters (after `--`)
290
349
  - Match against column/field names in the output
291
- - Partial, case-insensitive matching on column names
350
+ - Case-insensitive matching with optional anchoring
292
351
  - Multiple columns can be specified
293
352
 
294
353
  ```bash
295
- # "Instance" matches: "InstanceId", "InstanceType", "InstanceName"
354
+ # "Instance" matches: "InstanceId", "InstanceType", "InstanceName" (contains)
296
355
  awsquery ec2 describe-instances -- Instance
297
356
 
298
- # Shows columns containing "Tag", "State", or "IP"
299
- awsquery ec2 describe-instances -- Tag State IP
357
+ # "^Instance" matches: "InstanceId", "InstanceType" (starts with)
358
+ awsquery ec2 describe-instances -- ^Instance
359
+
360
+ # "Name$" matches: "InstanceName", "GroupName", "Tags.Name" (ends with)
361
+ awsquery ec2 describe-instances -- Name$
362
+
363
+ # "^State.Name$" matches: only exactly "State.Name" (exact match)
364
+ awsquery ec2 describe-instances -- ^State.Name$
300
365
 
301
- # Nested field matching
302
- awsquery ec2 describe-instances -- State.Name Tags.Environment
366
+ # Multiple patterns
367
+ awsquery ec2 describe-instances -- ^Instance Name$ State
303
368
  ```
304
369
 
305
370
  ### Multi-Level API Calls
@@ -11,8 +11,6 @@ services:
11
11
  - ~/.aws:/root/.aws:ro
12
12
  # Mount current directory for development
13
13
  - .:/app
14
- # Mount sample responses directory
15
- - ./sample-responses:/app/sample-responses
16
14
  environment:
17
15
  # Set default AWS region if not specified
18
16
  - AWS_REGION=${AWS_REGION:-eu-central-1}
@@ -26,24 +24,6 @@ services:
26
24
  tty: true
27
25
  working_dir: /app
28
26
 
29
- # Production environment with minimal dependencies
30
- awsquery-prod:
31
- build:
32
- context: .
33
- dockerfile: Dockerfile.prod
34
- volumes:
35
- # Mount AWS credentials (read-only for security)
36
- - ~/.aws:/home/awsquery/.aws:ro
37
- environment:
38
- # Set default AWS region if not specified
39
- - AWS_REGION=${AWS_REGION:-eu-central-1}
40
- - AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION:-eu-central-1}
41
- # Preserve other AWS environment variables
42
- - AWS_PROFILE=${AWS_PROFILE:-}
43
- - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-}
44
- - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-}
45
- - AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN:-}
46
-
47
27
  # Legacy service name for backward compatibility
48
28
  awsquery:
49
29
  extends: awsquery-dev
@@ -0,0 +1,75 @@
1
+ # Mutation Testing with Mutmut
2
+
3
+ This project uses `mutmut` for mutation testing to verify test suite quality.
4
+
5
+ ## Installation
6
+
7
+ Mutmut is included in development dependencies:
8
+
9
+ ```bash
10
+ pip install -e ".[dev]"
11
+ ```
12
+
13
+ ## Configuration
14
+
15
+ Mutation testing is configured in `pyproject.toml`:
16
+
17
+ ```toml
18
+ [tool.mutmut]
19
+ paths_to_mutate = ["src/awsquery/"]
20
+ runner = "python -m pytest -x -q"
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ### Run Mutation Testing
26
+
27
+ ```bash
28
+ # Run complete mutation testing
29
+ make mutmut
30
+
31
+ # Or directly
32
+ mutmut run
33
+ ```
34
+
35
+ ### View Results
36
+
37
+ ```bash
38
+ # Show summary of results
39
+ make mutmut-results
40
+
41
+ # Generate HTML report
42
+ make mutmut-html
43
+
44
+ # Clean mutation cache
45
+ make mutmut-clean
46
+ ```
47
+
48
+ ## Interpreting Results
49
+
50
+ Mutmut creates mutations in your code and runs tests to see if they detect the changes:
51
+
52
+ - **Killed**: Test suite detected the mutation (good)
53
+ - **Survived**: Test suite didn't detect the mutation (indicates missing test coverage)
54
+ - **Timeout**: Mutation caused infinite loop or significant slowdown
55
+ - **Suspicious**: Test behavior inconsistent
56
+
57
+ ## Best Practices
58
+
59
+ 1. Focus on critical code paths first
60
+ 2. Run on specific modules during development
61
+ 3. Use mutation testing to identify weak test areas
62
+ 4. Not all survived mutations need fixing - use judgment
63
+
64
+ ## Example: Testing Specific Module
65
+
66
+ ```bash
67
+ # Test only the filters module
68
+ mutmut run src/awsquery/filters.py
69
+ ```
70
+
71
+ ## Performance Tips
72
+
73
+ - Use `--max-children` to limit parallel processes
74
+ - Run on subsets of code during development
75
+ - Full runs can be done in CI or before releases