mirror of
https://github.com/MobAI-App/simslim.git
synced 2026-09-27 17:02:00 +02:00
The repo root becomes `package simslim`, an importable library holding every piece of slimming logic; the CLI moves to `cmd/simslim`. Previously everything was `package main`, so nothing here could be imported at all. The library carries no external dependencies — urfave/cli stays on the CLI side, along with all terminal-facing code: the interactive profile wizard, writeJSON, truncate/humanBytes, fatal and usage. The library never writes to stdout; it returns values and reports progress through the Reporter callback. Renames forced by collisions with existing types: status() -> ReadStatus, statusForDevice() -> ReadStatusForDevice, diskCleanupPlan() -> PlanDiskCleanup. The shutdown/boot timeouts move to simctl.go as ShutdownTimeout/BootTimeout. `go install` gains a path element: github.com/mobai-app/simslim/cmd/simslim. The installed binary is still named simslim, and -X main.version still applies. packaging/homebrew/simslim.rb.in is updated to match, since std_go_args passes no package path. Verified live against a real simulator: list, profiles, status, doctor, size, disk-plan, measure, boot, shutdown, on, off, on --except, on --profile, clone, rename, delete and the interactive wizard all behave identically to the previous build. JSON output, human output, help text and exit codes are unchanged.
83 lines
3.8 KiB
Go
83 lines
3.8 KiB
Go
package simslim
|
|
|
|
import "fmt"
|
|
|
|
// Feature is a user-facing capability backed by specific launchd daemons.
|
|
// Every label must also live in a Category (enforced in features_test.go), so a
|
|
// feature only ever names daemons the tool could actually have turned off.
|
|
type Feature struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Labels []string `json:"labels"`
|
|
}
|
|
|
|
// Features maps commonly required capabilities to the daemons they need running.
|
|
var Features = []Feature{
|
|
{ID: "push", Name: "Push notifications", Labels: []string{"com.apple.apsd"}},
|
|
{ID: "storekit", Name: "StoreKit / in-app purchase", Labels: []string{"com.apple.storekitd"}},
|
|
{ID: "app-store", Name: "App Store", Labels: []string{"com.apple.appstored", "com.apple.itunesstored"}},
|
|
{ID: "universal-links", Name: "Universal links / associated domains", Labels: []string{"com.apple.swcd"}},
|
|
{ID: "spotlight", Name: "Spotlight & Settings search", Labels: []string{"com.apple.searchd", "com.apple.searchtoold"}},
|
|
{ID: "siri", Name: "Siri & speech", Labels: []string{"com.apple.assistantd", "com.apple.corespeechd"}},
|
|
{ID: "icloud", Name: "iCloud sync", Labels: []string{"com.apple.cloudd"}},
|
|
{ID: "keychain-sync", Name: "iCloud Keychain", Labels: []string{"com.apple.akd"}},
|
|
{ID: "contacts", Name: "Contacts", Labels: []string{"com.apple.contactsd"}},
|
|
{ID: "calendar", Name: "Calendar", Labels: []string{"com.apple.calaccessd"}},
|
|
{ID: "reminders", Name: "Reminders", Labels: []string{"com.apple.remindd"}},
|
|
{ID: "mail", Name: "Mail", Labels: []string{"com.apple.email.maild"}},
|
|
{ID: "photos", Name: "Photos library & analysis", Labels: []string{"com.apple.assetsd", "com.apple.photoanalysisd"}},
|
|
{ID: "health", Name: "HealthKit", Labels: []string{"com.apple.healthd"}},
|
|
{ID: "homekit", Name: "HomeKit", Labels: []string{"com.apple.homed"}},
|
|
{ID: "imessage", Name: "iMessage & FaceTime", Labels: []string{"com.apple.identityservicesd"}},
|
|
{ID: "widgets", Name: "Widgets & Live Activities", Labels: []string{"com.apple.chronod", "com.apple.liveactivitiesd"}},
|
|
{ID: "wallet", Name: "Wallet & passes", Labels: []string{"com.apple.passd"}},
|
|
{ID: "maps", Name: "Maps background services", Labels: []string{"com.apple.Maps.mapssyncd"}},
|
|
{ID: "weather", Name: "Weather", Labels: []string{"com.apple.weatherd"}},
|
|
{ID: "news", Name: "News", Labels: []string{"com.apple.newsd"}},
|
|
{ID: "game-center", Name: "Game Center", Labels: []string{"com.apple.gamed"}},
|
|
{ID: "find-my", Name: "Find My", Labels: []string{"com.apple.findmy.findmylocated"}},
|
|
{ID: "screen-time", Name: "Screen Time", Labels: []string{"com.apple.ScreenTimeAgent"}},
|
|
}
|
|
|
|
func featureByID(id string) (Feature, bool) {
|
|
for _, f := range Features {
|
|
if f.ID == id {
|
|
return f, true
|
|
}
|
|
}
|
|
return Feature{}, false
|
|
}
|
|
|
|
// resolveFeatures maps requested IDs to their Features, erroring on the first
|
|
// unknown one so a typo in --requires fails loudly instead of passing silently.
|
|
func ResolveFeatures(ids []string) ([]Feature, error) {
|
|
out := make([]Feature, 0, len(ids))
|
|
for _, id := range ids {
|
|
f, ok := featureByID(id)
|
|
if !ok {
|
|
return nil, fmt.Errorf("unknown feature %q (see `simslim doctor --list`)", id)
|
|
}
|
|
out = append(out, f)
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// diagnoseFeatures reports, for each feature, which of its daemons the device
|
|
// currently has disabled. A feature is OK only when none of them are.
|
|
func DiagnoseFeatures(features []Feature, disabled map[string]bool) DoctorOutput {
|
|
statuses := make([]FeatureStatus, 0, len(features))
|
|
allOK := true
|
|
for _, f := range features {
|
|
var down []string
|
|
for _, l := range f.Labels {
|
|
if disabled[l] {
|
|
down = append(down, l)
|
|
}
|
|
}
|
|
ok := len(down) == 0
|
|
allOK = allOK && ok
|
|
statuses = append(statuses, FeatureStatus{ID: f.ID, Name: f.Name, OK: ok, Disabled: down})
|
|
}
|
|
return DoctorOutput{OK: allOK, Features: statuses}
|
|
}
|