Thank you for considering contributing to envdiff! This document provides guidelines and instructions for contributing.
-
Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/env-diff-cli.git cd env-diff-cli -
Install dependencies
npm install
-
Build the project
npm run build
-
Run tests
npm test
src/
cli.ts # Commander setup, command registration
commands/
diff.ts # diff two env sources
check.ts # validate against a baseline
audit.ts # suspicious value detection
parsers/
dotenv.ts # .env and .env.example
compose.ts # docker-compose.yml environment blocks
vercel.ts # vercel.json + .vercel/output
railway.ts # railway.toml
core/
differ.ts # diff logic, set operations on variable maps
auditor.ts # suspicious value rules
reporter.ts # format output (text | json | markdown)
types.ts # shared types
__tests__/ # unit tests
fixtures/ # test data
- TypeScript strict mode - All code must pass strict type checking
- Functional style - Prefer pure functions over classes
- Named exports only - No default exports
- Async/await - Use async functions for all I/O operations
- No
anytype - Useunknownand narrow explicitly - ESLint + Prettier - Code must pass linting and formatting checks
Run formatting and linting:
npm run format
npm run lintTo add support for a new configuration format:
- Create a new parser in
src/parsers/yourformat.ts - Implement the parser function that returns
Promise<EnvMap> - Add test fixtures in
src/__tests__/fixtures/ - Write unit tests in
src/__tests__/yourformat.test.ts - Update the
loadSourcefunction insrc/commands/diff.ts - Update README.md and EXAMPLES.md with usage examples
Example parser structure:
import { readFile } from 'fs/promises'
import type { EnvMap } from '../types.js'
import { ParseError } from '../types.js'
export async function parseYourFormat(filePath: string): Promise<EnvMap> {
try {
const content = await readFile(filePath, 'utf-8')
// Parse content and return EnvMap
return {}
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
return {}
}
throw new ParseError(`Failed to parse: ${filePath}`)
}
}To add a new security audit rule:
- Add the rule to the
rulesarray insrc/core/auditor.ts - Write tests in
src/__tests__/auditor.test.ts(positive and negative cases) - Update README.md with the new rule description
Example rule:
{
id: 'YOUR_RULE_ID',
severity: 'warn' | 'error',
match: (key: string, value: string) => {
// Return true if the rule should trigger
return false
}
}# Run all tests
npm test
# Run tests once (no watch mode)
npm run test:run
# Run with coverage
npm run test:coverage- Place tests in
src/__tests__/ - Use descriptive test names
- Test both positive and negative cases
- Use fixtures in
src/__tests__/fixtures/for test data - Avoid mocking the filesystem - use real files in temp directories
Example test:
import { describe, it, expect } from 'vitest'
import { yourFunction } from '../your-module.js'
describe('yourFunction', () => {
it('should handle valid input', () => {
const result = yourFunction('input')
expect(result).toBe('expected')
})
it('should throw on invalid input', () => {
expect(() => yourFunction('')).toThrow()
})
})-
Create a feature branch
git checkout -b feature/your-feature-name
-
Make your changes
- Write clean, well-documented code
- Add tests for new functionality
- Update documentation as needed
-
Test your changes
npm run lint npm run format:check npm run test:run npm run build
-
Commit your changes
git add . git commit -m "feat: add your feature description"
-
Push to your fork
git push origin feature/your-feature-name
-
Create a Pull Request
- Provide a clear description of the changes
- Link to any related issues
- Ensure all CI checks pass
Follow conventional commits:
feat:- New featurefix:- Bug fixdocs:- Documentation changestest:- Adding or updating testsrefactor:- Code refactoringperf:- Performance improvementschore:- Maintenance tasks
Examples:
feat: add support for Kubernetes ConfigMaps
fix: handle empty environment files correctly
docs: update installation instructions
test: add tests for audit rules
- Open an issue for bugs or feature requests
- Start a discussion for questions or ideas
- Check existing issues before creating new ones
By contributing, you agree that your contributions will be licensed under the MIT License.