Skip to main content

Welcome Contributors

Thank you for your interest in contributing to List! This guide will help you get started with development and explain our contribution process.
List is an open-source project that welcomes contributions from developers of all skill levels. Whether you’re fixing a bug, adding a feature, or improving documentation, your help is appreciated!

Getting Started

1

Fork and Clone

Fork the repository on GitHub and clone your fork:
git clone https://github.com/YOUR_USERNAME/list.git
cd list
2

Set Up Development Environment

Ensure you have the required tools:
  • Swift 6.2 or later
  • macOS 13+ (for macOS development) or Linux
  • Git
Verify your Swift installation:
swift --version
# Should output Swift version 6.2 or later
3

Build the Project

Build List to ensure everything works:
swift build
Run the built executable:
.build/debug/sls
4

Run Tests

Verify that all tests pass:
swift test
All tests should pass before you start making changes.

Development Workflow

Creating a Feature Branch

Always create a new branch for your changes:
# Create and switch to a new branch
git checkout -b feature/your-feature-name

# Or for bug fixes
git checkout -b fix/issue-description
Use descriptive branch names that explain what you’re working on, such as feature/add-json-output or fix/symlink-handling.

Making Changes

1

Code Your Changes

Make your changes following the project structure:
  • CLI changes: Edit files in Sources/SwiftListCLI/
  • Core logic: Edit files in Sources/SwiftListCore/
  • Tests: Edit or add to Tests/SwiftListTests.swift
2

Format Your Code

The project uses .swift-format for consistent code style. Format your changes:
swift-format format -i -r Sources/ Tests/
All code must follow the project’s formatting rules defined in .swift-format. CI will fail if code is not properly formatted.
3

Add or Update Tests

Add tests for your changes in Tests/SwiftListTests.swift:
import Testing
import SwiftListCore
import SwiftListCLI

@Test
func testYourFeature() {
    // Your test code here
}
Run tests to ensure they pass:
swift test
4

Build and Test

Verify everything still works:
# Clean build
swift package clean
swift build

# Run all tests
swift test

# Test manually
.build/debug/sls --long --color

Code Style Guidelines

Swift Formatting Rules

The project uses .swift-format configuration with these key settings:
  • Indentation: 4 spaces (not tabs)
  • Line length: 180 characters maximum
  • File-scoped declarations: Use private access level
  • Documentation: Required for public APIs

Code Organization

Follow the existing module structure:
Sources/
├── SwiftList/           # Executable entry point
│   └── main.swift       # Minimal bootstrap code
├── SwiftListCLI/        # Command-line interface
│   └── ListCommand.swift
└── SwiftListCore/       # Core business logic
    ├── Configuration/   # Options and settings
    ├── Models/         # Data models
    └── Utilities/      # Helper classes

Do

  • Follow existing patterns
  • Add documentation comments
  • Write tests for new features
  • Use meaningful variable names
  • Keep functions focused and small

Don't

  • Mix CLI and core logic
  • Use force unwrapping (!)
  • Skip error handling
  • Ignore compiler warnings
  • Submit unformatted code

Documentation Comments

Add documentation for public APIs:
/// Brief one-line summary of the function.
///
/// Detailed description explaining what the function does,
/// its parameters, and any important behavior.
///
/// ## Example
///
/// ```swift
/// let result = myFunction(value: 42)
/// ```
///
/// - Parameter value: Description of the parameter
/// - Returns: Description of what is returned
/// - Throws: Description of errors that can be thrown
public func myFunction(value: Int) throws -> String {
    // Implementation
}

Testing Strategy

Writing Tests

List uses the modern Swift Testing framework (0.11.0+):
import Testing
import SwiftListCore

@Test
func testSortingByName() {
    let options = DisplayOptions(sortBy: .name)
    // Test implementation
}

What to Test

  • File listing with different options
  • Sorting (by name, size, time)
  • Filtering (hidden files, etc.)
  • File type detection
  • Symbolic link handling
  • Recursive directory traversal
  • Empty directories
  • Permission denied scenarios
  • Broken symbolic links
  • Very long file names
  • Special characters in file names
  • Depth limit in recursive mode
  • Long format output
  • Color codes applied correctly
  • Icon display
  • Terminal width wrapping
  • Human-readable sizes

Running Tests

# Run all tests
swift test

# Run with verbose output
swift test --verbose

# Run in parallel (default)
swift test --parallel

Adding New Features

Feature Development Checklist

When adding a new feature:
  • Create a feature branch
  • Design the feature (consider architecture impact)
  • Update DisplayOptions if needed (new configuration)
  • Add CLI flags to ListCommand if needed
  • Implement core logic in SwiftListCore
  • Write comprehensive tests
  • Update documentation comments
  • Format code with swift-format
  • Run full test suite
  • Test manually with various scenarios
  • Update README if user-facing
  • Submit pull request

