|
1 | 1 | # SwiftGit |
2 | 2 |
|
3 | | -A description of this package. |
| 3 | +SwiftGit is a Swift Package that wraps and orchestrates Git command-line functionality |
| 4 | +so you can drive Git operations programmatically from Swift. It includes a small |
| 5 | +shell abstraction, typed models for common git results, command builders for many |
| 6 | +git subcommands, and an embedded portable git distribution for environments that |
| 7 | +don't provide `git` on PATH. |
| 8 | + |
| 9 | +This README gives a focused code-oriented overview of the implementation in |
| 10 | +`Sources/` and practical instructions for building, testing, and contributing. |
| 11 | + |
| 12 | +Key features |
| 13 | +- Thin, testable wrappers around `git` commands (clone, commit, push, tag, stash, etc.) |
| 14 | +- Centralized process execution utilities in `Shell` supporting Combine and async/await |
| 15 | +- Typed models for common git outputs (`GitStatus`, `Commit`, `ShowCommitResult`) |
| 16 | +- Embedded portable git at `Sources/SwiftGit/Resource/git-instance.bundle` for hermetic runs |
| 17 | +- Extensive unit and integration tests that exercise parsing and real git workflows |
| 18 | + |
| 19 | +Table of contents |
| 20 | +- Project layout |
| 21 | +- Build & test |
| 22 | +- Important modules (quick code map) |
| 23 | +- Embedded git bundle |
| 24 | +- Tests and integration tests |
| 25 | +- Contribution notes |
| 26 | + - Contribution notes |
| 27 | + - See `CONTRIBUTING.md` for contribution workflow, pre-commit hook instructions, and lint/format guidance. |
| 28 | + |
| 29 | +Project layout (sources) |
| 30 | +- `Sources/SwiftGit/` — main package sources |
| 31 | + - `Custom/` — hand-written implementation |
| 32 | + - `commands/` — high-level command helpers, e.g. `git-commands-clone.swift`, `git-commands-tag.swift` |
| 33 | + - `models/` — typed models like `GitStatus.swift`, `Commit.swift`, `Reference.swift` |
| 34 | + - `results/` — parsing results and helpers (e.g. `ShowCommitResult.swift`) |
| 35 | + - `Shell.swift` — centralized Process wrapper with Combine + async/await support |
| 36 | + - `GitEnvironment.swift` — locate and configure embedded or system git |
| 37 | + - `Git.swift` — top-level `Git` class, wiring environment, shell, and triggers |
| 38 | + - `Repository.swift` (+ extensions) — repository-level helpers |
| 39 | + - `Resource/git-instance.bundle/` — portable git binaries and extras included in the package |
| 40 | + - `options/` — typed option values used to compose command arguments |
| 41 | + |
| 42 | +Build & test |
| 43 | +- Build the package (debug): |
| 44 | + |
| 45 | +```bash |
| 46 | +swift build |
| 47 | +``` |
| 48 | + |
| 49 | +- Build for release: |
| 50 | + |
| 51 | +```bash |
| 52 | +swift build -c release |
| 53 | +``` |
| 54 | + |
| 55 | +- Run the full test suite: |
| 56 | + |
| 57 | +```bash |
| 58 | +swift test |
| 59 | +``` |
| 60 | + |
| 61 | +- Run a single test by name (recommended): |
| 62 | + |
| 63 | +```bash |
| 64 | +# filter matches test case and/or function name |
| 65 | +swift test --filter ParseTests.testChangedEntryIndex_valid |
| 66 | +swift test --filter test_format_date |
| 67 | +``` |
| 68 | + |
| 69 | +- Run tests in parallel (CI friendly): |
| 70 | + |
| 71 | +```bash |
| 72 | +swift test --parallel |
| 73 | +``` |
| 74 | + |
| 75 | +Important modules (quick code map) |
| 76 | +- `Shell` (`Sources/SwiftGit/Custom/Shell.swift`) |
| 77 | + - Centralizes process creation, captures stdout/stderr, provides publishers and async helpers. |
| 78 | + - Use `Git.data(...)` or `Git.run(...)` which delegate to `Shell.Instance`. |
| 79 | + |
| 80 | +- `GitEnvironment` (`Sources/SwiftGit/Custom/GitEnvironment.swift`) |
| 81 | + - Selects between embedded git (`.embed`), system git (`.system`), or custom folder. |
| 82 | + - Exposes environment variables used to run git (e.g. `GIT_EXEC_PATH`). |
| 83 | + |
| 84 | +- `Git` (`Sources/SwiftGit/Custom/Git.swift`) |
| 85 | + - High-level entrypoint. Use `Git(environment:)` or `try Git.shared` (throws if environment fails). |
| 86 | + - Methods: `run`, `runPublisher`, `data` with variants for arrays of args and string commands. |
| 87 | + |
| 88 | +- `Repository` (`Sources/SwiftGit/Custom/Repository.swift` + `Repository+*.swift`) |
| 89 | + - Convenience methods that operate in a repository directory (run, clone, status, tag, etc.). |
| 90 | + |
| 91 | +- `GitStatus` and parsing models (`Sources/SwiftGit/Custom/models/GitStatus.swift`) |
| 92 | + - Strongly-typed representations of `git status` output. Parsing code is defensive to avoid crashes on malformed input. |
| 93 | + |
| 94 | +Embedded git bundle |
| 95 | +- This repository includes a pre-packaged git distribution at: |
| 96 | + |
| 97 | + `Sources/SwiftGit/Resource/git-instance.bundle` |
| 98 | + |
| 99 | +- `GitEnvironment` will prefer the embedded instance when `Style.embed` is selected or when `Style.auto` finds it. |
| 100 | +- Agents and tests should not modify files under the bundle. Use `GitEnvironment.Style.custom(URL)` to point to an alternate git distribution. |
| 101 | + |
| 102 | +Tests and integration tests |
| 103 | +- Tests live under `Tests/SwiftGitTests/`. |
| 104 | + - Unit tests: parsing and helpers (safe parsing of `git` output, command splitting). |
| 105 | + - Integration tests: initialize temporary repos and run real git workflows (init, add, commit, tag, branch, stash, rebase, plumbing commands like `write-tree`). |
| 106 | +- Integration tests try to use the embedded git first and fall back to system git. If neither is available they skip. |
| 107 | +- Helper examples: `Tests/SwiftGitTests/IntegrationTests.swift`, `PlumbingTests.swift`, `ShowCommitResultTests.swift`. |
| 108 | + |
| 109 | +Design & safety notes |
| 110 | +- Parsing: code attempts to be defensive; `GitStatus` uses failable/parsing helpers and falls back to safe defaults for malformed input. |
| 111 | +- Process execution: `Shell` captures stdout/stderr and surfaces a typed error when a process exits non‑zero (includes exit code and working directory where possible). |
| 112 | +- Command string handling: the library provides a `splitCommandLine` helper to handle quoted/escaped arguments for string-based overloads. Prefer array-based overloads when possible to avoid shell-escaping issues. |
| 113 | + |
| 114 | +CI |
| 115 | +- A GitHub Actions workflow is included at `.github/workflows/ci.yml` and runs the build + tests on `macos-latest`. |
| 116 | + |
| 117 | +Contributing and agents |
| 118 | +- There is an `AGENTS.md` file with rules and commands for automated agents and contributors. Agents should follow its guidelines when editing, testing, and committing. |
| 119 | + |
| 120 | +Example usage |
| 121 | +- Simple programmatic example (conceptual): |
| 122 | + |
| 123 | +```swift |
| 124 | +import SwiftGit |
| 125 | + |
| 126 | +// create environment and git |
| 127 | +let env = try GitEnvironment(type: .auto) |
| 128 | +let git = try Git(environment: env) |
| 129 | + |
| 130 | +// run git --version |
| 131 | +let version = try git.run(["--version"]) |
| 132 | +print("git version: \(version)") |
| 133 | +``` |
| 134 | + |
| 135 | +Where to look next |
| 136 | +- If you want to understand parsing code, start with `Sources/SwiftGit/Custom/results/ShowCommitResult.swift` and |
| 137 | + `Sources/SwiftGit/Custom/models/GitStatus.swift`. |
| 138 | +- To add a new command helper, follow existing patterns under `Sources/SwiftGit/Custom/commands/`. |
| 139 | + |
| 140 | +Questions or issues |
| 141 | +- Open an issue describing what you tried, including commands and repository state. If you want me to extend tests to cover more commands from the official Git docs, say which areas to prioritize (plumbing, submodule flows, network edge cases, etc.). |
0 commit comments