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.
- {awsquery-0.1.0 → awsquery-0.2.0}/.claude/settings.local.json +3 -1
- awsquery-0.2.0/.dockerignore +52 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/.gitignore +6 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/CLAUDE.md +76 -1
- {awsquery-0.1.0 → awsquery-0.2.0}/Dockerfile +19 -13
- {awsquery-0.1.0 → awsquery-0.2.0}/Dockerfile.prod +10 -8
- {awsquery-0.1.0 → awsquery-0.2.0}/Makefile +16 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/PKG-INFO +81 -15
- {awsquery-0.1.0 → awsquery-0.2.0}/README.md +79 -14
- {awsquery-0.1.0 → awsquery-0.2.0}/docker-compose.yml +0 -20
- awsquery-0.2.0/docs/mutation-testing.md +75 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/pyproject.toml +8 -2
- awsquery-0.2.0/pytest.ini +13 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/cli.py +243 -63
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/config.py +17 -9
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/core.py +106 -63
- awsquery-0.2.0/src/awsquery/default_filters.yaml +2707 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/filters.py +102 -24
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/formatters.py +137 -66
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/security.py +25 -12
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/utils.py +8 -5
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/PKG-INFO +81 -15
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/SOURCES.txt +18 -4
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/requires.txt +1 -0
- awsquery-0.2.0/tests/__init__.py +1 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/conftest.py +7 -7
- awsquery-0.2.0/tests/integration/test_autocomplete_resilience.py +141 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/test_end_to_end.py +40 -49
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/test_feature_combinations.py +57 -54
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/test_keys_behavior.py +41 -45
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/test_multi_level.py +91 -110
- awsquery-0.2.0/tests/integration/test_multi_level_calls.py +368 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/test_session_management.py +20 -26
- awsquery-0.2.0/tests/unit/test_cli_arg_processing.py +418 -0
- awsquery-0.2.0/tests/unit/test_cli_flags.py +299 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_cli_parser.py +143 -49
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_cli_session_args.py +28 -34
- awsquery-0.2.0/tests/unit/test_column_ordering.py +212 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_config_loading.py +4 -5
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_core.py +62 -71
- awsquery-0.2.0/tests/unit/test_core_inference.py +172 -0
- awsquery-0.2.0/tests/unit/test_core_string_handling.py +193 -0
- awsquery-0.2.0/tests/unit/test_critical_mutations.py +216 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_default_column_filters.py +51 -49
- awsquery-0.2.0/tests/unit/test_filter_edge_cases.py +258 -0
- awsquery-0.2.0/tests/unit/test_filter_implementation.py +309 -0
- awsquery-0.2.0/tests/unit/test_filter_matching.py +280 -0
- awsquery-0.2.0/tests/unit/test_filter_parameter_extraction.py +212 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_filters.py +3 -6
- awsquery-0.2.0/tests/unit/test_filters_pattern_matching.py +282 -0
- awsquery-0.2.0/tests/unit/test_formatter_edge_cases.py +325 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_formatters.py +5 -14
- awsquery-0.2.0/tests/unit/test_formatters_data_processing.py +355 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_keys_display_fix.py +51 -57
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_messaging_enhancements.py +58 -64
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_security.py +16 -64
- awsquery-0.2.0/tests/unit/test_security_edge_cases.py +190 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/unit/test_tags_transformation.py +6 -11
- awsquery-0.1.0/.dockerignore +0 -27
- awsquery-0.1.0/awsquery.py +0 -21
- awsquery-0.1.0/pytest.ini +0 -21
- awsquery-0.1.0/src/awsquery/default_filters.yaml +0 -76
- awsquery-0.1.0/tests/unit/test_flag_positioning.py +0 -245
- awsquery-0.1.0/tests/unit/test_flags_after_separator.py +0 -266
- awsquery-0.1.0/tests/unit/test_parser_regression.py +0 -202
- {awsquery-0.1.0 → awsquery-0.2.0}/.claude/agents/code-reviewer.md +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/.claude/agents/makefile-optimizer.md +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/.claude/agents/python-infra-automator.md +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/.claude/agents/test-writer.md +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/.coveragerc +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/.devcontainer/devcontainer.json +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/.flake8 +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/.github/workflows/quality.yml +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/.github/workflows/release.yml +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/.github/workflows/test.yml +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/LICENSE +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/Todo.md +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/docs/DOCKER.md +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/policy.json +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/requirements.txt +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/setup.cfg +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/__init__.py +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery/policy.json +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/dependency_links.txt +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/entry_points.txt +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/src/awsquery.egg-info/top_level.txt +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/fixtures/__init__.py +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/fixtures/aws_responses.py +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/fixtures/policy_samples.py +0 -0
- {awsquery-0.1.0 → awsquery-0.2.0}/tests/integration/__init__.py +0 -0
- {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
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
-
#
|
|
46
|
-
|
|
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
|
-
#
|
|
49
|
-
RUN
|
|
50
|
-
&&
|
|
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.
|
|
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
|
-
###
|
|
378
|
+
### Filter Matching Behavior
|
|
379
|
+
|
|
380
|
+
All filters in awsquery use **case-insensitive matching** with optional anchoring:
|
|
332
381
|
|
|
333
|
-
|
|
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
|
|
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
|
-
#
|
|
345
|
-
awsquery ec2 describe-instances prod
|
|
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
|
-
# "
|
|
348
|
-
awsquery ec2 describe-instances
|
|
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
|
-
-
|
|
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
|
-
#
|
|
361
|
-
awsquery ec2 describe-instances --
|
|
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
|
-
#
|
|
364
|
-
awsquery ec2 describe-instances --
|
|
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
|
-
###
|
|
315
|
+
### Filter Matching Behavior
|
|
316
|
+
|
|
317
|
+
All filters in awsquery use **case-insensitive matching** with optional anchoring:
|
|
270
318
|
|
|
271
|
-
|
|
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
|
|
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
|
-
#
|
|
283
|
-
awsquery ec2 describe-instances prod
|
|
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
|
-
# "
|
|
286
|
-
awsquery ec2 describe-instances
|
|
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
|
-
-
|
|
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
|
-
#
|
|
299
|
-
awsquery ec2 describe-instances --
|
|
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
|
-
#
|
|
302
|
-
awsquery ec2 describe-instances --
|
|
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
|