Example: Adding a New Sort Option

1

Update SortOption Enum

Add the new option to Sources/SwiftListCore/Configuration/SortOption.swift:
public enum SortOption: String, ExpressibleByArgument {
    case name
    case time
    case size
    case extension  // New option
}
2

Add CLI Flag

Add the flag to Sources/SwiftListCLI/ListCommand.swift:
@Flag(name: [.customShort("X"), .long], 
      help: "Sort by file extension.")
var sortExtension = false
Update the run() method to handle it.
3

Implement Sorting Logic

Update FileManagerHelper.contents() in Sources/SwiftListCore/Utilities/FileManagerHelper.swift:
case .extension:
    return url1.pathExtension.localizedCompare(url2.pathExtension) 
        == .orderedAscending
4

Add Tests

Test the new sort option in Tests/SwiftListTests.swift:
@Test
func testSortByExtension() {
    let options = DisplayOptions(sortBy: .extension)
    // Verify sorting works correctly
}

Continuous Integration

The project uses GitHub Actions for CI/CD: Location: .github/workflows/release.yml

CI Pipeline

The CI pipeline automatically:
  1. Builds the project on multiple platforms:
    • macOS (x86_64 and arm64)
    • Linux (x86_64 and arm64)
  2. Runs tests on all platforms
  3. Creates releases when tags are pushed:
    • Builds release binaries
    • Uploads artifacts to GitHub Releases
All pull requests must pass CI checks before they can be merged. This ensures code quality and prevents breaking changes.

Build Matrix

Builds are tested on:
  • macOS 14 with Swift 6.2 (x86_64 and arm64)
  • Ubuntu 22.04 with Swift 6.2 (x86_64 and arm64)

Submitting Changes

Pull Request Process

1

Commit Your Changes

Make meaningful commits:
git add .
git commit -m "Add feature: sort by file extension"
Use clear, descriptive commit messages that explain what and why.
2

Push to Your Fork

Push your branch to GitHub:
git push origin feature/your-feature-name
3

Create Pull Request

Go to the List repository and create a pull request:
  • Describe what your changes do
  • Reference any related issues
  • Explain your approach if complex
  • Include screenshots for UI changes
4

Address Review Feedback

Respond to code review comments:
  • Make requested changes
  • Push updates to your branch
  • Reply to comments
  • Mark conversations as resolved

Pull Request Template

## Description
Brief description of changes

## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update

## Testing
- [ ] Tests pass locally
- [ ] Added new tests
- [ ] Tested manually

## Checklist
- [ ] Code follows style guidelines
- [ ] Code is formatted with swift-format
- [ ] Documentation updated
- [ ] No new warnings

Reporting Issues

Found a bug or have a feature request?

Report Bug

Create a bug report with details and reproduction steps

Request Feature

Suggest a new feature or enhancement

Bug Report Template

Include the following information:
  • Description: Clear description of the bug
  • Steps to reproduce: Exact commands to trigger the bug
  • Expected behavior: What should happen
  • Actual behavior: What actually happens
  • Environment:
    • OS: (e.g., macOS 14.2, Ubuntu 22.04)
    • Swift version: (output of swift --version)
    • List version: (output of sls --version)
  • Additional context: Screenshots, logs, etc.

Community Guidelines

Code of Conduct

  • Be respectful and inclusive
  • Welcome newcomers and help them learn
  • Provide constructive feedback
  • Focus on what is best for the project
  • Accept constructive criticism gracefully

Communication

  • Issues: Bug reports and feature requests
  • Pull Requests: Code contributions
  • Discussions: General questions and ideas

Resources

GitHub Repository

View source code and open issues

Swift Documentation

Learn more about Swift

ArgumentParser

CLI framework documentation

Swift Testing

Testing framework guide

Advanced Topics

Platform-Specific Code

When adding platform-specific features:
#if canImport(Darwin)
import Darwin
// macOS-specific code
#elseif canImport(Glibc)
import Glibc
// Linux-specific code
#endif

Performance Considerations

  • Use efficient file system APIs
  • Avoid unnecessary file attribute queries
  • Consider memory usage for large directories
  • Profile performance for recursive operations

Security

  • Never follow symbolic links without permission
  • Handle permission errors gracefully
  • Validate file paths
  • Be careful with user-provided input

Next Steps

Ready to contribute?
  1. Pick an issue from the GitHub issues page
  2. Comment on the issue to let others know you’re working on it
  3. Follow this guide to implement your changes
  4. Submit a pull request when ready
Start with issues labeled “good first issue” if you’re new to the project!
Thank you for contributing to List!

Build docs developers (and LLMs) love