youcaport 0.1.0__tar.gz
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.
- youcaport-0.1.0/LICENSE +21 -0
- youcaport-0.1.0/PKG-INFO +380 -0
- youcaport-0.1.0/README.md +362 -0
- youcaport-0.1.0/pyproject.toml +57 -0
- youcaport-0.1.0/src/youcaport/__init__.py +23 -0
- youcaport-0.1.0/src/youcaport/cli.py +415 -0
- youcaport-0.1.0/src/youcaport/core/docker_manager.py +124 -0
- youcaport-0.1.0/src/youcaport/core/port_manager.py +129 -0
- youcaport-0.1.0/src/youcaport/core/privileges.py +145 -0
- youcaport-0.1.0/src/youcaport/core/process_manager.py +165 -0
- youcaport-0.1.0/src/youcaport/core/profiles.py +91 -0
- youcaport-0.1.0/src/youcaport/core/project_manager.py +41 -0
- youcaport-0.1.0/src/youcaport/core/suggester.py +27 -0
- youcaport-0.1.0/src/youcaport/core/validator.py +34 -0
- youcaport-0.1.0/src/youcaport/dashboard.py +328 -0
- youcaport-0.1.0/src/youcaport/menu.py +133 -0
- youcaport-0.1.0/src/youcaport/utils/terminal.py +231 -0
youcaport-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Fitiafenohaja
|
|
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.
|
youcaport-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: youcaport
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI pour lister, vérifier et libérer les ports réseau utilisés localement.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: Fitiafenohaja
|
|
8
|
+
Requires-Python: >=3.11,<3.14
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Topic :: System :: Networking
|
|
14
|
+
Requires-Dist: psutil (>=5.9,<7.0)
|
|
15
|
+
Requires-Dist: rich (>=13.0,<14.0)
|
|
16
|
+
Requires-Dist: typer (>=0.12,<1.0)
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# YoucaPort
|
|
20
|
+
|
|
21
|
+
**Gestionnaire de ports en ligne de commande** — trouve, vérifie et libère les ports réseau
|
|
22
|
+
utilisés localement, sans avoir besoin de connaître `lsof`, `ss`, `netstat` ou `kill`.
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
╭──────────────────────────────╮
|
|
26
|
+
│ PORTKEEPER │
|
|
27
|
+
│ Port Manager CLI │
|
|
28
|
+
╰──────────────────────────────╯
|
|
29
|
+
|
|
30
|
+
1. Ports utilisés
|
|
31
|
+
2. Vérifier un port
|
|
32
|
+
3. Libérer un port
|
|
33
|
+
4. Quitter
|
|
34
|
+
|
|
35
|
+
Choix :
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Pourquoi YoucaPort ?
|
|
41
|
+
|
|
42
|
+
Quand vous lancez un projet (Next.js, FastAPI, PostgreSQL, Vite...), il arrive que le port
|
|
43
|
+
soit déjà occupé :
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
EADDRINUSE: address already in use
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Plutôt que de jongler avec `lsof -i :3000`, `kill -9 <PID>` et autres commandes système,
|
|
50
|
+
YoucaPort centralise tout dans une interface simple :
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
PORT APPLICATION PID STATUS
|
|
54
|
+
────────────────────────────────────────
|
|
55
|
+
3000 Next.js 447315 RUNNING
|
|
56
|
+
5173 Vite 321456 RUNNING
|
|
57
|
+
8000 Uvicorn 221890 RUNNING
|
|
58
|
+
5432 PostgreSQL 189230 RUNNING
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
### Avec pipx (recommandé)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pipx install youcaport
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Avec pip
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install youcaport
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Depuis les sources
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
git clone https://github.com/Fitiafenohaja/YoucaPort.git
|
|
81
|
+
cd youcaport
|
|
82
|
+
poetry install
|
|
83
|
+
poetry build
|
|
84
|
+
pipx install dist/youcaport-*.whl
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Prérequis** : Python 3.11+. Plateforme prioritaire : **Linux** (Windows/macOS non testés
|
|
88
|
+
pour cette version, mais l'architecture est déjà abstraite pour une extension future).
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Utilisation
|
|
93
|
+
|
|
94
|
+
### Menu interactif
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
youcaport
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Lance le menu principal : ports utilisés / vérifier un port / libérer un port / quitter.
|
|
101
|
+
|
|
102
|
+
### Commandes directes
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Lister tous les ports utilisés
|
|
106
|
+
youcaport status
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Vérifier un port précis
|
|
111
|
+
youcaport check 3000
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
✗ Port 3000 occupé
|
|
116
|
+
|
|
117
|
+
Application : Next.js
|
|
118
|
+
PID : 447315
|
|
119
|
+
État : En cours d'exécution
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Libérer un port (avec confirmation obligatoire)
|
|
124
|
+
youcaport free 3000
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
Port 3000
|
|
129
|
+
|
|
130
|
+
Application : Next.js
|
|
131
|
+
PID : 447315
|
|
132
|
+
|
|
133
|
+
Voulez-vous arrêter cette application ?
|
|
134
|
+
[y/N]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Aide et version
|
|
139
|
+
youcaport --help
|
|
140
|
+
youcaport --version
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Fonctionnalités avancées (V2 → V6)
|
|
146
|
+
|
|
147
|
+
### Suggérer des ports libres — Auto Port (V4)
|
|
148
|
+
|
|
149
|
+
Quand un port est occupé, `check` propose automatiquement des ports libres proches.
|
|
150
|
+
Une commande dédiée existe aussi :
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
youcaport suggest 3000 --count 5
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```text
|
|
157
|
+
Ports libres suggérés : 3001, 3002, 3003, 3004, 3005
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Profils de projets — Port Profiles (V2)
|
|
161
|
+
|
|
162
|
+
Associez des ports à des projets nommés (stockage : `~/.config/youcaport/profiles.json`) :
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
youcaport profile add frontend 3000 # associe le port 3000 au projet "frontend"
|
|
166
|
+
youcaport profile list # liste les profils
|
|
167
|
+
youcaport profile show frontend # état des ports d'un profil
|
|
168
|
+
youcaport profile remove frontend # supprime le profil
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Ports d'un projet — Project Management (V3)
|
|
172
|
+
|
|
173
|
+
Détecte automatiquement les ports utilisés par les processus tournant depuis un dossier :
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
youcaport project /chemin/vers/mon/projet
|
|
177
|
+
# ou, depuis le dossier du projet :
|
|
178
|
+
youcaport project .
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Dashboard web local (V5)
|
|
182
|
+
|
|
183
|
+
Interface web locale (stdlib, aucune dépendance supplémentaire), auto-rechargée :
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
youcaport dashboard # http://127.0.0.1:8421
|
|
187
|
+
youcaport dashboard --port 9000
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Une API JSON est exposée sur `/api/ports`, pratique pour l'intégration.
|
|
191
|
+
|
|
192
|
+
### Ports protégés (root / docker) — mode sudo
|
|
193
|
+
|
|
194
|
+
Certains écouteurs (services système, moteur Docker, autre utilisateur) ne sont pas
|
|
195
|
+
identifiables par un utilisateur normal : YoucaPort les affiche alors comme occupés
|
|
196
|
+
mais **non identifiés**, sans pouvoir les arrêter. Le mode `--sudo` lève ce voile en
|
|
197
|
+
interrogeant `ss` avec les privilèges root (le mot de passe sudo sert de confirmation) :
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
youcaport status --sudo # identifie les ports protégés
|
|
201
|
+
youcaport check 8080 --sudo # détail d'un port protégé
|
|
202
|
+
youcaport free 9100 --sudo # arrête vraiment le processus protégé (TERM puis KILL)
|
|
203
|
+
youcaport dashboard --sudo # enrichit l'API/la page (uniquement si sudo déjà authentifié)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Comportements importants :
|
|
207
|
+
|
|
208
|
+
- CLI : si sudo n'est pas encore authentifié, le mot de passe est **demandé** au lancement ;
|
|
209
|
+
si ce n'est pas possible (pas de terminal), un message invite à lancer une fois `sudo -v`.
|
|
210
|
+
- Dashboard : jamais de demande de mot de passe — il n'utilise que les identifiants déjà
|
|
211
|
+
en cache (`sudo -n`), sinon les ports restent « non identifiés ».
|
|
212
|
+
- L'arrêt reste **toujours confirmé** et passe par TERM puis KILL en dernier recours.
|
|
213
|
+
- Sous Windows, le mode `--sudo` est sans effet (pas de `sudo`/`ss`).
|
|
214
|
+
|
|
215
|
+
### Gestion des conteneurs Docker (V6)
|
|
216
|
+
|
|
217
|
+
Quand un port est occupé par le moteur Docker, identifiez puis arrêtez le bon conteneur
|
|
218
|
+
(`docker-proxy` n'est qu'un relais — arrêter le conteneur est la bonne manière) :
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
youcaport docker list # conteneurs actifs + leurs ports hôtes
|
|
222
|
+
youcaport docker show 5432 # conteneur qui publie le port 5432 (détails)
|
|
223
|
+
youcaport docker stop 5432 # arrête le conteneur (confirmation obligatoire)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
```text
|
|
227
|
+
Port 5432 → conteneur Docker
|
|
228
|
+
Nom : postgres-dev
|
|
229
|
+
ID : a1b2c3d4e5f6
|
|
230
|
+
Image : postgres:16
|
|
231
|
+
Statut : Up 2 hours
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Fonctionne partout où le CLI `docker` est disponible. Après l'arrêt, le port revient
|
|
235
|
+
libre : `youcaport status` le confirme.
|
|
236
|
+
|
|
237
|
+
### Exécutable autonome (PyInstaller)
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
make binary # ou : ./scripts/dev.sh binary
|
|
241
|
+
./dist/youcaport --version
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Windows
|
|
247
|
+
|
|
248
|
+
YoucaPort fonctionne aussi sur Windows (psutil est multiplateforme, couvert par un job CI
|
|
249
|
+
`windows-latest`). Particularités :
|
|
250
|
+
|
|
251
|
+
- **Installation** : `pip install youcaport` (ou `pipx install youcaport`) ; l'exécutable
|
|
252
|
+
PyInstaller se construit sur une machine Windows (`make binary` n'est pas requis,
|
|
253
|
+
utiliser `scripts/build_binary.sh` dans un terminal Windows).
|
|
254
|
+
- **Arrêt d'un processus** : Windows n'offre pas de signal d'arrêt gracieux (SIGTERM) ;
|
|
255
|
+
`terminate()` réalise un arrêt immédiat. YoucaPort vous en avertit explicitement avant
|
|
256
|
+
la confirmation.
|
|
257
|
+
- **Profil de projets** : le fichier `profiles.json` est stocké dans `%LOCALAPPDATA%\youcaport\`
|
|
258
|
+
(au lieu de `~/.config/youcaport/` sur Linux/macOS).
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Fonctionnement de l'arrêt d'un processus
|
|
263
|
+
|
|
264
|
+
YoucaPort ne tue jamais un processus brutalement par défaut :
|
|
265
|
+
|
|
266
|
+
1. Confirmation obligatoire (`y/N`) avec rappel de l'application, du PID et du port.
|
|
267
|
+
2. Envoi d'un **SIGTERM** (arrêt propre).
|
|
268
|
+
3. Période de grâce de **3 secondes**.
|
|
269
|
+
4. **SIGKILL** uniquement si le processus n'a pas répondu au SIGTERM.
|
|
270
|
+
|
|
271
|
+
Aucune stack trace n'est jamais affichée à l'utilisateur : chaque erreur (port invalide,
|
|
272
|
+
permission insuffisante, processus déjà arrêté...) est traduite en message clair en français,
|
|
273
|
+
avec un code de sortie approprié (`0` ou `1`).
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Architecture
|
|
278
|
+
|
|
279
|
+
```text
|
|
280
|
+
youcaport/
|
|
281
|
+
│
|
|
282
|
+
├── pyproject.toml # source de vérité pour la version et les dépendances
|
|
283
|
+
├── poetry.lock
|
|
284
|
+
├── README.md
|
|
285
|
+
├── LICENSE
|
|
286
|
+
│
|
|
287
|
+
├── src/youcaport/
|
|
288
|
+
│ ├── __init__.py # version via importlib.metadata (repli tomllib en dev)
|
|
289
|
+
│ ├── cli.py # commandes Typer (status/check/free/suggest/project/dashboard/profile)
|
|
290
|
+
│ ├── menu.py # menu interactif + sous-menu — pas de logique métier
|
|
291
|
+
│ ├── dashboard.py # interface web locale (V5) — stdlib uniquement
|
|
292
|
+
│ │
|
|
293
|
+
│ ├── core/ # aucune dépendance d'affichage, 100% testable
|
|
294
|
+
│ │ ├── port_manager.py # orchestration, dataclass InfoPort
|
|
295
|
+
│ │ ├── process_manager.py # seul module appelant psutil (abstraction Linux/macOS/Windows)
|
|
296
|
+
│ │ ├── privileges.py # accès privilégié (sudo) aux processus protégés
|
|
297
|
+
│ │ ├── docker_manager.py # conteneurs Docker publiant des ports (V6)
|
|
298
|
+
│ │ ├── validator.py # validateurs + exceptions (PortInvalideError, ...)
|
|
299
|
+
│ │ ├── profiles.py # profils de projets (V2) — JSON via XDG
|
|
300
|
+
│ │ ├── suggester.py # ports libres à proximité (V4)
|
|
301
|
+
│ │ └── project_manager.py # ports utilisés par un projet (V3)
|
|
302
|
+
│ │
|
|
303
|
+
│ └── utils/
|
|
304
|
+
│ └── terminal.py # seul module Rich (tableaux, confirmations, gestion des erreurs)
|
|
305
|
+
│
|
|
306
|
+
└── tests/
|
|
307
|
+
├── test_ports.py # sockets réellement en écoute
|
|
308
|
+
├── test_processes.py # sous-processus enfants réellement lancés/tués
|
|
309
|
+
├── test_validator.py
|
|
310
|
+
├── test_profiles.py # profils de projets
|
|
311
|
+
├── test_suggester.py # auto-port
|
|
312
|
+
├── test_project.py # détection par projet
|
|
313
|
+
├── test_privileges.py # parsing `ss` via sudo + enrichissement
|
|
314
|
+
└── test_docker.py # parsing `docker ps` (V6)
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Principes respectés :**
|
|
318
|
+
- `core/` ne dépend d'aucune bibliothèque d'affichage (testable en isolation).
|
|
319
|
+
- `cli.py` / `menu.py` orchestrent uniquement ; tout l'affichage passe par `utils/terminal.py`.
|
|
320
|
+
- Exceptions personnalisées plutôt que codes de retour épars.
|
|
321
|
+
- Tests réalistes (sockets et sous-processus réels), mocks réservés aux cas impossibles à
|
|
322
|
+
reproduire en local (ex. permission refusée).
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Développement
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
# Installer les dépendances (dev incluses)
|
|
330
|
+
make install
|
|
331
|
+
# ou : poetry install
|
|
332
|
+
|
|
333
|
+
# Lancer les tests
|
|
334
|
+
make test
|
|
335
|
+
# ou : poetry run pytest
|
|
336
|
+
|
|
337
|
+
# Lint + format
|
|
338
|
+
make lint
|
|
339
|
+
make format
|
|
340
|
+
# ou : poetry run ruff check . / poetry run ruff format .
|
|
341
|
+
|
|
342
|
+
# Build (wheel + sdist)
|
|
343
|
+
make build
|
|
344
|
+
# ou : poetry build
|
|
345
|
+
|
|
346
|
+
# Exécutable autonome (PyInstaller)
|
|
347
|
+
make binary
|
|
348
|
+
# ou : ./scripts/dev.sh binary
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Toutes ces commandes sont aussi disponibles via `scripts/dev.sh`.
|
|
352
|
+
|
|
353
|
+
### CI/CD
|
|
354
|
+
|
|
355
|
+
`.github/workflows/ci.yml` exécute à chaque push/PR :
|
|
356
|
+
- lint (`ruff check`, `ruff format --check`)
|
|
357
|
+
- tests (`pytest`) sur Python 3.11 + 3.12 (Linux), et sur Windows et macOS (Python 3.12)
|
|
358
|
+
|
|
359
|
+
À chaque tag `v*`, le workflow publie automatiquement sur PyPI via **trusted publishing**
|
|
360
|
+
(OIDC — aucun token PyPI à stocker en secret).
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
git tag v0.1.0
|
|
364
|
+
git push origin v0.1.0
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Limites de cette version
|
|
370
|
+
|
|
371
|
+
Comme prévu par le cahier des charges, YoucaPort reste volontairement simple :
|
|
372
|
+
|
|
373
|
+
- **Dashboard lourd / comptes / base de données** : hors périmètre MVP ; le dashboard V5
|
|
374
|
+
est volontairement léger (page locale, stdlib).
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## Licence
|
|
379
|
+
|
|
380
|
+
Voir [LICENSE](./LICENSE).
|