How sochi works
The ideas behind sochi, the Apple tools it calls, and where to start in the code.
Principles
Section titled “Principles”Xcode is the source of truth. sochi has no hand-written lists of Apple’s data. Templates, the capability catalog, entitlement and Info.plist schemas, and product types all come from the selected Xcode when sochi runs. A new Xcode brings new capabilities and templates with no sochi update.
Remember choices, never settings. sochi saves the scheme and team you picked, and nothing else. Build settings are read from xcodebuild every time.
Every edit is checked or undone. Edits are planned first, shown as a diff, written atomically, then checked against xcodebuild. If a check fails, every file goes back.
Your project stays an Xcode project. No generator, no new format. sochi edits project.pbxproj in place in Xcode’s own style, so Xcode and sochi can take turns on the same project.
Status on stderr, app on stdout. You can pipe sochi run into other tools.
Apple tools sochi calls
Section titled “Apple tools sochi calls”| Tool | Used for |
|---|---|
xcodebuild |
Building, listing schemes and targets, reading build settings, resolving packages. |
xcrun devicectl |
Listing devices, checking installed apps, installing, launching with the console attached. |
xcrun simctl |
Listing, booting, installing on and launching simulators. |
swift package dump-package |
Reading a package’s products. |
git ls-remote |
Finding a package’s newest release tag. |
xcode-select, defaults |
Finding Xcode, and the teams signed into it. |
Signing is Xcode’s automatic signing, through xcodebuild -allowProvisioningUpdates. sochi doesn’t use the App Store Connect API, libimobiledevice, XcodeProj or Tuist.
Code layout
Section titled “Code layout”sochi is a Swift 6 package that needs macOS 14 or later. Its only dependency is swift-argument-parser.
| Target | Role |
|---|---|
sochi |
The command-line interface: commands, options, terminal output. |
SochiKit |
Everything else. |
SochiKitTests |
Swift Testing suites. Many read the installed Xcode. |
Running an app
Section titled “Running an app”Session holds one project, scheme and destination.
XcodeProjectfinds the project.- The scheme, device and team are resolved, from your options first, then saved choices, then detection.
Xcodebuildbuilds into sochi’s own DerivedData, andBuildLogturns the output into tasks, diagnostics and results.AppBundlechecks the product,ProjectStatedecides whether to install, anddevicectlorsimctllaunch it.
Editing a project
Section titled “Editing a project”ProjectEditor plans an edit as an EditPlan, then applies it. Parts it relies on:
PBXProjectFilereadsproject.pbxproj, andPBXEditorandPBXTextWritermake targeted text edits in Xcode’s layout.CapabilityCatalog,CapabilityWriterandEntitlementSchemahandle capabilities.TemplateIndex,TemplateEngineandTemplatePlannerrun Xcode’s.xctemplates.ProjectCreatordoes the same forsochi new.XcodeSpecsreads product types and embed rules from Xcode’s.xcspecfiles.Migration,MigrationVerifierandReorganizerhandlesochi migrate.PackageManager,PackageSpecandPackageResolverhandle packages andsochi.toml.
Contributing
Section titled “Contributing”git clone https://github.com/Chandram-Dutta/sochi.gitcd sochiswift buildswift test- Put behaviour in
SochiKit, and only the command wiring insochi. - When something needs Apple data, read it from Xcode rather than adding a list.
- The tests compare sochi’s output with projects that Xcode itself created, in
Fixtures/Golden.Fixtures/Classicis an old group-based project for the migration tests. scripts/build-release.sh 0.1.0builds a universal release binary intodist/for a local check.
Releases are made by publishing a GitHub release with a tag such as v0.1.0. A workflow builds the binary, attaches it with its checksum, and updates the Homebrew formula.