@mcamdali/podexit 0.0.0-stage → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.de.md +254 -0
- package/README.es.md +254 -0
- package/README.fr.md +254 -0
- package/README.ja.md +254 -0
- package/README.ko.md +254 -0
- package/README.md +297 -2
- package/README.pt-BR.md +254 -0
- package/README.ru.md +254 -0
- package/README.tr.md +254 -0
- package/README.zh-CN.md +254 -0
- package/data/publisher-policy.json +42 -0
- package/data/publisher-policy.schema.json +96 -0
- package/dist/analyze.d.ts +20 -0
- package/dist/analyze.js +195 -0
- package/dist/cli/discover.d.ts +15 -0
- package/dist/cli/discover.js +65 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +11 -0
- package/dist/cli/run.d.ts +19 -0
- package/dist/cli/run.js +146 -0
- package/dist/core/classify.d.ts +39 -0
- package/dist/core/classify.js +71 -0
- package/dist/core/lockfile.d.ts +47 -0
- package/dist/core/lockfile.js +164 -0
- package/dist/core/policy.d.ts +45 -0
- package/dist/core/policy.js +40 -0
- package/dist/core/project.d.ts +13 -0
- package/dist/core/project.js +25 -0
- package/dist/core/timeline.d.ts +16 -0
- package/dist/core/timeline.js +14 -0
- package/dist/core/versions.d.ts +11 -0
- package/dist/core/versions.js +57 -0
- package/dist/data.d.ts +3 -0
- package/dist/data.js +9 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +28 -0
- package/dist/net/cache.d.ts +28 -0
- package/dist/net/cache.js +89 -0
- package/dist/net/cocoapods.d.ts +34 -0
- package/dist/net/cocoapods.js +83 -0
- package/dist/net/fetcher.d.ts +33 -0
- package/dist/net/fetcher.js +35 -0
- package/dist/net/github.d.ts +14 -0
- package/dist/net/github.js +42 -0
- package/dist/report/escape.d.ts +17 -0
- package/dist/report/escape.js +54 -0
- package/dist/report/index.d.ts +11 -0
- package/dist/report/index.js +21 -0
- package/dist/report/labels.d.ts +22 -0
- package/dist/report/labels.js +82 -0
- package/dist/report/markdown.d.ts +6 -0
- package/dist/report/markdown.js +75 -0
- package/dist/report/tty.d.ts +12 -0
- package/dist/report/tty.js +103 -0
- package/dist/report-model.d.ts +75 -0
- package/dist/report-model.js +3 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +7 -0
- package/package.json +72 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Muhittin Camdali
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.de.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
<!-- i18n-source: README.md@1c83a153cf8713f20722fb4899b14a3a0509ab39 status=reviewed -->
|
|
2
|
+
<!-- brand:start -->
|
|
3
|
+
|
|
4
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/banner-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/banner-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/banner-light.svg" alt="podexit: Which of your pods stop getting updates when CocoaPods trunk goes read-only, and which already ship a Swift package."></picture></p>
|
|
5
|
+
|
|
6
|
+
<!-- lang-selector:start -->
|
|
7
|
+
<p align="center"><a href="README.md">English</a> · <a href="README.tr.md">Türkçe</a> · <a href="README.zh-CN.md">简体中文</a> · <a href="README.ja.md">日本語</a> · <a href="README.ko.md">한국어</a> · <a href="README.es.md">Español</a> · <a href="README.de.md">Deutsch</a> · <a href="README.fr.md">Français</a> · <a href="README.pt-BR.md">Português (Brasil)</a> · <a href="README.ru.md">Русский</a></p>
|
|
8
|
+
<!-- lang-selector:end -->
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://github.com/muhittincamdali/podexit/actions/workflows/ci.yml"><img src="https://github.com/muhittincamdali/podexit/actions/workflows/ci.yml/badge.svg" alt="CI-Status"></a>
|
|
12
|
+
<a href="https://github.com/muhittincamdali/podexit/releases"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-version-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-version-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-version-light.svg" alt="Aktuelle Version: v0.1.1"></picture></a>
|
|
13
|
+
<a href="https://github.com/muhittincamdali/podexit/blob/main/package.json"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-language-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-language-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-language-light.svg" alt="Sprachversion: Node.js 22.12+"></picture></a>
|
|
14
|
+
<a href="https://github.com/muhittincamdali/podexit/blob/main/LICENSE"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-license-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-license-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-license-light.svg" alt="Lizenz: MIT"></picture></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<p align="center">
|
|
18
|
+
<a href="#schnellstart"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-start-de-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-start-de-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-start-de-light.svg" alt="Loslegen"></picture></a>
|
|
19
|
+
<a href="https://muhittincamdali.github.io/podexit/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-docs-de-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-docs-de-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-docs-de-light.svg" alt="Dokumentation"></picture></a>
|
|
20
|
+
<a href="https://github.com/muhittincamdali/podexit/tree/main/docs/guides"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-guides-de-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-guides-de-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-guides-de-light.svg" alt="Anleitungen"></picture></a>
|
|
21
|
+
<a href="https://github.com/muhittincamdali/podexit/tree/main/examples"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-examples-de-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-examples-de-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-examples-de-light.svg" alt="Beispiele"></picture></a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
> Dies ist eine Übersetzung der englischen README. Bei Abweichungen gilt die englische Fassung.
|
|
25
|
+
|
|
26
|
+
<!-- brand:end -->
|
|
27
|
+
|
|
28
|
+
CocoaPods trunk wird am 2. Dezember 2026 schreibgeschützt. Deine Builds laufen weiter, aber dort veröffentlichte Pods bekommen nie wieder ein Update. podexit zeigt dir, welche deiner Abhängigkeiten eingefroren sind, welche bereits ein Swift-Package anbieten und wie der Migrationsweg für natives iOS, Flutter und React Native/Expo aussieht. Es liest das `Podfile.lock`, das du ohnehin hast; in dein Projekt wird nichts installiert.
|
|
29
|
+
|
|
30
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="docs/media/demo-native-dark.svg"><source media="(prefers-color-scheme: light)" srcset="docs/media/demo-native-light.svg"><img src="docs/media/demo-native-light.svg" alt="podexit auf einer nativen iOS-App: Firebase-Pods auf 12.x begrenzt; Alamofire, Kingfisher, SnapKit und andere ab dem 2. Dezember eingefroren, jeweils mit einem Swift-Package"></picture>
|
|
31
|
+
|
|
32
|
+
<sub>Aufgezeichnet mit der echten CLI am <a href="fixtures/native-app/Podfile">native-app-Fixture</a>, mit den am 14. Oktober 2026 gespeicherten Antworten von trunk und GitHub (<code>npm run demo</code>).</sub>
|
|
33
|
+
|
|
34
|
+
## Highlights
|
|
35
|
+
|
|
36
|
+
- **Zwei Antworten pro Pod**: ob er keine Updates mehr bekommt (auf trunk eingefroren, vom Herausgeber früh begrenzt oder nicht betroffen) und ob sein Upstream-Repository ein `Package.swift` hat.
|
|
37
|
+
- **Versionsbewusst**: Prüft auch das `Package.swift` am gesperrten Tag und weist darauf hin, wenn das Swift-Package erst in neueren Versionen existiert.
|
|
38
|
+
- **Firebase-Obergrenze eingebaut**: Die 20 von Firebase aufgeführten Pods sind samt ihren Subabhängigkeiten auf 12.x begrenzt, belegt durch eine Datendatei mit Quellenangabe, die die Firebase-Seite zitiert.
|
|
39
|
+
- **Nativ, Flutter, React Native und Expo**: Findet `Podfile.lock` im Ordner selbst oder in `ios/`, `macos/`, `example/ios/` oder `example/macos/`, erkennt die Projektart und verlinkt die passende Anleitung.
|
|
40
|
+
- **Terminal, Markdown oder JSON**: eine Tabelle für dich, Markdown für einen Pull Request, JSON für Skripte.
|
|
41
|
+
- **Funktioniert offline**: Antworten werden 24 Stunden in `~/.cache/podexit` zwischengespeichert; `--offline` nutzt nur den Cache.
|
|
42
|
+
|
|
43
|
+
## Schnellstart
|
|
44
|
+
|
|
45
|
+
Du brauchst [Node.js](https://nodejs.org/) 22.12 oder neuer (`node --version` zeigt die Version an; auf dem Mac installiert `brew install node` es). Sonst nichts.
|
|
46
|
+
|
|
47
|
+
**1. Öffne ein Terminal im Ordner deiner App**, in dem das `Podfile`, der Ordner `ios/` oder (bei einem Flutter-Plugin) der Ordner `example/` liegt:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
cd path/to/YourApp
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**2. Starte podexit:**
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
npx @mcamdali/podexit
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Das npm-Paket heißt `@mcamdali/podexit` (npm hat den Namen ohne Scope abgelehnt); der Befehl, den es installiert, heißt weiterhin `podexit`.
|
|
60
|
+
|
|
61
|
+
**3. Lies die Tabelle.** Zeilen mit **capped** hören zuerst auf (Firebase veröffentlicht ab Oktober 2026 nicht mehr auf CocoaPods); Zeilen mit **frozen after Dec 2** bekommen nach dem 2. Dezember keine neuen Versionen. Wo die Spalte Swift package **yes** zeigt, lässt sich der Pod schon jetzt umstellen. Die letzte Zeile verlinkt die Anleitung für deine Projektart.
|
|
62
|
+
|
|
63
|
+
## Was sich am 2. Dezember ändert (und was nicht)
|
|
64
|
+
|
|
65
|
+
Laut der [CocoaPods-Ankündigung](https://blog.cocoapods.org/CocoaPods-Specs-Repo/) und der [Firebase-Migrationsseite](https://firebase.google.com/docs/ios/cocoapods-deprecation):
|
|
66
|
+
|
|
67
|
+
1. **Builds laufen weiter.** Das Specs-Repository und das CDN bleiben online; `pod install` löst weiterhin jede bereits veröffentlichte Version auf. Ein Testlauf des Schreibschutzes findet vom 1. bis 7. November 2026 statt.
|
|
68
|
+
2. **Pods auf trunk bekommen nach dem 2. Dezember 2026 keine neuen Versionen mehr**, auch keine Sicherheitskorrekturen, es sei denn, sie werden anders ausgeliefert (meist als Swift-Package).
|
|
69
|
+
3. **Firebase 12 ist die letzte Hauptversion auf CocoaPods**, und Firebase veröffentlicht dort ab Oktober 2026 nicht mehr. Die Versionen 12 und früher bleiben installierbar.
|
|
70
|
+
|
|
71
|
+
Mehr dazu in [Was sich am 2. Dezember ändert](docs/guides/what-changes.md).
|
|
72
|
+
|
|
73
|
+
## Installation
|
|
74
|
+
|
|
75
|
+
Führe es ohne Installation aus oder füge es einem Projekt hinzu, um die Version festzulegen:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
npm install --save-dev @mcamdali/podexit
|
|
79
|
+
npx @mcamdali/podexit
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
So installierst du den Befehl global:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
npm i -g @mcamdali/podexit
|
|
86
|
+
podexit
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Mit Homebrew genügt `brew install muhittincamdali/tap/podexit`; das installiert das Release-Tarball von GitHub.
|
|
90
|
+
|
|
91
|
+
## Verwendung
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
podexit [paths...] [options]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
| Option | Was sie macht |
|
|
98
|
+
| ----------------------- | ---------------------------------------------------------------------------------- |
|
|
99
|
+
| `paths` | `Podfile.lock`-Dateien oder Projektordner; Standard ist der aktuelle Ordner |
|
|
100
|
+
| `-f, --format <format>` | `tty` (Standard), `markdown` oder `json` |
|
|
101
|
+
| `-o, --output <file>` | Schreibt den Bericht in eine Datei statt ins Terminal |
|
|
102
|
+
| `-a, --all` | Listet in der Tabelle auch Pods aus lokalen Pfaden, git und privaten Specs auf |
|
|
103
|
+
| `--offline` | Nutzt nur Antworten aus dem Cache; greift nie aufs Netzwerk zu |
|
|
104
|
+
| `--refresh` | Ignoriert den Cache und fragt das Netzwerk erneut |
|
|
105
|
+
| `--cache-dir <dir>` | Cache-Ordner (Standard `$XDG_CACHE_HOME/podexit` oder `~/.cache/podexit`) |
|
|
106
|
+
| `--no-color` | Reiner Text, auch in einem Terminal (`NO_COLOR` und `FORCE_COLOR` werden beachtet) |
|
|
107
|
+
| `--concurrency <n>` | Parallele Pod-Abfragen, 1 bis 64 (Standard 8) |
|
|
108
|
+
|
|
109
|
+
Exit-Codes: `0` Bericht geschrieben, `2` ungültige Argumente, kein `Podfile.lock` gefunden oder eine Datei, die keines ist, `1` alles Unerwartete. podexit berichtet; es lässt keinen Build wegen seiner Funde fehlschlagen.
|
|
110
|
+
|
|
111
|
+
Ohne Pfade liest podexit jede Lockfile, die es unter `Podfile.lock`, `ios/Podfile.lock`, `macos/Podfile.lock`, `example/ios/Podfile.lock` und `example/macos/Podfile.lock` findet; ein als Pfad übergebener Ordner wird genauso durchsucht.
|
|
112
|
+
|
|
113
|
+
| Umgebungsvariable | Was sie macht |
|
|
114
|
+
| -------------------------- | -------------------------------------------------------------------------- |
|
|
115
|
+
| `PODEXIT_CACHE_DIR` | Cache-Ordner, wenn `--cache-dir` fehlt |
|
|
116
|
+
| `GITHUB_TOKEN`, `GH_TOKEN` | Wird nur an GitHub-Hosts gesendet; nötig für private Upstream-Repositories |
|
|
117
|
+
| `NO_COLOR`, `FORCE_COLOR` | Schaltet Terminalfarben aus oder ein |
|
|
118
|
+
|
|
119
|
+
### Einen Markdown-Bericht beim Code aufbewahren
|
|
120
|
+
|
|
121
|
+
```sh
|
|
122
|
+
npx @mcamdali/podexit --format markdown --output podexit.md
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Die Markdown-Version enthält dieselben Tabellen, Veröffentlichungsdaten und Links zum Repository jedes Swift-Packages; Pods aus lokalen Pfaden und git werden in einem `<details>`-Block zusammengefasst.
|
|
126
|
+
|
|
127
|
+
### Den JSON-Bericht in Skripten verwenden
|
|
128
|
+
|
|
129
|
+
```sh
|
|
130
|
+
npx @mcamdali/podexit --format json > podexit.json
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Jeder Pod enthält `updates.status`, `swiftPackage.status`, die neueste Version auf trunk mit Datum und einen Satz, der jede Antwort erklärt. Das Layout ist `schemaVersion` 0 und kann sich vor 1.0 ändern. [examples/shell/frozen-pods.sh](examples/shell/frozen-pods.sh) filtert ihn mit `jq`.
|
|
134
|
+
|
|
135
|
+
### In CI ausführen
|
|
136
|
+
|
|
137
|
+
[examples/github-actions/podexit.yml](examples/github-actions/podexit.yml) fügt den Bericht der Job-Zusammenfassung jedes Pull Requests hinzu, der ein `Podfile.lock` ändert.
|
|
138
|
+
|
|
139
|
+
### Rate Limits und private Repositories
|
|
140
|
+
|
|
141
|
+
podexit liest `Package.swift` über raw.githubusercontent.com, das nicht auf das Kontingent der GitHub-API angerechnet wird. Setze `GITHUB_TOKEN` (oder `GH_TOKEN`), um private Upstream-Repositories einzusehen; das Token wird nur an GitHub-Hosts gesendet.
|
|
142
|
+
|
|
143
|
+
### Aus JavaScript
|
|
144
|
+
|
|
145
|
+
```js
|
|
146
|
+
import {
|
|
147
|
+
analyzeLockfile,
|
|
148
|
+
buildReport,
|
|
149
|
+
CachedFetcher,
|
|
150
|
+
HttpFetcher,
|
|
151
|
+
loadPublisherPolicy,
|
|
152
|
+
render,
|
|
153
|
+
} from '@mcamdali/podexit';
|
|
154
|
+
|
|
155
|
+
const policy = loadPublisherPolicy();
|
|
156
|
+
const fetcher = new CachedFetcher(new HttpFetcher({ userAgent: 'my-tool' }), {
|
|
157
|
+
directory: '.cache',
|
|
158
|
+
});
|
|
159
|
+
const lockfile = await analyzeLockfile(text, 'ios/Podfile.lock', { fetcher, policy });
|
|
160
|
+
console.log(render(buildReport([lockfile], { policy, offline: false }), 'markdown'));
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Eine lauffähige Version ist [examples/api/summary.mjs](examples/api/summary.mjs).
|
|
164
|
+
|
|
165
|
+
## Demo
|
|
166
|
+
|
|
167
|
+
Die drei Aufnahmen stammen aus den [Fixtures](fixtures/README.md): echte Projekte, mit der jeweiligen Toolchain erstellt und mit CocoaPods 1.16.2 aufgelöst, abgespielt mit den am 14. Oktober 2026 gespeicherten Antworten.
|
|
168
|
+
|
|
169
|
+
| Projekt | Aufnahme |
|
|
170
|
+
| ---------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
171
|
+
| Native iOS-App (Firebase, Alamofire, Google Sign-In) | oben auf dieser Seite |
|
|
172
|
+
| Flutter-App (FlutterFire, google_sign_in, …) | [hell](docs/media/demo-flutter-light.svg) · [dunkel](docs/media/demo-flutter-dark.svg) |
|
|
173
|
+
| Expo-SDK-57-App (Sentry, RevenueCat, Lottie) | [hell](docs/media/demo-expo-light.svg) · [dunkel](docs/media/demo-expo-dark.svg) |
|
|
174
|
+
|
|
175
|
+
Gemessen auf einem Mac (Apple silicon, M5 Max) mit Node.js 25.9 am 14. Oktober 2026: Ein erster Lauf auf dem nativen Fixture (28 Pods) machte 112 Anfragen und dauerte 6,6 bis 7,1 Sekunden; ein zweiter Lauf antwortete in 0,3 Sekunden aus dem Cache. Die Netzwerkgeschwindigkeit bestimmt den größten Teil der ersten Zahl.
|
|
176
|
+
|
|
177
|
+
Zum erneuten Aufzeichnen: `npm run demo`.
|
|
178
|
+
|
|
179
|
+
## Status
|
|
180
|
+
|
|
181
|
+
| Funktion | Status |
|
|
182
|
+
| ---------------------------------------------------------------------------- | ------------- |
|
|
183
|
+
| `Podfile.lock` lesen: Pods, Subspecs, Abhängigkeitsgraph, Quelle jedes Pods | funktioniert |
|
|
184
|
+
| Neueste Version und Veröffentlichungsdaten von CocoaPods trunk | funktioniert |
|
|
185
|
+
| `Package.swift` im Standard-Branch und am gesperrten Tag | funktioniert |
|
|
186
|
+
| Herausgeber-Obergrenzen (Firebase 12.x) und ihre Subabhängigkeiten | funktioniert |
|
|
187
|
+
| Erkennung von nativ, Flutter-App, Flutter-Plugin, React Native und Expo | funktioniert |
|
|
188
|
+
| Berichte für Terminal, Markdown und JSON; `--offline`-Cache-Wiedergabe | funktioniert |
|
|
189
|
+
| Das npm- oder pub.dev-Paket nennen, das jeden Pod mitbringt | geplant (0.3) |
|
|
190
|
+
| Produktnamen und Versionen des Swift-Packages pro Pod, `plan` → MIGRATION.md | geplant (0.5) |
|
|
191
|
+
| SARIF-Ausgabe, `--fail-on`, GitHub Action | geplant (0.5) |
|
|
192
|
+
| Autorenmodus: podspec → Ausgangspunkt für `Package.swift` | geplant (0.8) |
|
|
193
|
+
| Flutter-`--fix`, statische Webseite, stabiles JSON-Schema | geplant (1.0) |
|
|
194
|
+
|
|
195
|
+
## Dokumentation
|
|
196
|
+
|
|
197
|
+
API-Referenz und Anleitungen: [muhittincamdali.github.io/podexit](https://muhittincamdali.github.io/podexit/).
|
|
198
|
+
|
|
199
|
+
## Anleitungen
|
|
200
|
+
|
|
201
|
+
- [Was sich am 2. Dezember ändert (und was nicht)](docs/guides/what-changes.md)
|
|
202
|
+
- [Natives iOS: von CocoaPods zu Swift Package Manager](docs/guides/native-ios.md)
|
|
203
|
+
- [Flutter-Apps und -Plugins](docs/guides/flutter.md)
|
|
204
|
+
- [React Native und Expo](docs/guides/react-native-expo.md)
|
|
205
|
+
- [Firebase nach Version 12](docs/guides/firebase.md)
|
|
206
|
+
- [Pod-Autoren: Ersatz für `pod trunk push`](docs/guides/pod-authors.md)
|
|
207
|
+
|
|
208
|
+
## Voraussetzungen
|
|
209
|
+
|
|
210
|
+
| Toolchain | Mindestversion |
|
|
211
|
+
| --------- | -------------- |
|
|
212
|
+
| Node.js | 22.12 |
|
|
213
|
+
|
|
214
|
+
CI führt die Tests auf Node.js 22 und 24 (Linux) aus. Lokal laufen sie mit Node.js 22.23, 24.22 und 25.9 auf einem Mac (Apple silicon) durch.
|
|
215
|
+
|
|
216
|
+
## Architektur
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
Podfile.lock ─► parseLockfile pods, subspecs, dependency graph, source per pod
|
|
220
|
+
─► classifyLockfile frozen-on-trunk | capped | not-affected | unknown
|
|
221
|
+
data/publisher-policy.json (sourced; Firebase 12.x)
|
|
222
|
+
─► analyzeLockfile per trunk pod, through a Fetcher:
|
|
223
|
+
cdn.cocoapods.org versions and podspec (GitHub repository and tag)
|
|
224
|
+
trunk.cocoapods.org release dates
|
|
225
|
+
raw.githubusercontent.com Package.swift at HEAD and at the locked tag
|
|
226
|
+
─► buildReport ─► render tty | markdown | json
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
- `src/core/` ist rein: Parsen, Versionsvergleich, Klassifizierung. Keine E/A.
|
|
230
|
+
- Alles aus dem Netzwerk läuft über einen `Fetcher`. `CachedFetcher` speichert pro Anfrage eine JSON-Datei; dieselben Dateien sind die aufgezeichneten Antworten, die die Tests und `--offline` abspielen.
|
|
231
|
+
- Eine fehlende Antwort wird mit Begründung als `unknown` gemeldet, nie als Fehler.
|
|
232
|
+
- Die CLI (`src/cli/`) parst nur Argumente, findet Lockfiles und schreibt die Ausgabe.
|
|
233
|
+
|
|
234
|
+
## Roadmap
|
|
235
|
+
|
|
236
|
+
Siehe die Tabelle unter [Status](#status): 0.3 ergänzt das npm- und pub.dev-Paket hinter jedem Pod, 0.5 den Migrationsplan, SARIF und eine GitHub Action, 0.8 den Autorenmodus, 1.0 ein stabiles JSON-Schema. [CHANGELOG.md](CHANGELOG.md) listet auf, was jedes Release geändert hat.
|
|
237
|
+
|
|
238
|
+
## FAQ
|
|
239
|
+
|
|
240
|
+
**Baut meine App am 2. Dezember nicht mehr?** Doch, sie baut weiter. Sowohl CocoaPods als auch Firebase sagen, dass bestehende Versionen installierbar bleiben. Bei podexit geht es um Updates, die du nicht bekommen wirst, nicht um Builds, die aufhören.
|
|
241
|
+
|
|
242
|
+
**Warum ist ein Pod „unknown“?** Sein Podspec verweist auf einen anderen Host als GitHub (zum Beispiel ein Binary auf dl.google.com), oder das Netzwerk war nicht erreichbar. Die JSON- und Markdown-Berichte nennen den Grund pro Pod.
|
|
243
|
+
|
|
244
|
+
**Warum sind Flutter-Plugins und React-Native-Module „not affected"?** Sie sind Pods mit lokalem Pfad aus `.symlinks/plugins` oder `node_modules` und werden über pub oder npm aktualisiert. Die SDKs, von denen sie abhängen, werden separat aufgelistet, und die können eingefroren sein.
|
|
245
|
+
|
|
246
|
+
**Verändert podexit mein Projekt?** Nein. Es liest `Podfile.lock` und schreibt nur seinen Cache und den Bericht, den du anforderst.
|
|
247
|
+
|
|
248
|
+
## Mitwirken
|
|
249
|
+
|
|
250
|
+
Beiträge sind willkommen. Lies vor einem Pull Request [CONTRIBUTING.md](CONTRIBUTING.md) und den [Verhaltenskodex](https://github.com/muhittincamdali/.github/blob/main/CODE_OF_CONDUCT.md). Sicherheitsprobleme meldest du so, wie es in [SECURITY.md](SECURITY.md) beschrieben ist.
|
|
251
|
+
|
|
252
|
+
## Lizenz
|
|
253
|
+
|
|
254
|
+
Veröffentlicht unter der MIT-Lizenz. Siehe [LICENSE](LICENSE).
|
package/README.es.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
<!-- i18n-source: README.md@1c83a153cf8713f20722fb4899b14a3a0509ab39 status=reviewed -->
|
|
2
|
+
<!-- brand:start -->
|
|
3
|
+
|
|
4
|
+
<p align="center"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/banner-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/banner-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/banner-light.svg" alt="podexit: Which of your pods stop getting updates when CocoaPods trunk goes read-only, and which already ship a Swift package."></picture></p>
|
|
5
|
+
|
|
6
|
+
<!-- lang-selector:start -->
|
|
7
|
+
<p align="center"><a href="README.md">English</a> · <a href="README.tr.md">Türkçe</a> · <a href="README.zh-CN.md">简体中文</a> · <a href="README.ja.md">日本語</a> · <a href="README.ko.md">한국어</a> · <a href="README.es.md">Español</a> · <a href="README.de.md">Deutsch</a> · <a href="README.fr.md">Français</a> · <a href="README.pt-BR.md">Português (Brasil)</a> · <a href="README.ru.md">Русский</a></p>
|
|
8
|
+
<!-- lang-selector:end -->
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://github.com/muhittincamdali/podexit/actions/workflows/ci.yml"><img src="https://github.com/muhittincamdali/podexit/actions/workflows/ci.yml/badge.svg" alt="Estado de CI"></a>
|
|
12
|
+
<a href="https://github.com/muhittincamdali/podexit/releases"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-version-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-version-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-version-light.svg" alt="Última versión: v0.1.1"></picture></a>
|
|
13
|
+
<a href="https://github.com/muhittincamdali/podexit/blob/main/package.json"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-language-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-language-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-language-light.svg" alt="Versión del lenguaje: Node.js 22.12+"></picture></a>
|
|
14
|
+
<a href="https://github.com/muhittincamdali/podexit/blob/main/LICENSE"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-license-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-license-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/badge-license-light.svg" alt="Licencia: MIT"></picture></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<p align="center">
|
|
18
|
+
<a href="#inicio-rápido"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-start-es-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-start-es-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-start-es-light.svg" alt="Empezar"></picture></a>
|
|
19
|
+
<a href="https://muhittincamdali.github.io/podexit/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-docs-es-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-docs-es-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-docs-es-light.svg" alt="Documentación"></picture></a>
|
|
20
|
+
<a href="https://github.com/muhittincamdali/podexit/tree/main/docs/guides"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-guides-es-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-guides-es-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-guides-es-light.svg" alt="Guías"></picture></a>
|
|
21
|
+
<a href="https://github.com/muhittincamdali/podexit/tree/main/examples"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-examples-es-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-examples-es-light.svg"><img src="https://raw.githubusercontent.com/muhittincamdali/podexit/main/.github/brand/button-examples-es-light.svg" alt="Ejemplos"></picture></a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
> Esta es una traducción del README en inglés. Si hay diferencias, la versión en inglés es la vigente.
|
|
25
|
+
|
|
26
|
+
<!-- brand:end -->
|
|
27
|
+
|
|
28
|
+
CocoaPods trunk pasará a ser de solo lectura el 2 de diciembre de 2026. Tus compilaciones seguirán funcionando, pero los pods publicados allí no recibirán ninguna actualización más. podexit te muestra cuáles de tus dependencias quedan congeladas, cuáles ya ofrecen un paquete de Swift y la ruta de migración para iOS nativo, Flutter y React Native/Expo. Lee el `Podfile.lock` que ya tienes; no se instala nada en tu proyecto.
|
|
29
|
+
|
|
30
|
+
<picture><source media="(prefers-color-scheme: dark)" srcset="docs/media/demo-native-dark.svg"><source media="(prefers-color-scheme: light)" srcset="docs/media/demo-native-light.svg"><img src="docs/media/demo-native-light.svg" alt="podexit ejecutado en una app iOS nativa: pods de Firebase limitados a 12.x; Alamofire, Kingfisher, SnapKit y otros quedan congelados tras el 2 de diciembre, cada uno con un paquete de Swift"></picture>
|
|
31
|
+
|
|
32
|
+
<sub>Grabado con la CLI real sobre el <a href="fixtures/native-app/Podfile">fixture native-app</a>, con las respuestas de trunk y GitHub guardadas el 14 de octubre de 2026 (<code>npm run demo</code>).</sub>
|
|
33
|
+
|
|
34
|
+
## Lo más destacado
|
|
35
|
+
|
|
36
|
+
- **Dos respuestas por pod**: si deja de recibir actualizaciones (congelado en trunk, limitado antes de tiempo por su editor o no afectado) y si su repositorio original tiene un `Package.swift`.
|
|
37
|
+
- **Consciente de las versiones**: comprueba también el `Package.swift` en la etiqueta que tienes bloqueada e indica cuándo el paquete de Swift solo existe en versiones más nuevas.
|
|
38
|
+
- **Límite de Firebase incluido**: los 20 pods de Firebase que figuran en su lista se limitan a 12.x, junto con sus subdependencias, a partir de un archivo de datos con fuentes que cita la página de Firebase.
|
|
39
|
+
- **Nativo, Flutter, React Native y Expo**: encuentra `Podfile.lock` en la carpeta o en `ios/`, `macos/`, `example/ios/` o `example/macos/`, reconoce el tipo de proyecto y enlaza la guía correspondiente.
|
|
40
|
+
- **Terminal, Markdown o JSON**: una tabla para ti, Markdown para una pull request y JSON para scripts.
|
|
41
|
+
- **Funciona sin conexión**: las respuestas se guardan en caché 24 horas en `~/.cache/podexit`; `--offline` usa solo la caché.
|
|
42
|
+
|
|
43
|
+
## Inicio rápido
|
|
44
|
+
|
|
45
|
+
Necesitas [Node.js](https://nodejs.org/) 22.12 o posterior (`node --version` muestra la versión; en un Mac, `brew install node` lo instala). Nada más.
|
|
46
|
+
|
|
47
|
+
**1. Abre una terminal en la carpeta de tu app**, la que contiene el `Podfile`, la carpeta `ios/` o (en un plugin de Flutter) la carpeta `example/`:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
cd path/to/YourApp
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**2. Ejecuta podexit:**
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
npx @mcamdali/podexit
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
El paquete de npm es `@mcamdali/podexit` (npm rechazó el nombre sin ámbito); el comando que instala sigue siendo `podexit`.
|
|
60
|
+
|
|
61
|
+
**3. Lee la tabla.** Las filas marcadas como **capped** son las primeras en detenerse (Firebase deja de publicar en CocoaPods en octubre de 2026); las marcadas como **frozen after Dec 2** no reciben versiones nuevas después del 2 de diciembre. Donde la columna Swift package dice **yes**, el pod se puede migrar ya. La última línea enlaza la guía para tu tipo de proyecto.
|
|
62
|
+
|
|
63
|
+
## Qué cambia el 2 de diciembre (y qué no)
|
|
64
|
+
|
|
65
|
+
Según el [anuncio de CocoaPods](https://blog.cocoapods.org/CocoaPods-Specs-Repo/) y la [página de migración de Firebase](https://firebase.google.com/docs/ios/cocoapods-deprecation):
|
|
66
|
+
|
|
67
|
+
1. **Las compilaciones siguen funcionando.** El repositorio Specs y la CDN siguen en línea; `pod install` sigue resolviendo todas las versiones ya publicadas. Una prueba del modo de solo lectura se hará del 1 al 7 de noviembre de 2026.
|
|
68
|
+
2. **Los pods de trunk no recibirán versiones nuevas** después del 2 de diciembre de 2026, correcciones de seguridad incluidas, a menos que se distribuyan de otra forma (normalmente, un paquete de Swift).
|
|
69
|
+
3. **Firebase 12 es la última versión mayor en CocoaPods**, y Firebase deja de publicar allí en octubre de 2026. Las versiones 12 y anteriores seguirán siendo instalables.
|
|
70
|
+
|
|
71
|
+
Más información en [Qué cambia el 2 de diciembre](docs/guides/what-changes.md).
|
|
72
|
+
|
|
73
|
+
## Instalación
|
|
74
|
+
|
|
75
|
+
Ejecútalo sin instalar, o añádelo a un proyecto para fijar una versión:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
npm install --save-dev @mcamdali/podexit
|
|
79
|
+
npx @mcamdali/podexit
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Para instalar el comando de forma global:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
npm i -g @mcamdali/podexit
|
|
86
|
+
podexit
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Con Homebrew puedes ejecutar `brew install muhittincamdali/tap/podexit`, que instala el tarball de la versión publicada en GitHub.
|
|
90
|
+
|
|
91
|
+
## Uso
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
podexit [paths...] [options]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
| Opción | Qué hace |
|
|
98
|
+
| ----------------------- | ------------------------------------------------------------------------------ |
|
|
99
|
+
| `paths` | Archivos `Podfile.lock` o carpetas de proyecto; por defecto, la carpeta actual |
|
|
100
|
+
| `-f, --format <format>` | `tty` (por defecto), `markdown` o `json` |
|
|
101
|
+
| `-o, --output <file>` | Escribe el informe en un archivo en lugar de la terminal |
|
|
102
|
+
| `-a, --all` | Incluye también en la tabla los pods de rutas locales, git y specs privados |
|
|
103
|
+
| `--offline` | Usa solo respuestas en caché; nunca accede a la red |
|
|
104
|
+
| `--refresh` | Ignora la caché y vuelve a consultar la red |
|
|
105
|
+
| `--cache-dir <dir>` | Carpeta de caché (por defecto `$XDG_CACHE_HOME/podexit` o `~/.cache/podexit`) |
|
|
106
|
+
| `--no-color` | Texto plano incluso en una terminal (se respetan `NO_COLOR` y `FORCE_COLOR`) |
|
|
107
|
+
| `--concurrency <n>` | Consultas de pods en paralelo, de 1 a 64 (por defecto 8) |
|
|
108
|
+
|
|
109
|
+
Códigos de salida: `0` informe escrito; `2` argumentos incorrectos, no se encontró ningún `Podfile.lock` o el archivo no es uno; `1` cualquier otro error inesperado. podexit informa; no hace fallar una compilación por lo que encuentre.
|
|
110
|
+
|
|
111
|
+
Sin rutas, podexit lee cada lockfile que encuentra en `Podfile.lock`, `ios/Podfile.lock`, `macos/Podfile.lock`, `example/ios/Podfile.lock` y `example/macos/Podfile.lock`; una carpeta pasada como ruta se busca de la misma forma.
|
|
112
|
+
|
|
113
|
+
| Variable de entorno | Qué hace |
|
|
114
|
+
| -------------------------- | -------------------------------------------------------------------------------- |
|
|
115
|
+
| `PODEXIT_CACHE_DIR` | Carpeta de caché cuando no se indica `--cache-dir` |
|
|
116
|
+
| `GITHUB_TOKEN`, `GH_TOKEN` | Solo se envía a hosts de GitHub; necesaria para repositorios originales privados |
|
|
117
|
+
| `NO_COLOR`, `FORCE_COLOR` | Desactiva o activa los colores en la terminal |
|
|
118
|
+
|
|
119
|
+
### Guarda un informe en Markdown junto al código
|
|
120
|
+
|
|
121
|
+
```sh
|
|
122
|
+
npx @mcamdali/podexit --format markdown --output podexit.md
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
La versión en Markdown tiene las mismas tablas, las fechas de publicación y los enlaces al repositorio de cada paquete de Swift; los pods de rutas locales y de git se agrupan en un bloque `<details>`.
|
|
126
|
+
|
|
127
|
+
### Usa el informe JSON en scripts
|
|
128
|
+
|
|
129
|
+
```sh
|
|
130
|
+
npx @mcamdali/podexit --format json > podexit.json
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Cada pod incluye `updates.status`, `swiftPackage.status`, la última versión en trunk con su fecha y una frase que explica cada respuesta. El formato es `schemaVersion` 0 y puede cambiar antes de la 1.0. [examples/shell/frozen-pods.sh](examples/shell/frozen-pods.sh) lo filtra con `jq`.
|
|
134
|
+
|
|
135
|
+
### Ejecútalo en CI
|
|
136
|
+
|
|
137
|
+
[examples/github-actions/podexit.yml](examples/github-actions/podexit.yml) añade el informe al resumen del job de cada pull request que modifica un `Podfile.lock`.
|
|
138
|
+
|
|
139
|
+
### Límites de uso y repositorios privados
|
|
140
|
+
|
|
141
|
+
podexit lee `Package.swift` a través de raw.githubusercontent.com, que no consume la cuota de la API de GitHub. Define `GITHUB_TOKEN` (o `GH_TOKEN`) para consultar repositorios originales privados; el token solo se envía a hosts de GitHub.
|
|
142
|
+
|
|
143
|
+
### Desde JavaScript
|
|
144
|
+
|
|
145
|
+
```js
|
|
146
|
+
import {
|
|
147
|
+
analyzeLockfile,
|
|
148
|
+
buildReport,
|
|
149
|
+
CachedFetcher,
|
|
150
|
+
HttpFetcher,
|
|
151
|
+
loadPublisherPolicy,
|
|
152
|
+
render,
|
|
153
|
+
} from '@mcamdali/podexit';
|
|
154
|
+
|
|
155
|
+
const policy = loadPublisherPolicy();
|
|
156
|
+
const fetcher = new CachedFetcher(new HttpFetcher({ userAgent: 'my-tool' }), {
|
|
157
|
+
directory: '.cache',
|
|
158
|
+
});
|
|
159
|
+
const lockfile = await analyzeLockfile(text, 'ios/Podfile.lock', { fetcher, policy });
|
|
160
|
+
console.log(render(buildReport([lockfile], { policy, offline: false }), 'markdown'));
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Hay una versión ejecutable en [examples/api/summary.mjs](examples/api/summary.mjs).
|
|
164
|
+
|
|
165
|
+
## Demo
|
|
166
|
+
|
|
167
|
+
Las tres grabaciones proceden de los [fixtures](fixtures/README.md): proyectos reales creados con cada toolchain y resueltos con CocoaPods 1.16.2, reproducidos con las respuestas guardadas el 14 de octubre de 2026.
|
|
168
|
+
|
|
169
|
+
| Proyecto | Grabación |
|
|
170
|
+
| ---------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
171
|
+
| App iOS nativa (Firebase, Alamofire, Google Sign-In) | parte superior de esta página |
|
|
172
|
+
| App de Flutter (FlutterFire, google_sign_in, …) | [claro](docs/media/demo-flutter-light.svg) · [oscuro](docs/media/demo-flutter-dark.svg) |
|
|
173
|
+
| App de Expo SDK 57 (Sentry, RevenueCat, Lottie) | [claro](docs/media/demo-expo-light.svg) · [oscuro](docs/media/demo-expo-dark.svg) |
|
|
174
|
+
|
|
175
|
+
Medido en un Mac (Apple silicon, M5 Max) con Node.js 25.9 el 14 de octubre de 2026: una primera ejecución sobre el fixture nativo (28 pods) hizo 112 peticiones y tardó de 6,6 a 7,1 segundos; una segunda ejecución respondió desde la caché en 0,3 segundos. La velocidad de la red decide la mayor parte del primer número.
|
|
176
|
+
|
|
177
|
+
Para grabarlas de nuevo: `npm run demo`.
|
|
178
|
+
|
|
179
|
+
## Estado
|
|
180
|
+
|
|
181
|
+
| Funcionalidad | Estado |
|
|
182
|
+
| ----------------------------------------------------------------------------------- | ----------------- |
|
|
183
|
+
| Leer `Podfile.lock`: pods, subspecs, grafo de dependencias, origen de cada pod | funciona |
|
|
184
|
+
| Última versión y fechas de publicación desde CocoaPods trunk | funciona |
|
|
185
|
+
| `Package.swift` en la rama por defecto y en la etiqueta bloqueada | funciona |
|
|
186
|
+
| Límites de los editores (Firebase 12.x) y sus subdependencias | funciona |
|
|
187
|
+
| Detección de nativo, app de Flutter, plugin de Flutter, React Native y Expo | funciona |
|
|
188
|
+
| Informes en terminal, Markdown y JSON; reproducción de caché con `--offline` | funciona |
|
|
189
|
+
| Indicar el paquete de npm o pub.dev que trae cada pod | planificado (0.3) |
|
|
190
|
+
| Nombres de producto y versiones del paquete de Swift por pod, `plan` → MIGRATION.md | planificado (0.5) |
|
|
191
|
+
| Salida SARIF, `--fail-on`, GitHub Action | planificado (0.5) |
|
|
192
|
+
| Modo autor: podspec → punto de partida de `Package.swift` | planificado (0.8) |
|
|
193
|
+
| `--fix` para Flutter, página web estática, esquema JSON estable | planificado (1.0) |
|
|
194
|
+
|
|
195
|
+
## Documentación
|
|
196
|
+
|
|
197
|
+
Referencia de la API y guías: [muhittincamdali.github.io/podexit](https://muhittincamdali.github.io/podexit/).
|
|
198
|
+
|
|
199
|
+
## Guías
|
|
200
|
+
|
|
201
|
+
- [Qué cambia el 2 de diciembre (y qué no)](docs/guides/what-changes.md)
|
|
202
|
+
- [iOS nativo: de CocoaPods a Swift Package Manager](docs/guides/native-ios.md)
|
|
203
|
+
- [Apps y plugins de Flutter](docs/guides/flutter.md)
|
|
204
|
+
- [React Native y Expo](docs/guides/react-native-expo.md)
|
|
205
|
+
- [Firebase después de la versión 12](docs/guides/firebase.md)
|
|
206
|
+
- [Autores de pods: cómo sustituir `pod trunk push`](docs/guides/pod-authors.md)
|
|
207
|
+
|
|
208
|
+
## Requisitos
|
|
209
|
+
|
|
210
|
+
| Toolchain | Versión mínima |
|
|
211
|
+
| --------- | -------------- |
|
|
212
|
+
| Node.js | 22.12 |
|
|
213
|
+
|
|
214
|
+
CI ejecuta las pruebas en Node.js 22 y 24 (Linux). En local pasan con Node.js 22.23, 24.22 y 25.9 en un Mac (Apple silicon).
|
|
215
|
+
|
|
216
|
+
## Arquitectura
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
Podfile.lock ─► parseLockfile pods, subspecs, dependency graph, source per pod
|
|
220
|
+
─► classifyLockfile frozen-on-trunk | capped | not-affected | unknown
|
|
221
|
+
data/publisher-policy.json (sourced; Firebase 12.x)
|
|
222
|
+
─► analyzeLockfile per trunk pod, through a Fetcher:
|
|
223
|
+
cdn.cocoapods.org versions and podspec (GitHub repository and tag)
|
|
224
|
+
trunk.cocoapods.org release dates
|
|
225
|
+
raw.githubusercontent.com Package.swift at HEAD and at the locked tag
|
|
226
|
+
─► buildReport ─► render tty | markdown | json
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
- `src/core/` es puro: análisis, comparación de versiones, clasificación. Sin E/S.
|
|
230
|
+
- Todo lo que viene de la red pasa por un `Fetcher`. `CachedFetcher` guarda un archivo JSON por petición; esos mismos archivos son las respuestas grabadas que reproducen las pruebas y `--offline`.
|
|
231
|
+
- Una respuesta que falta se informa como `unknown` con su motivo, nunca como un error.
|
|
232
|
+
- La CLI (`src/cli/`) solo analiza argumentos, busca lockfiles y escribe la salida.
|
|
233
|
+
|
|
234
|
+
## Hoja de ruta
|
|
235
|
+
|
|
236
|
+
Consulta la tabla de [Estado](#estado): 0.3 añade el paquete de npm y pub.dev que hay detrás de cada pod, 0.5 el plan de migración, SARIF y una GitHub Action, 0.8 el modo autor y 1.0 un esquema JSON estable. [CHANGELOG.md](CHANGELOG.md) enumera los cambios de cada versión.
|
|
237
|
+
|
|
238
|
+
## FAQ
|
|
239
|
+
|
|
240
|
+
**¿Dejará mi app de compilar el 2 de diciembre?** No. Tanto CocoaPods como Firebase dicen que las versiones existentes seguirán siendo instalables. podexit trata de las actualizaciones que no recibirás, no de compilaciones que se detengan.
|
|
241
|
+
|
|
242
|
+
**¿Por qué un pod aparece como "unknown"?** Su podspec apunta a un host distinto de GitHub (por ejemplo, un binario en dl.google.com) o la red no estaba disponible. Los informes JSON y Markdown indican el motivo de cada pod.
|
|
243
|
+
|
|
244
|
+
**¿Por qué los plugins de Flutter y los módulos de React Native aparecen como "not affected"?** Son pods de ruta local procedentes de `.symlinks/plugins` o `node_modules`; se actualizan con pub o npm. Los SDK de los que dependen se listan por separado, y esos sí pueden estar congelados.
|
|
245
|
+
|
|
246
|
+
**¿podexit modifica mi proyecto?** No. Lee `Podfile.lock` y solo escribe su caché y el informe que le pidas.
|
|
247
|
+
|
|
248
|
+
## Contribuir
|
|
249
|
+
|
|
250
|
+
Las contribuciones son bienvenidas. Lee [CONTRIBUTING.md](CONTRIBUTING.md) y el [código de conducta](https://github.com/muhittincamdali/.github/blob/main/CODE_OF_CONDUCT.md) antes de abrir una pull request. Informa de los problemas de seguridad como se describe en [SECURITY.md](SECURITY.md).
|
|
251
|
+
|
|
252
|
+
## Licencia
|
|
253
|
+
|
|
254
|
+
Publicado bajo la licencia MIT. Consulta [LICENSE](LICENSE).
|