Code Style
General Principles
-
Readability: Code should be easy to understand
-
Simplicity: Avoid unnecessary complexity
-
Consistency: Follow existing patterns
-
MECE: Mutually Exclusive, Collectively Exhaustive
Ruby Style
Excavate follows standard Ruby conventions with Rubocop enforcement.
Object-Oriented Design
Error Handling
Documentation
Public Methods
Document public methods:
# Extract archive to target directory
#
# @param target [String, nil] Target directory path
# @param recursive_packages [Boolean] Extract nested archives
# @param files [Array<String>] Specific files to extract
# @param filter [String, nil] Glob pattern for filtering
# @return [String, Array<String>] Target path or extracted file paths
# @raise [TargetExistsError] If target already exists
# @raise [UnknownArchiveError] If format not recognized
def extract(target = nil, recursive_packages: false, files: [], filter: nil)
endComplex Logic
Add comments for complex logic:
def extract_recursive(target)
# Find all extracted files that might be archives
potential_archives = Dir.glob("#{target}/**/*").select do |file|
File.file?(file) && archive_extension?(file)
end
# Extract each nested archive
potential_archives.each do |archive|
# ...
end
endTesting
Descriptive Names
Use descriptive test names:
# Good
it 'extracts ZIP archive to target directory'
# Bad
it 'works'One Assertion per Test
# Good
it 'creates target directory' do
extractor.extract(target)
expect(Dir.exist?(target)).to be true
end
it 'extracts all files' do
extractor.extract(target)
expect(Dir.glob("#{target}/*").size).to eq(3)
end
# Bad
it 'extracts correctly' do
extractor.extract(target)
expect(Dir.exist?(target)).to be true
expect(Dir.glob("#{target}/*").size).to eq(3)
endRunning Rubocop
# Check all files
bundle exec rubocop
# Auto-fix issues
bundle exec rubocop -A
# Generate config for remaining issues
bundle exec rubocop --auto-gen-config