Skip to content

feat: Clean CFGPP implementation - production ready configuration parser #46

feat: Clean CFGPP implementation - production ready configuration parser

feat: Clean CFGPP implementation - production ready configuration parser #46

Workflow file for this run

name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.9', '3.10', '3.11']
exclude:
# Reduce matrix size for faster CI
- os: macos-latest
python-version: '3.9'
- os: windows-latest
python-version: '3.9'
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip dependencies
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml', '**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
cd implementations/python
pip install -e .
pip install pytest pytest-cov pytest-xdist
- name: Run tests
run: |
cd implementations/python
pytest --cov=src/cfgpp --cov-report=xml --cov-report=term-missing -v
- name: Upload coverage to Codecov
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.9'
uses: codecov/codecov-action@v3
with:
file: ./implementations/python/coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
cd implementations/python
pip install -e .[dev]
- name: Check code formatting with Black
run: |
cd implementations/python
black --check --diff src/ tests/
- name: Lint with flake8
run: |
cd implementations/python
flake8 src/ tests/ --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 src/ tests/ --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics
- name: Type check with mypy
run: |
cd implementations/python
mypy src/ --ignore-missing-imports
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install bandit safety
cd implementations/python
pip install -e .
- name: Run security checks with bandit
run: |
cd implementations/python
bandit -r src/ -f json -o bandit-report.json || true
bandit -r src/
- name: Check dependencies with safety
run: |
safety check
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
cd implementations/python
pip install -e .
- name: Validate documentation links
run: |
# Check that all documentation files exist and are properly linked
python -c "
import os
docs_dir = 'docs'
required_docs = [
'README.md', 'getting-started.md', 'language-specification.md',
'api-reference.md', 'error-handling.md', 'contributing.md'
]
for doc in required_docs:
path = os.path.join(docs_dir, doc)
if not os.path.exists(path):
print(f'Missing documentation: {path}')
exit(1)
print(f'✓ {doc}')
print('All documentation files exist')
"
- name: Test example configurations
run: |
cd implementations/python
python -c "
from cfgpp import load
import os
# Test the example configuration file
example_path = '../../specification/examples/complex_config.cfgpp'
if os.path.exists(example_path):
try:
config = load(example_path)
print('✓ Example configuration parses successfully')
except Exception as e:
print(f'✗ Example configuration failed to parse: {e}')
exit(1)
else:
print('No example configuration found - skipping')
"
integration:
runs-on: ubuntu-latest
needs: [test, lint]
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
cd implementations/python
pip install -e .
- name: Run integration tests
run: |
python -c "
# Integration test: Parse a complex configuration
from cfgpp import parse_string, parse_file, loads, load
from cfgpp.core.parser import ConfigParseError
from cfgpp.core.lexer import LexerError
import tempfile
import os
# Test 1: Basic parsing functionality
config_text = '''
AppConfig {
name = \"TestApp\"
port = 8080
debug = true
database = Database::PostgreSQL(
string host = \"localhost\",
int port = 5432
)
features = [\"auth\", \"logging\", \"metrics\"]
}
'''
try:
# Test new clear API
result = parse_string(config_text)
assert 'body' in result
assert 'AppConfig' in result['body']
print('✓ Complex configuration parsing (new API)')
# Test backward compatibility
result_legacy = loads(config_text)
assert result == result_legacy
print('✓ Backward compatibility verified')
except Exception as e:
print(f'✗ Complex configuration parsing failed: {e}')
exit(1)
# Test 2: File parsing
with tempfile.NamedTemporaryFile(mode='w', suffix='.cfgpp', delete=False) as f:
f.write(config_text)
temp_file = f.name
try:
# Test new clear API
result = parse_file(temp_file)
assert 'body' in result
print('✓ File parsing (new API)')
# Test backward compatibility
result_legacy = load(temp_file)
assert result == result_legacy
print('✓ File parsing backward compatibility')
except Exception as e:
print(f'✗ File parsing failed: {e}')
exit(1)
finally:
os.unlink(temp_file)
# Test 3: Error handling
try:
parse_string('Invalid { syntax')
print('✗ Error handling test failed - should have raised exception')
exit(1)
except (ConfigParseError, LexerError):
print('✓ Error handling')
except Exception as e:
print(f'✗ Unexpected error type: {e}')
exit(1)
print('All integration tests passed!')
"
build:
runs-on: ubuntu-latest
needs: [test, lint, security, docs, integration]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine
cd implementations/python
pip install -e .
- name: Build package
run: |
cd implementations/python
python -m build
- name: Check package
run: |
cd implementations/python
twine check dist/*
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: implementations/python/dist/