v0.3.0
This commit is contained in:
parent
d28fc84bae
commit
87fb37fdd5
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
dist/
|
||||||
|
40
CHANGELOG.md
40
CHANGELOG.md
@ -1,16 +1,24 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
- **25/06/15** - commit: v0.2.0
|
- **27/06/15** - commit: v0.3.0
|
||||||
- **Hinzugefügt:**
|
- **Hinzugefügt:**
|
||||||
- [X] git submodule erstellt
|
- [X] Nginx Proxy Manager
|
||||||
- [X] Rust Toolchain Einrichtung
|
|
||||||
- [X] Rust offline-installation
|
---
|
||||||
|
|
||||||
- **25/06/15** - commit: v0.1.0
|
- **25/06/15** - commit: v0.2.0
|
||||||
- **Hinzugefügt:**
|
- **Hinzugefügt:**
|
||||||
- [X] helix
|
- [X] git submodule erstellt
|
||||||
- [x] desktop.ini
|
- [X] Rust Toolchain Einrichtung
|
||||||
|
- [X] Rust offline-installation
|
||||||
---
|
|
||||||
|
---
|
||||||
- **initial commit**
|
|
||||||
|
- **25/06/15** - commit: v0.1.0
|
||||||
|
- **Hinzugefügt:**
|
||||||
|
- [X] helix
|
||||||
|
- [x] desktop.ini
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- **initial commit**
|
||||||
|
2
LICENSE
2
LICENSE
@ -1 +1 @@
|
|||||||
(C) 2025 - Adam Skotarczak <adam@skotarczak.net
|
(C) 2025 - Adam Skotarczak <adam@skotarczak.net
|
||||||
|
353
README.md
353
README.md
@ -1,175 +1,178 @@
|
|||||||
# -= Admin´s Log =-
|
# -= Admin´s Log =-
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Kleine Sammlung von Gedächnissstützen für den privaten und persönlichen Gebrauch.
|
Kleine Sammlung von Gedächnissstützen für den privaten und persönlichen Gebrauch.
|
||||||
Ausserdem befinden sich hier auch viele Artikel die von mir noch nicht vollständig verwertet worden sind.
|
Ausserdem befinden sich hier auch viele Artikel die von mir noch nicht vollständig verwertet worden sind.
|
||||||
Die Artikel sind auch zur Vorbereitung für neue Artikel auf <https://www.ionivation.com> vorgesehen.
|
Die Artikel sind auch zur Vorbereitung für neue Artikel auf <https://www.ionivation.com> vorgesehen.
|
||||||
|
|
||||||
**origin:** <https://local.ionivation.com/realAscot/adminslog>
|
**origin:** <https://local.ionivation.com/realAscot/adminslog>
|
||||||
|
|
||||||
## Inhalt
|
## Inhalt
|
||||||
|
|
||||||
- [-= Admin´s Log =-](#--admins-log--)
|
- [-= Admin´s Log =-](#--admins-log--)
|
||||||
- [Inhalt](#inhalt)
|
- [Inhalt](#inhalt)
|
||||||
- [Informationen](#informationen)
|
- [Informationen](#informationen)
|
||||||
- [Themen](#themen)
|
- [Themen](#themen)
|
||||||
- [AsciiDoc](#asciidoc)
|
- [AsciiDoc](#asciidoc)
|
||||||
- [Editoren/ IDE´s](#editoren-ides)
|
- [Editoren/ IDE´s](#editoren-ides)
|
||||||
- [Helix](#helix)
|
- [Helix](#helix)
|
||||||
- [Git](#git)
|
- [Git](#git)
|
||||||
- [Markdown](#markdown)
|
- [Markdown](#markdown)
|
||||||
- [Mermaid](#mermaid)
|
- [Mermaid](#mermaid)
|
||||||
- [Mechanik](#mechanik)
|
- [Mechanik](#mechanik)
|
||||||
- [Server](#server)
|
- [Server](#server)
|
||||||
- [Plesk](#plesk)
|
- [Plesk](#plesk)
|
||||||
- [Webserver](#webserver)
|
- [Webserver](#webserver)
|
||||||
- [Windows](#windows)
|
- [Windows](#windows)
|
||||||
- [Programmierung](#programmierung)
|
- [Programmierung](#programmierung)
|
||||||
- [Rust](#rust)
|
- [Rust](#rust)
|
||||||
- [ts - js - node](#ts---js---node)
|
- [ts - js - node](#ts---js---node)
|
||||||
- [Projektinhalt](#projektinhalt)
|
- [Projektinhalt](#projektinhalt)
|
||||||
- [Neue Dokumente](#neue-dokumente)
|
- [Neue Dokumente](#neue-dokumente)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Informationen
|
## Informationen
|
||||||
|
|
||||||
Unter `./tools/` befinden sich Programme/ Skripte (aktuell in Typescript und Python) die Markdown-Dateien suchen und daraus ein Verzeichnis erstellen.
|
Unter `./tools/` befinden sich Programme/ Skripte (aktuell in Typescript und Python) die Markdown-Dateien suchen und daraus ein Verzeichnis erstellen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Themen
|
## Themen
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### AsciiDoc
|
### AsciiDoc
|
||||||
|
|
||||||
- [Asciidoctor PDF: Kapitel bleibt „Chapter“ – Fehleranalyse & Workaround](dokus/asciidoc/asciidoctor-theme-bug-workaround.md)
|
- [Asciidoctor PDF: Kapitel bleibt „Chapter“ – Fehleranalyse & Workaround](dokus/asciidoc/asciidoctor-theme-bug-workaround.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Editoren/ IDE´s
|
### Editoren/ IDE´s
|
||||||
|
|
||||||
#### Helix
|
#### Helix
|
||||||
|
|
||||||
- [Helix Editor – Ein umfassender Einstieg für Anfänger (Deutsch)](dokus/helix__editor_einfuehrung_de.md)
|
- [Helix Editor – Ein umfassender Einstieg für Anfänger (Deutsch)](dokus/helix__editor_einfuehrung_de.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Git
|
### Git
|
||||||
|
|
||||||
- [Artikel: git](dokus/git/git.md)
|
- [Artikel: git](dokus/git/git.md)
|
||||||
- [SSH-Zugriff auf Git-Repository in WSL einrichten](dokus/git/git-ssh-remote.md)
|
- [SSH-Zugriff auf Git-Repository in WSL einrichten](dokus/git/git-ssh-remote.md)
|
||||||
- [Git – Remote-Branches: Häufige Aufgaben und Lösungen](dokus/git/git-remote-branch.md)
|
- [Git – Remote-Branches: Häufige Aufgaben und Lösungen](dokus/git/git-remote-branch.md)
|
||||||
- [Git-Submodule: Der umfassende Praxisleitfaden](dokus/git/git-submodule-leitfaden.md)
|
- [Git-Submodule: Der umfassende Praxisleitfaden](dokus/git/git-submodule-leitfaden.md)
|
||||||
|
|
||||||
### Markdown
|
### Markdown
|
||||||
|
|
||||||
#### Mermaid
|
#### Mermaid
|
||||||
|
|
||||||
- [mermaidPockedGuide](https://local.ionivation.com/realAscot/mermaidPockedGuide) **EXTERN** 🚀
|
- [mermaidPockedGuide](https://local.ionivation.com/realAscot/mermaidPockedGuide) **EXTERN** 🚀
|
||||||
|
|
||||||
### Mechanik
|
### Mechanik
|
||||||
|
|
||||||
- [Gewindetabellen](dokus/mechanik/gewindetabellen.md)
|
- [Gewindetabellen](dokus/mechanik/gewindetabellen.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
|
|
||||||
#### Plesk
|
#### Plesk
|
||||||
|
|
||||||
- [Plesk ausgesperrt bei Rechnerwechsel](dokus/plesk/plesk-benutzer-schon-vorhanden.md)
|
- [Plesk ausgesperrt bei Rechnerwechsel](dokus/plesk/plesk-benutzer-schon-vorhanden.md)
|
||||||
|
|
||||||
#### Webserver
|
#### Webserver
|
||||||
|
|
||||||
- [Let's Encrypt: Fehlerbehebung bei Challenge-Timeout unter Plesk](dokus/apache-plesk/lets-encrypt-plesk.md)
|
- [Let's Encrypt: Fehlerbehebung bei Challenge-Timeout unter Plesk](dokus/plesk/lets-encrypt-plesk.md)
|
||||||
|
- [NGINX Proxy Manager als Reverse Proxy für Node.js-Apps](dokus/webserver/nginx-proxy-manager-setup.md)
|
||||||
---
|
|
||||||
|
---
|
||||||
### Windows
|
|
||||||
|
### Windows
|
||||||
- [Einführung in die `desktop.ini`-Datei: Verwendung und Anpassung von Ordnern in Windows](dokus/windows/desktop_ini.md)
|
|
||||||
|
- [Einführung in die `desktop.ini`-Datei: Verwendung und Anpassung von Ordnern in Windows](dokus/windows/desktop_ini.md)
|
||||||
---
|
|
||||||
|
---
|
||||||
### Programmierung
|
|
||||||
|
### Programmierung
|
||||||
#### Rust
|
|
||||||
|
#### Rust
|
||||||
- [Rust-Toolchain mit MSVC unter Windows einrichten](dokus/rust/rust-toolchain-msvc.md)
|
|
||||||
- [Erstellung eines Installationsmediums für Rust + MSVC (Offline)](dokus/rust/rust-offline-installation.md)
|
- [Rust-Toolchain mit MSVC unter Windows einrichten](dokus/rust/rust-toolchain-msvc.md)
|
||||||
|
- [Erstellung eines Installationsmediums für Rust + MSVC (Offline)](dokus/rust/rust-offline-installation.md)
|
||||||
---
|
|
||||||
|
---
|
||||||
#### ts - js - node
|
|
||||||
|
#### ts - js - node
|
||||||
- [Einstieg in JavaScript-Dialekte und TypeScript-Konfiguration](dokus/js-ts/js-ts-dialekte.md)
|
|
||||||
|
- [Einstieg in JavaScript-Dialekte und TypeScript-Konfiguration](dokus/js-ts/js-ts-dialekte.md)
|
||||||
---
|
|
||||||
|
---
|
||||||
## Projektinhalt
|
|
||||||
|
## Projektinhalt
|
||||||
*Erstellt mit [treescanner](https://github.com/realAscot/treeScanner)*
|
|
||||||
|
*Erstellt mit [treescanner](https://github.com/realAscot/treeScanner)*
|
||||||
```plaintext
|
|
||||||
📁 ./
|
```plaintext
|
||||||
├── 📁 dokus
|
📁 ./
|
||||||
│ ├── 📁 apache-plesk
|
├── 📁 dokus
|
||||||
│ │ └── 📄 lets-encrypt-plesk.md
|
│ ├── 📁 apache-plesk
|
||||||
│ ├── 📁 asciidoc
|
│ │ └── 📄 lets-encrypt-plesk.md
|
||||||
│ │ └── 📄 asciidoctor-theme-bug-workaround.md
|
│ ├── 📁 asciidoc
|
||||||
│ ├── 📁 git
|
│ │ └── 📄 asciidoctor-theme-bug-workaround.md
|
||||||
│ │ ├── 📄 git-remote-branch.md
|
│ ├── 📁 git
|
||||||
│ │ ├── 📄 git-ssh-remote.md
|
│ │ ├── 📄 git-remote-branch.md
|
||||||
│ │ ├── 📄 git-submodule-leitfaden.md
|
│ │ ├── 📄 git-ssh-remote.md
|
||||||
│ │ └── 📄 git.md
|
│ │ ├── 📄 git-submodule-leitfaden.md
|
||||||
│ ├── 📁 js-ts
|
│ │ └── 📄 git.md
|
||||||
│ │ └── 📄 js-ts-dialekte.md
|
│ ├── 📁 js-ts
|
||||||
│ ├── 📁 mechanik
|
│ │ └── 📄 js-ts-dialekte.md
|
||||||
│ │ └── 📄 gewindetabellen.md
|
│ ├── 📁 mechanik
|
||||||
│ ├── 📁 plesk
|
│ │ └── 📄 gewindetabellen.md
|
||||||
│ │ └── 📄 plesk-benutzer-schon-vorhanden.md
|
│ ├── 📁 plesk
|
||||||
│ ├── 📁 rust
|
│ │ └── 📄 plesk-benutzer-schon-vorhanden.md
|
||||||
│ │ ├── 📄 rust-offline-installation.md
|
│ ├── 📁 rust
|
||||||
│ │ └── 📄 rust-toolchain-msvc.md
|
│ │ ├── 📄 rust-offline-installation.md
|
||||||
│ ├── 📁 windows
|
│ │ └── 📄 rust-toolchain-msvc.md
|
||||||
│ │ └── 📄 desktop_ini.md
|
│ ├── 📁 windows
|
||||||
│ └── 📄 helix__editor_einfuehrung_de.md
|
│ │ └── 📄 desktop_ini.md
|
||||||
├── 📁 media
|
│ └── 📄 helix__editor_einfuehrung_de.md
|
||||||
│ └── 📄 realAscotLogo_128x128.png
|
├── 📁 media
|
||||||
├── 📁 tools
|
│ └── 📄 realAscotLogo_128x128.png
|
||||||
│ ├── 📁 collector
|
├── 📁 tools
|
||||||
│ │ ├── 📄 config.jsonc
|
│ ├── 📁 collector
|
||||||
│ │ ├── 📄 link_collector.js
|
│ │ ├── 📄 config.jsonc
|
||||||
│ │ ├── 📄 link_collector.py
|
│ │ ├── 📄 link_collector.js
|
||||||
│ │ └── 📄 processed.log
|
│ │ ├── 📄 link_collector.py
|
||||||
│ ├── 📁 dist
|
│ │ └── 📄 processed.log
|
||||||
│ │ ├── 📁 collector
|
│ ├── 📁 dist
|
||||||
│ │ ├── 📄 fscopy.js
|
│ │ ├── 📁 collector
|
||||||
│ │ └── 📄 fsdel.js
|
│ │ ├── 📄 fscopy.js
|
||||||
│ └── 📁 src
|
│ │ └── 📄 fsdel.js
|
||||||
│ ├── 📁 collector
|
│ └── 📁 src
|
||||||
│ │ ├── 📄 config.jsonc.template
|
│ ├── 📁 collector
|
||||||
│ │ └── 📄 link_collector.ts
|
│ │ ├── 📄 config.jsonc.template
|
||||||
│ ├── 📄 fscopy.ts
|
│ │ └── 📄 link_collector.ts
|
||||||
│ └── 📄 fsdel.ts
|
│ ├── 📄 fscopy.ts
|
||||||
├── 📄 .gitignore
|
│ └── 📄 fsdel.ts
|
||||||
├── 📄 CHANGELOG.md
|
├── 📄 .gitignore
|
||||||
├── 📄 LICENSE
|
├── 📄 CHANGELOG.md
|
||||||
├── 📄 package-lock.json
|
├── 📄 LICENSE
|
||||||
├── 📄 package.json
|
├── 📄 package-lock.json
|
||||||
├── 📄 README.md
|
├── 📄 package.json
|
||||||
├── 📄 scan.cmd
|
├── 📄 README.md
|
||||||
├── 📄 tsconfig.json
|
├── 📄 scan.cmd
|
||||||
└── 📄 VERSION
|
├── 📄 tsconfig.json
|
||||||
```
|
└── 📄 VERSION
|
||||||
|
```
|
||||||
---
|
|
||||||
|
---
|
||||||
## Neue Dokumente
|
|
||||||
|
## Neue Dokumente
|
||||||
> führe `scan.cmd` oder [`link_collector.py`](./tools/collector/link_collector.py) oder `npm run scan` aus um nach neuen Dateien zu suchen!
|
|
||||||
|
> führe `scan.cmd` oder [`link_collector.py`](./tools/collector/link_collector.py) oder `npm run scan` aus um nach neuen Dateien zu suchen!
|
||||||
**NEUE EINTRÄGE AUS 'link_collector'->**
|
|
||||||
|
**NEUE EINTRÄGE AUS 'link_collector'->**
|
||||||
|
|
||||||
|
---
|
||||||
|
@ -1,82 +1,82 @@
|
|||||||
# Asciidoctor PDF: Kapitel bleibt „Chapter“ – Fehleranalyse & Workaround
|
# Asciidoctor PDF: Kapitel bleibt „Chapter“ – Fehleranalyse & Workaround
|
||||||
|
|
||||||
## 🧩 Problem
|
## 🧩 Problem
|
||||||
|
|
||||||
Beim Generieren von PDFs mit `asciidoctor-pdf` (Version 2.3.19) wird die Kapitelüberschrift trotz korrekt gesetztem deutschen Theme und Sprache **nicht lokalisiert**:
|
Beim Generieren von PDFs mit `asciidoctor-pdf` (Version 2.3.19) wird die Kapitelüberschrift trotz korrekt gesetztem deutschen Theme und Sprache **nicht lokalisiert**:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Chapter 1. Einführung
|
Chapter 1. Einführung
|
||||||
```
|
```
|
||||||
|
|
||||||
…statt:
|
…statt:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Kapitel 1. Einführung
|
Kapitel 1. Einführung
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✅ Erwartete Konfiguration
|
## ✅ Erwartete Konfiguration
|
||||||
|
|
||||||
Folgendes wurde korrekt gesetzt:
|
Folgendes wurde korrekt gesetzt:
|
||||||
|
|
||||||
- `chapter.title: "Kapitel {counter:chapter-number}. "` im Theme
|
- `chapter.title: "Kapitel {counter:chapter-number}. "` im Theme
|
||||||
- `locale: lang` im Theme
|
- `locale: lang` im Theme
|
||||||
- Fonts korrekt eingebunden
|
- Fonts korrekt eingebunden
|
||||||
- `:lang: de` entfernt aus `.adoc` (zur Sicherheit)
|
- `:lang: de` entfernt aus `.adoc` (zur Sicherheit)
|
||||||
- Keine `de.yml` verwendet
|
- Keine `de.yml` verwendet
|
||||||
- Keine Snap-Version oder Paketkonflikte
|
- Keine Snap-Version oder Paketkonflikte
|
||||||
- Theme definitiv geladen (`font_size`, `base`, etc. wirksam)
|
- Theme definitiv geladen (`font_size`, `base`, etc. wirksam)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ❌ Ergebnis
|
## ❌ Ergebnis
|
||||||
|
|
||||||
Trotz aller Korrektheit:
|
Trotz aller Korrektheit:
|
||||||
|
|
||||||
- Ausgabe bleibt auf Englisch
|
- Ausgabe bleibt auf Englisch
|
||||||
- Lokalisierung über Theme wird ignoriert
|
- Lokalisierung über Theme wird ignoriert
|
||||||
- Das Verhalten ist **reproduzierbar auf mehreren Rechnern und Installationen**
|
- Das Verhalten ist **reproduzierbar auf mehreren Rechnern und Installationen**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧨 Vermutete Ursache
|
## 🧨 Vermutete Ursache
|
||||||
|
|
||||||
Ein Bug oder ein Regressionseffekt in `asciidoctor-pdf` ab Version `2.3.0`, bei dem:
|
Ein Bug oder ein Regressionseffekt in `asciidoctor-pdf` ab Version `2.3.0`, bei dem:
|
||||||
|
|
||||||
- entweder `chapter.title` aus Theme nicht mehr greift
|
- entweder `chapter.title` aus Theme nicht mehr greift
|
||||||
- oder durch eine andere Sprachverarbeitung überschrieben wird
|
- oder durch eine andere Sprachverarbeitung überschrieben wird
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✅ Workaround
|
## ✅ Workaround
|
||||||
|
|
||||||
Statt auf automatische Kapitelüberschriften zu setzen, diese manuell überschreiben:
|
Statt auf automatische Kapitelüberschriften zu setzen, diese manuell überschreiben:
|
||||||
|
|
||||||
### Im `.adoc`:
|
### Im `.adoc`:
|
||||||
|
|
||||||
```asciidoc
|
```asciidoc
|
||||||
:sectnums!:
|
:sectnums!:
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
== Kapitel 1. Einführung
|
== Kapitel 1. Einführung
|
||||||
```
|
```
|
||||||
|
|
||||||
→ So wird die Kapitelzeile manuell gesetzt und `sectnums` deaktiviert.
|
→ So wird die Kapitelzeile manuell gesetzt und `sectnums` deaktiviert.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📌 Empfehlung
|
## 📌 Empfehlung
|
||||||
|
|
||||||
- In Projekten mit PDF-Export: Immer testen, ob `theme.yml` wirklich angewendet wird
|
- In Projekten mit PDF-Export: Immer testen, ob `theme.yml` wirklich angewendet wird
|
||||||
- Optional: eigene `make test-theme` Ziel im Makefile zur Überprüfung einbauen
|
- Optional: eigene `make test-theme` Ziel im Makefile zur Überprüfung einbauen
|
||||||
- Bis Bug behoben ist: Kapitel manuell beschriften oder alternative Engine verwenden
|
- Bis Bug behoben ist: Kapitel manuell beschriften oder alternative Engine verwenden
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔗 Betroffene Versionen
|
## 🔗 Betroffene Versionen
|
||||||
|
|
||||||
- `asciidoctor-pdf 2.3.19`
|
- `asciidoctor-pdf 2.3.19`
|
||||||
- `asciidoctor 2.0.23`
|
- `asciidoctor 2.0.23`
|
||||||
- `ruby 3.1.x`
|
- `ruby 3.1.x`
|
||||||
- UTF-8 / Linux / WSL – identisches Verhalten
|
- UTF-8 / Linux / WSL – identisches Verhalten
|
||||||
|
@ -1,162 +1,162 @@
|
|||||||
# Git – Remote-Branches: Häufige Aufgaben und Lösungen
|
# Git – Remote-Branches: Häufige Aufgaben und Lösungen
|
||||||
|
|
||||||
**Stand:** 2025-05-26
|
**Stand:** 2025-05-26
|
||||||
|
|
||||||
> Diese Anleitung erklärt, wie man mit Remote-Branches arbeitet – insbesondere dann, wenn der Branch lokal noch nicht existiert oder gezielt ressourcenschonend gearbeitet werden soll.
|
> Diese Anleitung erklärt, wie man mit Remote-Branches arbeitet – insbesondere dann, wenn der Branch lokal noch nicht existiert oder gezielt ressourcenschonend gearbeitet werden soll.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📌 Inhalt
|
## 📌 Inhalt
|
||||||
|
|
||||||
- [Git – Remote-Branches: Häufige Aufgaben und Lösungen](#git--remote-branches-häufige-aufgaben-und-lösungen)
|
- [Git – Remote-Branches: Häufige Aufgaben und Lösungen](#git--remote-branches-häufige-aufgaben-und-lösungen)
|
||||||
- [📌 Inhalt](#-inhalt)
|
- [📌 Inhalt](#-inhalt)
|
||||||
- [❓ 1. Wie hole ich einen Remote-Branch, den ich lokal noch nicht habe?](#-1-wie-hole-ich-einen-remote-branch-den-ich-lokal-noch-nicht-habe)
|
- [❓ 1. Wie hole ich einen Remote-Branch, den ich lokal noch nicht habe?](#-1-wie-hole-ich-einen-remote-branch-den-ich-lokal-noch-nicht-habe)
|
||||||
- [❓ 2. Warum sehe ich den Remote-Branch nicht in `git branch -r`?](#-2-warum-sehe-ich-den-remote-branch-nicht-in-git-branch--r)
|
- [❓ 2. Warum sehe ich den Remote-Branch nicht in `git branch -r`?](#-2-warum-sehe-ich-den-remote-branch-nicht-in-git-branch--r)
|
||||||
- [❓ 3. Holt `git clone` automatisch alle Branches?](#-3-holt-git-clone-automatisch-alle-branches)
|
- [❓ 3. Holt `git clone` automatisch alle Branches?](#-3-holt-git-clone-automatisch-alle-branches)
|
||||||
- [❓ 4. Wie klone ich gezielt nur einen bestimmten Branch?](#-4-wie-klone-ich-gezielt-nur-einen-bestimmten-branch)
|
- [❓ 4. Wie klone ich gezielt nur einen bestimmten Branch?](#-4-wie-klone-ich-gezielt-nur-einen-bestimmten-branch)
|
||||||
- [❓ 5. Wann ist `--single-branch` sinnvoll?](#-5-wann-ist---single-branch-sinnvoll)
|
- [❓ 5. Wann ist `--single-branch` sinnvoll?](#-5-wann-ist---single-branch-sinnvoll)
|
||||||
- [❓ 6. Wie sehe ich alle Remote-Branches **vor** dem Clonen?](#-6-wie-sehe-ich-alle-remote-branches-vor-dem-clonen)
|
- [❓ 6. Wie sehe ich alle Remote-Branches **vor** dem Clonen?](#-6-wie-sehe-ich-alle-remote-branches-vor-dem-clonen)
|
||||||
- [🛠️ Optionaler Alias-Tipp](#️-optionaler-alias-tipp)
|
- [🛠️ Optionaler Alias-Tipp](#️-optionaler-alias-tipp)
|
||||||
- [🧠 Zusammenfassung](#-zusammenfassung)
|
- [🧠 Zusammenfassung](#-zusammenfassung)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ❓ 1. Wie hole ich einen Remote-Branch, den ich lokal noch nicht habe?
|
## ❓ 1. Wie hole ich einen Remote-Branch, den ich lokal noch nicht habe?
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git fetch
|
git fetch
|
||||||
git checkout -b <lokaler-name> origin/<remote-branch>
|
git checkout -b <lokaler-name> origin/<remote-branch>
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternativ automatisch als Tracking-Branch:
|
Alternativ automatisch als Tracking-Branch:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git checkout --track origin/<remote-branch>
|
git checkout --track origin/<remote-branch>
|
||||||
```
|
```
|
||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git checkout --track origin/feature/chat-system
|
git checkout --track origin/feature/chat-system
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ❓ 2. Warum sehe ich den Remote-Branch nicht in `git branch -r`?
|
## ❓ 2. Warum sehe ich den Remote-Branch nicht in `git branch -r`?
|
||||||
|
|
||||||
`git branch -r` zeigt nur die lokal bekannten Remote-Refs.
|
`git branch -r` zeigt nur die lokal bekannten Remote-Refs.
|
||||||
Du musst vorher `git fetch` ausführen:
|
Du musst vorher `git fetch` ausführen:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git fetch
|
git fetch
|
||||||
git branch -r
|
git branch -r
|
||||||
```
|
```
|
||||||
|
|
||||||
Optional: erzwungen alles holen:
|
Optional: erzwungen alles holen:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git fetch origin '+refs/heads/*:refs/remotes/origin/*'
|
git fetch origin '+refs/heads/*:refs/remotes/origin/*'
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ❓ 3. Holt `git clone` automatisch alle Branches?
|
## ❓ 3. Holt `git clone` automatisch alle Branches?
|
||||||
|
|
||||||
**Nicht ganz.** `git clone`:
|
**Nicht ganz.** `git clone`:
|
||||||
|
|
||||||
- ✅ holt alle Branches als Referenzen
|
- ✅ holt alle Branches als Referenzen
|
||||||
- ❌ checkt nur den Standard-Branch (z. B. `main`) lokal aus
|
- ❌ checkt nur den Standard-Branch (z. B. `main`) lokal aus
|
||||||
|
|
||||||
**Weitere Branches** müssen manuell ausgecheckt werden:
|
**Weitere Branches** müssen manuell ausgecheckt werden:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git checkout --track origin/<branch-name>
|
git checkout --track origin/<branch-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
Optional zur Sicherheit vorher:
|
Optional zur Sicherheit vorher:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git fetch
|
git fetch
|
||||||
git branch -r
|
git branch -r
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ❓ 4. Wie klone ich gezielt nur einen bestimmten Branch?
|
## ❓ 4. Wie klone ich gezielt nur einen bestimmten Branch?
|
||||||
|
|
||||||
Nur den gewünschten Branch klonen (kein anderer wird geholt):
|
Nur den gewünschten Branch klonen (kein anderer wird geholt):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone --branch <branch-name> --single-branch <repo-url>
|
git clone --branch <branch-name> --single-branch <repo-url>
|
||||||
```
|
```
|
||||||
|
|
||||||
Mit reduziertem Verlauf (nur letzte Commits):
|
Mit reduziertem Verlauf (nur letzte Commits):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone --branch <branch-name> --single-branch --depth 1 <repo-url>
|
git clone --branch <branch-name> --single-branch --depth 1 <repo-url>
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ❓ 5. Wann ist `--single-branch` sinnvoll?
|
## ❓ 5. Wann ist `--single-branch` sinnvoll?
|
||||||
|
|
||||||
Diese Variante ist ideal, wenn:
|
Diese Variante ist ideal, wenn:
|
||||||
|
|
||||||
- du **nur an einem Branch arbeiten** willst
|
- du **nur an einem Branch arbeiten** willst
|
||||||
- du **Platz oder Zeit sparen** möchtest
|
- du **Platz oder Zeit sparen** möchtest
|
||||||
- du das Repo **später einfach löschen** willst
|
- du das Repo **später einfach löschen** willst
|
||||||
- du z. B. in **CI/CD**, **Docker**, **VMs** oder **temporär lokal** arbeitest
|
- du z. B. in **CI/CD**, **Docker**, **VMs** oder **temporär lokal** arbeitest
|
||||||
|
|
||||||
Sie vermeidet unnötige Daten und beschleunigt den Clone-Prozess.
|
Sie vermeidet unnötige Daten und beschleunigt den Clone-Prozess.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ❓ 6. Wie sehe ich alle Remote-Branches **vor** dem Clonen?
|
## ❓ 6. Wie sehe ich alle Remote-Branches **vor** dem Clonen?
|
||||||
|
|
||||||
Du kannst dir **alle Branches am Remote-Repo anzeigen lassen**, ohne zu klonen:
|
Du kannst dir **alle Branches am Remote-Repo anzeigen lassen**, ohne zu klonen:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git ls-remote --heads <repo-url>
|
git ls-remote --heads <repo-url>
|
||||||
```
|
```
|
||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git ls-remote --heads ssh://git@local.ionivation.com:2222/codewalker/codewalker.net.git
|
git ls-remote --heads ssh://git@local.ionivation.com:2222/codewalker/codewalker.net.git
|
||||||
```
|
```
|
||||||
|
|
||||||
Ergebnis:
|
Ergebnis:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
f3a91d... refs/heads/main
|
f3a91d... refs/heads/main
|
||||||
c4bd79... refs/heads/feature/chat-system
|
c4bd79... refs/heads/feature/chat-system
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🛠️ Optionaler Alias-Tipp
|
## 🛠️ Optionaler Alias-Tipp
|
||||||
|
|
||||||
Wenn du häufig neue Branches holen willst:
|
Wenn du häufig neue Branches holen willst:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git config --global alias.fr 'fetch && branch -r'
|
git config --global alias.fr 'fetch && branch -r'
|
||||||
```
|
```
|
||||||
|
|
||||||
Verwendung:
|
Verwendung:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git fr
|
git fr
|
||||||
```
|
```
|
||||||
|
|
||||||
= `git fetch` + Anzeige aller Remote-Branches
|
= `git fetch` + Anzeige aller Remote-Branches
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧠 Zusammenfassung
|
## 🧠 Zusammenfassung
|
||||||
|
|
||||||
| Ziel | Befehl |
|
| Ziel | Befehl |
|
||||||
|-------------------------------------|------------------------------------------------------|
|
|-------------------------------------|------------------------------------------------------|
|
||||||
| Remote-Branch holen + auschecken | `git fetch` + `git checkout --track origin/<name>` |
|
| Remote-Branch holen + auschecken | `git fetch` + `git checkout --track origin/<name>` |
|
||||||
| Nur einen Branch klonen | `git clone --branch <name> --single-branch <url>` |
|
| Nur einen Branch klonen | `git clone --branch <name> --single-branch <url>` |
|
||||||
| Branchliste ohne Clone anzeigen | `git ls-remote --heads <repo-url>` |
|
| Branchliste ohne Clone anzeigen | `git ls-remote --heads <repo-url>` |
|
||||||
| Lokale Sichtbarkeit Remote-Branches | `git fetch` + `git branch -r` |
|
| Lokale Sichtbarkeit Remote-Branches | `git fetch` + `git branch -r` |
|
||||||
|
@ -1,194 +1,194 @@
|
|||||||
# SSH-Zugriff auf Git-Repository in WSL einrichten
|
# SSH-Zugriff auf Git-Repository in WSL einrichten
|
||||||
|
|
||||||
Diese Anleitung beschreibt, wie man innerhalb von WSL (z. B. Ubuntu) ein Git-Repository per SSH nutzen kann, z. B. bei einem selbst gehosteten Gitea-Server auf `dns.lan` mit Port `2222`.
|
Diese Anleitung beschreibt, wie man innerhalb von WSL (z. B. Ubuntu) ein Git-Repository per SSH nutzen kann, z. B. bei einem selbst gehosteten Gitea-Server auf `dns.lan` mit Port `2222`.
|
||||||
|
|
||||||
- [SSH-Zugriff auf Git-Repository in WSL einrichten](#ssh-zugriff-auf-git-repository-in-wsl-einrichten)
|
- [SSH-Zugriff auf Git-Repository in WSL einrichten](#ssh-zugriff-auf-git-repository-in-wsl-einrichten)
|
||||||
- [🔧 Voraussetzungen](#-voraussetzungen)
|
- [🔧 Voraussetzungen](#-voraussetzungen)
|
||||||
- [🧱 Schritt 1: SSH-Verzeichnis in WSL anlegen](#-schritt-1-ssh-verzeichnis-in-wsl-anlegen)
|
- [🧱 Schritt 1: SSH-Verzeichnis in WSL anlegen](#-schritt-1-ssh-verzeichnis-in-wsl-anlegen)
|
||||||
- [🗝️ Schritt 2: SSH-Schlüssel aus Windows in WSL übernehmen](#️-schritt-2-ssh-schlüssel-aus-windows-in-wsl-übernehmen)
|
- [🗝️ Schritt 2: SSH-Schlüssel aus Windows in WSL übernehmen](#️-schritt-2-ssh-schlüssel-aus-windows-in-wsl-übernehmen)
|
||||||
- [⚙️ Schritt 3: SSH-Konfiguration (optional, empfohlen)](#️-schritt-3-ssh-konfiguration-optional-empfohlen)
|
- [⚙️ Schritt 3: SSH-Konfiguration (optional, empfohlen)](#️-schritt-3-ssh-konfiguration-optional-empfohlen)
|
||||||
- [🧪 Schritt 4: Verbindung testen](#-schritt-4-verbindung-testen)
|
- [🧪 Schritt 4: Verbindung testen](#-schritt-4-verbindung-testen)
|
||||||
- [🐙 Schritt 5: Git-Remote setzen oder klonen](#-schritt-5-git-remote-setzen-oder-klonen)
|
- [🐙 Schritt 5: Git-Remote setzen oder klonen](#-schritt-5-git-remote-setzen-oder-klonen)
|
||||||
- [✅ Bestehendes Repo umstellen](#-bestehendes-repo-umstellen)
|
- [✅ Bestehendes Repo umstellen](#-bestehendes-repo-umstellen)
|
||||||
- [✅ Neues Repo klonen](#-neues-repo-klonen)
|
- [✅ Neues Repo klonen](#-neues-repo-klonen)
|
||||||
- [🛡️ Hinweis: Keine Shell-Zugänge über Git-SSH](#️-hinweis-keine-shell-zugänge-über-git-ssh)
|
- [🛡️ Hinweis: Keine Shell-Zugänge über Git-SSH](#️-hinweis-keine-shell-zugänge-über-git-ssh)
|
||||||
- [✅ Fertig](#-fertig)
|
- [✅ Fertig](#-fertig)
|
||||||
- [🔁 Optional: Globale Git-Konfiguration absichern](#-optional-globale-git-konfiguration-absichern)
|
- [🔁 Optional: Globale Git-Konfiguration absichern](#-optional-globale-git-konfiguration-absichern)
|
||||||
- [🔑 SSH-Key unter WSL erzeugen](#-ssh-key-unter-wsl-erzeugen)
|
- [🔑 SSH-Key unter WSL erzeugen](#-ssh-key-unter-wsl-erzeugen)
|
||||||
- [🛠️ Voraussetzungen installieren](#️-voraussetzungen-installieren)
|
- [🛠️ Voraussetzungen installieren](#️-voraussetzungen-installieren)
|
||||||
- [🔐 SSH-Key erzeugen](#-ssh-key-erzeugen)
|
- [🔐 SSH-Key erzeugen](#-ssh-key-erzeugen)
|
||||||
- [⌨️ Bei der Abfrage:](#️-bei-der-abfrage)
|
- [⌨️ Bei der Abfrage:](#️-bei-der-abfrage)
|
||||||
- [🔍 Public Key anzeigen](#-public-key-anzeigen)
|
- [🔍 Public Key anzeigen](#-public-key-anzeigen)
|
||||||
- [✅ Optional: SSH-Agent starten \& Schlüssel hinzufügen](#-optional-ssh-agent-starten--schlüssel-hinzufügen)
|
- [✅ Optional: SSH-Agent starten \& Schlüssel hinzufügen](#-optional-ssh-agent-starten--schlüssel-hinzufügen)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔧 Voraussetzungen
|
## 🔧 Voraussetzungen
|
||||||
|
|
||||||
- WSL ist eingerichtet (z. B. Ubuntu)
|
- WSL ist eingerichtet (z. B. Ubuntu)
|
||||||
- Ein Git-Server ist erreichbar (z. B. `git@dns.lan:2222`)
|
- Ein Git-Server ist erreichbar (z. B. `git@dns.lan:2222`)
|
||||||
- Du hast bereits Zugriff über Windows (z. B. via PowerShell)
|
- Du hast bereits Zugriff über Windows (z. B. via PowerShell)
|
||||||
- OpenSSH ist in der WSL-Distribution installiert
|
- OpenSSH ist in der WSL-Distribution installiert
|
||||||
- Wenn Du noch keinen Key hast oder einen neuen einrichten möchtest, gibt es unten unter [🔑 SSH-Key unter WSL erzeugen](#-ssh-key-unter-wsl-erzeugen) nochmal eine Auffrischung.
|
- Wenn Du noch keinen Key hast oder einen neuen einrichten möchtest, gibt es unten unter [🔑 SSH-Key unter WSL erzeugen](#-ssh-key-unter-wsl-erzeugen) nochmal eine Auffrischung.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧱 Schritt 1: SSH-Verzeichnis in WSL anlegen
|
## 🧱 Schritt 1: SSH-Verzeichnis in WSL anlegen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p ~/.ssh
|
mkdir -p ~/.ssh
|
||||||
chmod 700 ~/.ssh
|
chmod 700 ~/.ssh
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🗝️ Schritt 2: SSH-Schlüssel aus Windows in WSL übernehmen
|
## 🗝️ Schritt 2: SSH-Schlüssel aus Windows in WSL übernehmen
|
||||||
|
|
||||||
Falls du in Windows bereits einen Schlüssel hast, z. B. `C:\Users\NAME\.ssh\id_ed25519`, kopiere ihn:
|
Falls du in Windows bereits einen Schlüssel hast, z. B. `C:\Users\NAME\.ssh\id_ed25519`, kopiere ihn:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp /mnt/c/Users/NAME/.ssh/id_ed25519 ~/.ssh/
|
cp /mnt/c/Users/NAME/.ssh/id_ed25519 ~/.ssh/
|
||||||
cp /mnt/c/Users/NAME/.ssh/id_ed25519.pub ~/.ssh/
|
cp /mnt/c/Users/NAME/.ssh/id_ed25519.pub ~/.ssh/
|
||||||
chmod 600 ~/.ssh/id_ed25519
|
chmod 600 ~/.ssh/id_ed25519
|
||||||
chmod 644 ~/.ssh/id_ed25519.pub
|
chmod 644 ~/.ssh/id_ed25519.pub
|
||||||
```
|
```
|
||||||
|
|
||||||
🔁 Ersetze `NAME` mit deinem Windows-Benutzernamen.
|
🔁 Ersetze `NAME` mit deinem Windows-Benutzernamen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⚙️ Schritt 3: SSH-Konfiguration (optional, empfohlen)
|
## ⚙️ Schritt 3: SSH-Konfiguration (optional, empfohlen)
|
||||||
|
|
||||||
Erstelle (oder bearbeite) die Datei `~/.ssh/config`:
|
Erstelle (oder bearbeite) die Datei `~/.ssh/config`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
nano ~/.ssh/config
|
nano ~/.ssh/config
|
||||||
```
|
```
|
||||||
|
|
||||||
Füge ein:
|
Füge ein:
|
||||||
|
|
||||||
```ssh
|
```ssh
|
||||||
Host gitea
|
Host gitea
|
||||||
HostName dns.lan
|
HostName dns.lan
|
||||||
Port 2222
|
Port 2222
|
||||||
User git
|
User git
|
||||||
IdentityFile ~/.ssh/id_ed25519
|
IdentityFile ~/.ssh/id_ed25519
|
||||||
```
|
```
|
||||||
|
|
||||||
→ Damit kannst du den Hostname `gitea` als Alias verwenden.
|
→ Damit kannst du den Hostname `gitea` als Alias verwenden.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧪 Schritt 4: Verbindung testen
|
## 🧪 Schritt 4: Verbindung testen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ssh -T gitea
|
ssh -T gitea
|
||||||
```
|
```
|
||||||
|
|
||||||
Erwartete Ausgabe:
|
Erwartete Ausgabe:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Hi there, realAscot! You've successfully authenticated...
|
Hi there, realAscot! You've successfully authenticated...
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🐙 Schritt 5: Git-Remote setzen oder klonen
|
## 🐙 Schritt 5: Git-Remote setzen oder klonen
|
||||||
|
|
||||||
### ✅ Bestehendes Repo umstellen
|
### ✅ Bestehendes Repo umstellen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git remote set-url origin gitea:realAscot/mein-projekt.git
|
git remote set-url origin gitea:realAscot/mein-projekt.git
|
||||||
```
|
```
|
||||||
|
|
||||||
### ✅ Neues Repo klonen
|
### ✅ Neues Repo klonen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone gitea:realAscot/mein-projekt.git
|
git clone gitea:realAscot/mein-projekt.git
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🛡️ Hinweis: Keine Shell-Zugänge über Git-SSH
|
## 🛡️ Hinweis: Keine Shell-Zugänge über Git-SSH
|
||||||
|
|
||||||
Wenn du folgende Meldung siehst:
|
Wenn du folgende Meldung siehst:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
You've successfully authenticated, but Gitea does not provide shell access.
|
You've successfully authenticated, but Gitea does not provide shell access.
|
||||||
```
|
```
|
||||||
|
|
||||||
→ Das ist normal und **kein Fehler** – Push/Pull funktioniert trotzdem.
|
→ Das ist normal und **kein Fehler** – Push/Pull funktioniert trotzdem.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✅ Fertig
|
## ✅ Fertig
|
||||||
|
|
||||||
Du kannst jetzt in WSL wie gewohnt per SSH arbeiten:
|
Du kannst jetzt in WSL wie gewohnt per SSH arbeiten:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git pull
|
git pull
|
||||||
git push
|
git push
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔁 Optional: Globale Git-Konfiguration absichern
|
## 🔁 Optional: Globale Git-Konfiguration absichern
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git config --global core.autocrlf input
|
git config --global core.autocrlf input
|
||||||
git config --global core.eol lf
|
git config --global core.eol lf
|
||||||
```
|
```
|
||||||
|
|
||||||
Damit vermeidest du Konflikte durch Windows-Zeilenenden.
|
Damit vermeidest du Konflikte durch Windows-Zeilenenden.
|
||||||
Hat mit dem SSH Key jetzt nichts zu tun, aber ein kleiner Tipp nebenbei um bekannte Fehler zu vermeiden.
|
Hat mit dem SSH Key jetzt nichts zu tun, aber ein kleiner Tipp nebenbei um bekannte Fehler zu vermeiden.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔑 SSH-Key unter WSL erzeugen
|
## 🔑 SSH-Key unter WSL erzeugen
|
||||||
|
|
||||||
Hier ist eine kompakte Anleitung in **Markdown**, wie du unter **WSL** (z. B. Ubuntu) einen SSH-Key erzeugst und die nötigen Tools installierst, um z. B. Gitea-Zugriff zu ermöglichen.
|
Hier ist eine kompakte Anleitung in **Markdown**, wie du unter **WSL** (z. B. Ubuntu) einen SSH-Key erzeugst und die nötigen Tools installierst, um z. B. Gitea-Zugriff zu ermöglichen.
|
||||||
|
|
||||||
### 🛠️ Voraussetzungen installieren
|
### 🛠️ Voraussetzungen installieren
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install -y openssh-client
|
sudo apt install -y openssh-client
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🔐 SSH-Key erzeugen
|
### 🔐 SSH-Key erzeugen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ssh-keygen -t ed25519 -C "dein.name@example.com" -f ~/.ssh/id_ed25519_gitea
|
ssh-keygen -t ed25519 -C "dein.name@example.com" -f ~/.ssh/id_ed25519_gitea
|
||||||
```
|
```
|
||||||
|
|
||||||
Der Parameter `-f` gibt den Pfad und Namen des neuen Keys an.
|
Der Parameter `-f` gibt den Pfad und Namen des neuen Keys an.
|
||||||
Wenn man diesen weglässt, überschreibst Du Dir eventuell einen schon vorhandenen Key den Du vielleicht für etwas anderes nutzt!
|
Wenn man diesen weglässt, überschreibst Du Dir eventuell einen schon vorhandenen Key den Du vielleicht für etwas anderes nutzt!
|
||||||
Du wirst dann aber je nach Version nach einem Pfad gefragt.
|
Du wirst dann aber je nach Version nach einem Pfad gefragt.
|
||||||
Besser direkt angeben.
|
Besser direkt angeben.
|
||||||
|
|
||||||
- **Erklärung:**
|
- **Erklärung:**
|
||||||
|
|
||||||
- `-t ed25519`: moderner, sicherer Algorithmus
|
- `-t ed25519`: moderner, sicherer Algorithmus
|
||||||
- `-C`: Kommentar (z. B. Mailadresse oder Systembeschreibung)
|
- `-C`: Kommentar (z. B. Mailadresse oder Systembeschreibung)
|
||||||
|
|
||||||
#### ⌨️ Bei der Abfrage:
|
#### ⌨️ Bei der Abfrage:
|
||||||
|
|
||||||
- **Dateipfad**: einfach Enter drücken für Standard (`~/.ssh/id_ed25519_gitea`)
|
- **Dateipfad**: einfach Enter drücken für Standard (`~/.ssh/id_ed25519_gitea`)
|
||||||
- **Passphrase**: optional, aber empfohlen (für zusätzliche Sicherheit)
|
- **Passphrase**: optional, aber empfohlen (für zusätzliche Sicherheit)
|
||||||
|
|
||||||
### 🔍 Public Key anzeigen
|
### 🔍 Public Key anzeigen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cat ~/.ssh/id_ed25519_gitea.pub
|
cat ~/.ssh/id_ed25519_gitea.pub
|
||||||
```
|
```
|
||||||
|
|
||||||
→ Diesen Schlüssel dann in **Gitea unter „SSH-Schlüssel“** einfügen.
|
→ Diesen Schlüssel dann in **Gitea unter „SSH-Schlüssel“** einfügen.
|
||||||
|
|
||||||
### ✅ Optional: SSH-Agent starten & Schlüssel hinzufügen
|
### ✅ Optional: SSH-Agent starten & Schlüssel hinzufügen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
eval "$(ssh-agent -s)"
|
eval "$(ssh-agent -s)"
|
||||||
ssh-add ~/.ssh/id_ed25519_gitea
|
ssh-add ~/.ssh/id_ed25519_gitea
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -1,203 +1,203 @@
|
|||||||
# Git-Submodule: Der umfassende Praxisleitfaden
|
# Git-Submodule: Der umfassende Praxisleitfaden
|
||||||
|
|
||||||
## Inhalt
|
## Inhalt
|
||||||
|
|
||||||
- [Git-Submodule: Der umfassende Praxisleitfaden](#git-submodule-der-umfassende-praxisleitfaden)
|
- [Git-Submodule: Der umfassende Praxisleitfaden](#git-submodule-der-umfassende-praxisleitfaden)
|
||||||
- [Inhalt](#inhalt)
|
- [Inhalt](#inhalt)
|
||||||
- [🔰 Was ist ein Git-Submodul?](#-was-ist-ein-git-submodul)
|
- [🔰 Was ist ein Git-Submodul?](#-was-ist-ein-git-submodul)
|
||||||
- [🧱 Grundlagen](#-grundlagen)
|
- [🧱 Grundlagen](#-grundlagen)
|
||||||
- [📌 `.gitmodules`](#-gitmodules)
|
- [📌 `.gitmodules`](#-gitmodules)
|
||||||
- [🧠 Merksatz](#-merksatz)
|
- [🧠 Merksatz](#-merksatz)
|
||||||
- [🛠️ Submodul hinzufügen](#️-submodul-hinzufügen)
|
- [🛠️ Submodul hinzufügen](#️-submodul-hinzufügen)
|
||||||
- [🔄 Submodule aktualisieren](#-submodule-aktualisieren)
|
- [🔄 Submodule aktualisieren](#-submodule-aktualisieren)
|
||||||
- [📥 Klonen mit Submodulen](#-klonen-mit-submodulen)
|
- [📥 Klonen mit Submodulen](#-klonen-mit-submodulen)
|
||||||
- [Methode 1: Inklusive Submodule](#methode-1-inklusive-submodule)
|
- [Methode 1: Inklusive Submodule](#methode-1-inklusive-submodule)
|
||||||
- [Methode 2: Nachträglich initialisieren](#methode-2-nachträglich-initialisieren)
|
- [Methode 2: Nachträglich initialisieren](#methode-2-nachträglich-initialisieren)
|
||||||
- [🔃 Submodul-Synchronisation](#-submodul-synchronisation)
|
- [🔃 Submodul-Synchronisation](#-submodul-synchronisation)
|
||||||
- [📂 Weitere Remotes im Submodul](#-weitere-remotes-im-submodul)
|
- [📂 Weitere Remotes im Submodul](#-weitere-remotes-im-submodul)
|
||||||
- [❗ Stolperfallen und Besonderheiten](#-stolperfallen-und-besonderheiten)
|
- [❗ Stolperfallen und Besonderheiten](#-stolperfallen-und-besonderheiten)
|
||||||
- [🔄 Remote-URL wechseln](#-remote-url-wechseln)
|
- [🔄 Remote-URL wechseln](#-remote-url-wechseln)
|
||||||
- [🚀 Push \& Pull Verhalten](#-push--pull-verhalten)
|
- [🚀 Push \& Pull Verhalten](#-push--pull-verhalten)
|
||||||
- [🧼 Submodul löschen](#-submodul-löschen)
|
- [🧼 Submodul löschen](#-submodul-löschen)
|
||||||
- [🧰 Best Practices](#-best-practices)
|
- [🧰 Best Practices](#-best-practices)
|
||||||
- [📎 Nützliche Kommandos](#-nützliche-kommandos)
|
- [📎 Nützliche Kommandos](#-nützliche-kommandos)
|
||||||
- [📑 Beispiel `.gitmodules` mit kommentierter Remote-Auswahl](#-beispiel-gitmodules-mit-kommentierter-remote-auswahl)
|
- [📑 Beispiel `.gitmodules` mit kommentierter Remote-Auswahl](#-beispiel-gitmodules-mit-kommentierter-remote-auswahl)
|
||||||
- [🧭 Alternative: Subtree statt Submodul?](#-alternative-subtree-statt-submodul)
|
- [🧭 Alternative: Subtree statt Submodul?](#-alternative-subtree-statt-submodul)
|
||||||
- [📚 Fazit](#-fazit)
|
- [📚 Fazit](#-fazit)
|
||||||
- [🔗 Weiterführende Links](#-weiterführende-links)
|
- [🔗 Weiterführende Links](#-weiterführende-links)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔰 Was ist ein Git-Submodul?
|
## 🔰 Was ist ein Git-Submodul?
|
||||||
|
|
||||||
Ein **Submodul** ist ein Git-Repository innerhalb eines anderen Git-Repositories. Es erlaubt, einen festen Commit eines externen Repositories als Teilprojekt einzubinden, ohne dessen Dateien direkt zu übernehmen.
|
Ein **Submodul** ist ein Git-Repository innerhalb eines anderen Git-Repositories. Es erlaubt, einen festen Commit eines externen Repositories als Teilprojekt einzubinden, ohne dessen Dateien direkt zu übernehmen.
|
||||||
|
|
||||||
Beispielhafte Struktur:
|
Beispielhafte Struktur:
|
||||||
|
|
||||||
```plaintext
|
```plaintext
|
||||||
hauptprojekt/
|
hauptprojekt/
|
||||||
├── .gitmodules
|
├── .gitmodules
|
||||||
├── modul1/ ← eingebundenes Submodul
|
├── modul1/ ← eingebundenes Submodul
|
||||||
└── modul2/
|
└── modul2/
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🧱 Grundlagen
|
## 🧱 Grundlagen
|
||||||
|
|
||||||
### 📌 `.gitmodules`
|
### 📌 `.gitmodules`
|
||||||
|
|
||||||
Diese Datei beschreibt Pfad und Remote-URL aller eingebundenen Submodule:
|
Diese Datei beschreibt Pfad und Remote-URL aller eingebundenen Submodule:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[submodule "modul1"]
|
[submodule "modul1"]
|
||||||
path = modul1
|
path = modul1
|
||||||
url = git@github.com:user/modul1.git
|
url = git@github.com:user/modul1.git
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🧠 Merksatz
|
### 🧠 Merksatz
|
||||||
|
|
||||||
> Submodule sind **Pointer auf einen bestimmten Commit** eines anderen Repositories.
|
> Submodule sind **Pointer auf einen bestimmten Commit** eines anderen Repositories.
|
||||||
|
|
||||||
## 🛠️ Submodul hinzufügen
|
## 🛠️ Submodul hinzufügen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git submodule add <repo-url> <zielpfad>
|
git submodule add <repo-url> <zielpfad>
|
||||||
git commit -m "📦 Submodul hinzugefügt"
|
git commit -m "📦 Submodul hinzugefügt"
|
||||||
```
|
```
|
||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git submodule add git@github.com:user/libmath.git extern/libmath
|
git submodule add git@github.com:user/libmath.git extern/libmath
|
||||||
```
|
```
|
||||||
|
|
||||||
Erzeugt:
|
Erzeugt:
|
||||||
|
|
||||||
- `.gitmodules`
|
- `.gitmodules`
|
||||||
- Verzeichniseintrag im Git-Index
|
- Verzeichniseintrag im Git-Index
|
||||||
- Initialer Checkout des Submoduls (HEAD auf Remote-Commit)
|
- Initialer Checkout des Submoduls (HEAD auf Remote-Commit)
|
||||||
|
|
||||||
## 🔄 Submodule aktualisieren
|
## 🔄 Submodule aktualisieren
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd extern/libmath
|
cd extern/libmath
|
||||||
git pull origin main
|
git pull origin main
|
||||||
cd ../..
|
cd ../..
|
||||||
git add extern/libmath
|
git add extern/libmath
|
||||||
git commit -m "🔄 Submodul libmath aktualisiert"
|
git commit -m "🔄 Submodul libmath aktualisiert"
|
||||||
```
|
```
|
||||||
|
|
||||||
> Nur das **Hauptrepo speichert den Commit-Zeiger**, nicht den Submodul-Inhalt selbst.
|
> Nur das **Hauptrepo speichert den Commit-Zeiger**, nicht den Submodul-Inhalt selbst.
|
||||||
|
|
||||||
## 📥 Klonen mit Submodulen
|
## 📥 Klonen mit Submodulen
|
||||||
|
|
||||||
### Methode 1: Inklusive Submodule
|
### Methode 1: Inklusive Submodule
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone --recurse-submodules <url>
|
git clone --recurse-submodules <url>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Methode 2: Nachträglich initialisieren
|
### Methode 2: Nachträglich initialisieren
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone <url>
|
git clone <url>
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🔃 Submodul-Synchronisation
|
## 🔃 Submodul-Synchronisation
|
||||||
|
|
||||||
Wenn sich `.gitmodules` ändert (z. B. Remote-URL):
|
Wenn sich `.gitmodules` ändert (z. B. Remote-URL):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git submodule sync
|
git submodule sync
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📂 Weitere Remotes im Submodul
|
## 📂 Weitere Remotes im Submodul
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd modul1
|
cd modul1
|
||||||
git remote add backup git@backup.server:repo.git
|
git remote add backup git@backup.server:repo.git
|
||||||
```
|
```
|
||||||
|
|
||||||
> Diese Remotes sind **lokal**, nicht versioniert. `.gitmodules` kennt nur den Haupt-Remote.
|
> Diese Remotes sind **lokal**, nicht versioniert. `.gitmodules` kennt nur den Haupt-Remote.
|
||||||
|
|
||||||
## ❗ Stolperfallen und Besonderheiten
|
## ❗ Stolperfallen und Besonderheiten
|
||||||
|
|
||||||
| Problem | Erklärung |
|
| Problem | Erklärung |
|
||||||
|--------|-----------|
|
|--------|-----------|
|
||||||
| Submodul wird nicht mitgeclont | `--recurse-submodules` vergessen |
|
| Submodul wird nicht mitgeclont | `--recurse-submodules` vergessen |
|
||||||
| Änderungen im Submodul nicht sichtbar | Submodul-Commit im Hauptrepo nicht geupdated |
|
| Änderungen im Submodul nicht sichtbar | Submodul-Commit im Hauptrepo nicht geupdated |
|
||||||
| `.gitmodules` zeigt nicht funktionierende URL | z. B. lokale URL nach GitHub-Push – muss angepasst werden |
|
| `.gitmodules` zeigt nicht funktionierende URL | z. B. lokale URL nach GitHub-Push – muss angepasst werden |
|
||||||
| Submodul zeigt „detached HEAD“ | normaler Zustand, wenn Submodul auf festen Commit gesetzt ist |
|
| Submodul zeigt „detached HEAD“ | normaler Zustand, wenn Submodul auf festen Commit gesetzt ist |
|
||||||
|
|
||||||
## 🔄 Remote-URL wechseln
|
## 🔄 Remote-URL wechseln
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# In .gitmodules ändern oder per Befehl:
|
# In .gitmodules ändern oder per Befehl:
|
||||||
git config -f .gitmodules submodule.modul1.url git@github.com:newuser/libmath.git
|
git config -f .gitmodules submodule.modul1.url git@github.com:newuser/libmath.git
|
||||||
git submodule sync
|
git submodule sync
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚀 Push & Pull Verhalten
|
## 🚀 Push & Pull Verhalten
|
||||||
|
|
||||||
| Aktion | Wirkung |
|
| Aktion | Wirkung |
|
||||||
|---------------------|---------|
|
|---------------------|---------|
|
||||||
| `git push` im Hauptrepo | Pusht nur Zeiger auf Submodul-Commit |
|
| `git push` im Hauptrepo | Pusht nur Zeiger auf Submodul-Commit |
|
||||||
| `git push` im Submodul | Muss separat erfolgen |
|
| `git push` im Submodul | Muss separat erfolgen |
|
||||||
| `git pull` im Hauptrepo | Holt *nicht* automatisch neuen Submodul-Stand |
|
| `git pull` im Hauptrepo | Holt *nicht* automatisch neuen Submodul-Stand |
|
||||||
|
|
||||||
## 🧼 Submodul löschen
|
## 🧼 Submodul löschen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Schritt 1: Entfernen
|
# Schritt 1: Entfernen
|
||||||
git submodule deinit -f pfad/zum/modul
|
git submodule deinit -f pfad/zum/modul
|
||||||
git rm -f pfad/zum/modul
|
git rm -f pfad/zum/modul
|
||||||
rm -rf .git/modules/pfad/zum/modul
|
rm -rf .git/modules/pfad/zum/modul
|
||||||
git commit -m "❌ Submodul entfernt"
|
git commit -m "❌ Submodul entfernt"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🧰 Best Practices
|
## 🧰 Best Practices
|
||||||
|
|
||||||
- **Nur stabile Submodul-Commits einchecken**, keine laufenden Branches.
|
- **Nur stabile Submodul-Commits einchecken**, keine laufenden Branches.
|
||||||
- **Submodule niemals blind aktualisieren** – Änderungen genau prüfen.
|
- **Submodule niemals blind aktualisieren** – Änderungen genau prüfen.
|
||||||
- **Remote-Umschaltung dokumentieren oder automatisieren**, z. B. per Script.
|
- **Remote-Umschaltung dokumentieren oder automatisieren**, z. B. per Script.
|
||||||
- **Submodule klein halten** – große, tief verschachtelte Strukturen vermeiden.
|
- **Submodule klein halten** – große, tief verschachtelte Strukturen vermeiden.
|
||||||
- Für wiederverwendbare Bibliotheken oder Assets ideal (CAD, Snippets, Markdown, etc.).
|
- Für wiederverwendbare Bibliotheken oder Assets ideal (CAD, Snippets, Markdown, etc.).
|
||||||
|
|
||||||
## 📎 Nützliche Kommandos
|
## 📎 Nützliche Kommandos
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git submodule status # Überblick über alle Submodule
|
git submodule status # Überblick über alle Submodule
|
||||||
git submodule update --init # Submodule initial holen
|
git submodule update --init # Submodule initial holen
|
||||||
git submodule update --remote # Auf neuesten Remote-Stand updaten
|
git submodule update --remote # Auf neuesten Remote-Stand updaten
|
||||||
git config -f .gitmodules ... # .gitmodules direkt bearbeiten
|
git config -f .gitmodules ... # .gitmodules direkt bearbeiten
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📑 Beispiel `.gitmodules` mit kommentierter Remote-Auswahl
|
## 📑 Beispiel `.gitmodules` mit kommentierter Remote-Auswahl
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[submodule "modul1"]
|
[submodule "modul1"]
|
||||||
path = modul1
|
path = modul1
|
||||||
url = ssh://git@local.example.com:2222/myorg/modul1.git
|
url = ssh://git@local.example.com:2222/myorg/modul1.git
|
||||||
# url = git@github.com:myorg/modul1.git
|
# url = git@github.com:myorg/modul1.git
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🧭 Alternative: Subtree statt Submodul?
|
## 🧭 Alternative: Subtree statt Submodul?
|
||||||
|
|
||||||
Subtree ist einfacher zu verwalten, aber:
|
Subtree ist einfacher zu verwalten, aber:
|
||||||
|
|
||||||
- kein fester Commit-Zeiger,
|
- kein fester Commit-Zeiger,
|
||||||
- kein Remote-Wechsel ohne Umweg,
|
- kein Remote-Wechsel ohne Umweg,
|
||||||
- gemergte Historie im Hauptrepo.
|
- gemergte Historie im Hauptrepo.
|
||||||
|
|
||||||
**Submodul = getrennte Repos**
|
**Submodul = getrennte Repos**
|
||||||
**Subtree = eingemergter Inhalt**
|
**Subtree = eingemergter Inhalt**
|
||||||
|
|
||||||
## 📚 Fazit
|
## 📚 Fazit
|
||||||
|
|
||||||
Git-Submodule sind mächtig, aber erfordern **Disziplin und Überblick**. Für wiederverwendbare Komponenten, zentral gepflegte Inhalte oder externe Bibliotheken sind sie oft die bessere Wahl als Duplikate oder Copy-Paste.
|
Git-Submodule sind mächtig, aber erfordern **Disziplin und Überblick**. Für wiederverwendbare Komponenten, zentral gepflegte Inhalte oder externe Bibliotheken sind sie oft die bessere Wahl als Duplikate oder Copy-Paste.
|
||||||
|
|
||||||
## 🔗 Weiterführende Links
|
## 🔗 Weiterführende Links
|
||||||
|
|
||||||
- [Git Book: Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)
|
- [Git Book: Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)
|
||||||
- [git-scm Doku: submodule](https://git-scm.com/docs/git-submodule)
|
- [git-scm Doku: submodule](https://git-scm.com/docs/git-submodule)
|
||||||
- [Vergleich Submodule vs. Subtree](https://www.atlassian.com/git/tutorials/git-submodule)
|
- [Vergleich Submodule vs. Subtree](https://www.atlassian.com/git/tutorials/git-submodule)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Artikel: git
|
# Artikel: git
|
||||||
|
|
||||||
- [SSH-Zugriff auf Git-Repository in WSL einrichten](git-ssh-remote.md)
|
- [SSH-Zugriff auf Git-Repository in WSL einrichten](git-ssh-remote.md)
|
||||||
- [Git – Remote-Branches: Häufige Aufgaben und Lösungen](git-remote-branch.md)
|
- [Git – Remote-Branches: Häufige Aufgaben und Lösungen](git-remote-branch.md)
|
||||||
|
@ -1,182 +1,182 @@
|
|||||||
# Helix Editor – Ein umfassender Einstieg für Anfänger (Deutsch)
|
# Helix Editor – Ein umfassender Einstieg für Anfänger (Deutsch)
|
||||||
|
|
||||||
## Inhalt
|
## Inhalt
|
||||||
|
|
||||||
- [Helix Editor – Ein umfassender Einstieg für Anfänger (Deutsch)](#helix-editor--ein-umfassender-einstieg-für-anfänger-deutsch)
|
- [Helix Editor – Ein umfassender Einstieg für Anfänger (Deutsch)](#helix-editor--ein-umfassender-einstieg-für-anfänger-deutsch)
|
||||||
- [Inhalt](#inhalt)
|
- [Inhalt](#inhalt)
|
||||||
- [✨ Was ist Helix?](#-was-ist-helix)
|
- [✨ Was ist Helix?](#-was-ist-helix)
|
||||||
- [🔧 Installation](#-installation)
|
- [🔧 Installation](#-installation)
|
||||||
- [Linux (Fedora, Arch, Debian)](#linux-fedora-arch-debian)
|
- [Linux (Fedora, Arch, Debian)](#linux-fedora-arch-debian)
|
||||||
- [GitHub Release (empfohlen für aktuellste Version)](#github-release-empfohlen-für-aktuellste-version)
|
- [GitHub Release (empfohlen für aktuellste Version)](#github-release-empfohlen-für-aktuellste-version)
|
||||||
- [📁 Erstes Projekt starten](#-erstes-projekt-starten)
|
- [📁 Erstes Projekt starten](#-erstes-projekt-starten)
|
||||||
- [Beispiel: Rust-Projekt](#beispiel-rust-projekt)
|
- [Beispiel: Rust-Projekt](#beispiel-rust-projekt)
|
||||||
- [Beispiel: JavaScript-Projekt](#beispiel-javascript-projekt)
|
- [Beispiel: JavaScript-Projekt](#beispiel-javascript-projekt)
|
||||||
- [⌨ Bedienkonzept von Helix](#-bedienkonzept-von-helix)
|
- [⌨ Bedienkonzept von Helix](#-bedienkonzept-von-helix)
|
||||||
- [Modale Steuerung (ähnlich wie Vim)](#modale-steuerung-ähnlich-wie-vim)
|
- [Modale Steuerung (ähnlich wie Vim)](#modale-steuerung-ähnlich-wie-vim)
|
||||||
- [Wechsel der Modi](#wechsel-der-modi)
|
- [Wechsel der Modi](#wechsel-der-modi)
|
||||||
- [⚖️ Wichtige Tastenkombinationen](#️-wichtige-tastenkombinationen)
|
- [⚖️ Wichtige Tastenkombinationen](#️-wichtige-tastenkombinationen)
|
||||||
- [🪨 Sprachserver (LSP)](#-sprachserver-lsp)
|
- [🪨 Sprachserver (LSP)](#-sprachserver-lsp)
|
||||||
- [Rust](#rust)
|
- [Rust](#rust)
|
||||||
- [JavaScript/TypeScript](#javascripttypescript)
|
- [JavaScript/TypeScript](#javascripttypescript)
|
||||||
- [C / C++](#c--c)
|
- [C / C++](#c--c)
|
||||||
- [⚖️ LSP-Befehle in Helix](#️-lsp-befehle-in-helix)
|
- [⚖️ LSP-Befehle in Helix](#️-lsp-befehle-in-helix)
|
||||||
- [📂 Konfiguration](#-konfiguration)
|
- [📂 Konfiguration](#-konfiguration)
|
||||||
- [Beispiel-Inhalt](#beispiel-inhalt)
|
- [Beispiel-Inhalt](#beispiel-inhalt)
|
||||||
- [🌍 Weitere Ressourcen](#-weitere-ressourcen)
|
- [🌍 Weitere Ressourcen](#-weitere-ressourcen)
|
||||||
|
|
||||||
## ✨ Was ist Helix?
|
## ✨ Was ist Helix?
|
||||||
|
|
||||||
Helix ist ein moderner, terminalbasierter Code-Editor mit Fokus auf Produktivität, Effizienz und minimalistische Bedienung. Er verwendet **modale Eingabe** (wie Vim), bietet jedoch eine eigene, einsteigerfreundlichere Philosophie mit moderner Technologie wie **LSP**, **Tree-sitter**, und Syntax-Highlighting direkt aus dem Terminal.
|
Helix ist ein moderner, terminalbasierter Code-Editor mit Fokus auf Produktivität, Effizienz und minimalistische Bedienung. Er verwendet **modale Eingabe** (wie Vim), bietet jedoch eine eigene, einsteigerfreundlichere Philosophie mit moderner Technologie wie **LSP**, **Tree-sitter**, und Syntax-Highlighting direkt aus dem Terminal.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔧 Installation
|
## 🔧 Installation
|
||||||
|
|
||||||
### Linux (Fedora, Arch, Debian)
|
### Linux (Fedora, Arch, Debian)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Fedora
|
# Fedora
|
||||||
sudo dnf install helix
|
sudo dnf install helix
|
||||||
|
|
||||||
# Arch (via pacman)
|
# Arch (via pacman)
|
||||||
sudo pacman -S helix
|
sudo pacman -S helix
|
||||||
|
|
||||||
# Debian/Ubuntu (nur in neueren Versionen oder via GitHub)
|
# Debian/Ubuntu (nur in neueren Versionen oder via GitHub)
|
||||||
```
|
```
|
||||||
|
|
||||||
### GitHub Release (empfohlen für aktuellste Version)
|
### GitHub Release (empfohlen für aktuellste Version)
|
||||||
|
|
||||||
1. Gehe zu: [https://github.com/helix-editor/helix/releases](https://github.com/helix-editor/helix/releases)
|
1. Gehe zu: [https://github.com/helix-editor/helix/releases](https://github.com/helix-editor/helix/releases)
|
||||||
2. Lade das passende Paket für dein System herunter
|
2. Lade das passende Paket für dein System herunter
|
||||||
3. Entpacken:
|
3. Entpacken:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
tar -xvf helix-*-x86_64-linux.tar.xz
|
tar -xvf helix-*-x86_64-linux.tar.xz
|
||||||
sudo cp helix-*/helix/hx /usr/local/bin/
|
sudo cp helix-*/helix/hx /usr/local/bin/
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📁 Erstes Projekt starten
|
## 📁 Erstes Projekt starten
|
||||||
|
|
||||||
### Beispiel: Rust-Projekt
|
### Beispiel: Rust-Projekt
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo new hallo_helix
|
cargo new hallo_helix
|
||||||
cd hallo_helix
|
cd hallo_helix
|
||||||
hx src/main.rs
|
hx src/main.rs
|
||||||
```
|
```
|
||||||
|
|
||||||
### Beispiel: JavaScript-Projekt
|
### Beispiel: JavaScript-Projekt
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir node_hello && cd node_hello
|
mkdir node_hello && cd node_hello
|
||||||
echo 'console.log("Hallo, Welt!");' > index.js
|
echo 'console.log("Hallo, Welt!");' > index.js
|
||||||
hx index.js
|
hx index.js
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⌨ Bedienkonzept von Helix
|
## ⌨ Bedienkonzept von Helix
|
||||||
|
|
||||||
### Modale Steuerung (ähnlich wie Vim)
|
### Modale Steuerung (ähnlich wie Vim)
|
||||||
|
|
||||||
- **Normalmodus**: Standardmodus zum Navigieren und Bearbeiten
|
- **Normalmodus**: Standardmodus zum Navigieren und Bearbeiten
|
||||||
- **Einfügemodus (Insert)**: `i` drücken zum Schreiben
|
- **Einfügemodus (Insert)**: `i` drücken zum Schreiben
|
||||||
- **Auswahlmodus (Select)**: `v` für Zeichenweise, `V` für Zeilenweise Auswahl
|
- **Auswahlmodus (Select)**: `v` für Zeichenweise, `V` für Zeilenweise Auswahl
|
||||||
|
|
||||||
### Wechsel der Modi
|
### Wechsel der Modi
|
||||||
|
|
||||||
| Modus | Taste | Funktion |
|
| Modus | Taste | Funktion |
|
||||||
| ----------- | ----- | ----------------------- |
|
| ----------- | ----- | ----------------------- |
|
||||||
| Normal | `Esc` | Zur Steuerung & Befehle |
|
| Normal | `Esc` | Zur Steuerung & Befehle |
|
||||||
| Insert | `i` | Einfügen / Tippen |
|
| Insert | `i` | Einfügen / Tippen |
|
||||||
| Select | `v` | Auswahl ab Cursor |
|
| Select | `v` | Auswahl ab Cursor |
|
||||||
| Line-Select | `V` | Ganze Zeile auswählen |
|
| Line-Select | `V` | Ganze Zeile auswählen |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⚖️ Wichtige Tastenkombinationen
|
## ⚖️ Wichtige Tastenkombinationen
|
||||||
|
|
||||||
| Tastenkombi | Bedeutung |
|
| Tastenkombi | Bedeutung |
|
||||||
| ----------- | --------------------------------- |
|
| ----------- | --------------------------------- |
|
||||||
| `:w` | Datei speichern |
|
| `:w` | Datei speichern |
|
||||||
| `:q` | Editor beenden |
|
| `:q` | Editor beenden |
|
||||||
| `:wq` | Speichern und beenden |
|
| `:wq` | Speichern und beenden |
|
||||||
| `g g` | Zum Anfang der Datei |
|
| `g g` | Zum Anfang der Datei |
|
||||||
| `G` | Zum Ende der Datei |
|
| `G` | Zum Ende der Datei |
|
||||||
| `d d` | Aktuelle Zeile löschen |
|
| `d d` | Aktuelle Zeile löschen |
|
||||||
| `u` | Letzte Änderung rückgängig machen |
|
| `u` | Letzte Änderung rückgängig machen |
|
||||||
| `space + /` | Fuzzy-Dateisuche starten |
|
| `space + /` | Fuzzy-Dateisuche starten |
|
||||||
| `space + g` | Git-Diff anzeigen |
|
| `space + g` | Git-Diff anzeigen |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🪨 Sprachserver (LSP)
|
## 🪨 Sprachserver (LSP)
|
||||||
|
|
||||||
Helix erkennt automatisch den Dateityp und startet den passenden Sprachserver:
|
Helix erkennt automatisch den Dateityp und startet den passenden Sprachserver:
|
||||||
|
|
||||||
### Rust
|
### Rust
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rustup component add rust-analyzer
|
rustup component add rust-analyzer
|
||||||
```
|
```
|
||||||
|
|
||||||
### JavaScript/TypeScript
|
### JavaScript/TypeScript
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install -g typescript typescript-language-server
|
npm install -g typescript typescript-language-server
|
||||||
```
|
```
|
||||||
|
|
||||||
### C / C++
|
### C / C++
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo dnf install clang clang-tools-extra
|
sudo dnf install clang clang-tools-extra
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⚖️ LSP-Befehle in Helix
|
## ⚖️ LSP-Befehle in Helix
|
||||||
|
|
||||||
| Taste | Bedeutung |
|
| Taste | Bedeutung |
|
||||||
| ----- | ------------------------------- |
|
| ----- | ------------------------------- |
|
||||||
| `g d` | Gehe zur Definition |
|
| `g d` | Gehe zur Definition |
|
||||||
| `g r` | Gehe zu Referenzen |
|
| `g r` | Gehe zu Referenzen |
|
||||||
| `K` | Hover-Info anzeigen (Typ, Doku) |
|
| `K` | Hover-Info anzeigen (Typ, Doku) |
|
||||||
| `=` | Formatieren |
|
| `=` | Formatieren |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📂 Konfiguration
|
## 📂 Konfiguration
|
||||||
|
|
||||||
Helix-Konfiguration liegt unter:
|
Helix-Konfiguration liegt unter:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
~/.config/helix/config.toml
|
~/.config/helix/config.toml
|
||||||
```
|
```
|
||||||
|
|
||||||
Zum Öffnen:
|
Zum Öffnen:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
:config-open
|
:config-open
|
||||||
```
|
```
|
||||||
|
|
||||||
### Beispiel-Inhalt
|
### Beispiel-Inhalt
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
theme = "base16_default_dark"
|
theme = "base16_default_dark"
|
||||||
|
|
||||||
[keys.normal]
|
[keys.normal]
|
||||||
"C-s" = ":w"
|
"C-s" = ":w"
|
||||||
"C-q" = ":wq"
|
"C-q" = ":wq"
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🌍 Weitere Ressourcen
|
## 🌍 Weitere Ressourcen
|
||||||
|
|
||||||
- Offizielle Seite: [https://helix-editor.com](https://helix-editor.com)
|
- Offizielle Seite: [https://helix-editor.com](https://helix-editor.com)
|
||||||
- GitHub: [https://github.com/helix-editor/helix](https://github.com/helix-editor/helix)
|
- GitHub: [https://github.com/helix-editor/helix](https://github.com/helix-editor/helix)
|
||||||
- Tastenkombis: [https://docs.helix-editor.com/](https://docs.helix-editor.com/)
|
- Tastenkombis: [https://docs.helix-editor.com/](https://docs.helix-editor.com/)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -1,345 +1,345 @@
|
|||||||
# Einstieg in JavaScript-Dialekte und TypeScript-Konfiguration
|
# Einstieg in JavaScript-Dialekte und TypeScript-Konfiguration
|
||||||
|
|
||||||
## ✨ Ziel dieses Dokuments
|
## ✨ Ziel dieses Dokuments
|
||||||
|
|
||||||
Diese Anleitung richtet sich an Anfänger, die lernen wollen, wann sie welchen JavaScript-Dialekt (CommonJS vs. ESM) verwenden sollten, wie sie TypeScript korrekt konfigurieren und worauf sie bei modernen Projekten achten müssen.
|
Diese Anleitung richtet sich an Anfänger, die lernen wollen, wann sie welchen JavaScript-Dialekt (CommonJS vs. ESM) verwenden sollten, wie sie TypeScript korrekt konfigurieren und worauf sie bei modernen Projekten achten müssen.
|
||||||
|
|
||||||
## Inhalt
|
## Inhalt
|
||||||
|
|
||||||
- [Einstieg in JavaScript-Dialekte und TypeScript-Konfiguration](#einstieg-in-javascript-dialekte-und-typescript-konfiguration)
|
- [Einstieg in JavaScript-Dialekte und TypeScript-Konfiguration](#einstieg-in-javascript-dialekte-und-typescript-konfiguration)
|
||||||
- [✨ Ziel dieses Dokuments](#-ziel-dieses-dokuments)
|
- [✨ Ziel dieses Dokuments](#-ziel-dieses-dokuments)
|
||||||
- [Inhalt](#inhalt)
|
- [Inhalt](#inhalt)
|
||||||
- [🔢 Begriffe erklärt](#-begriffe-erklärt)
|
- [🔢 Begriffe erklärt](#-begriffe-erklärt)
|
||||||
- [JavaScript-Dialekte (Modulsysteme)](#javascript-dialekte-modulsysteme)
|
- [JavaScript-Dialekte (Modulsysteme)](#javascript-dialekte-modulsysteme)
|
||||||
- [Was ist TypeScript?](#was-ist-typescript)
|
- [Was ist TypeScript?](#was-ist-typescript)
|
||||||
- [🔍 Wann verwende ich was?](#-wann-verwende-ich-was)
|
- [🔍 Wann verwende ich was?](#-wann-verwende-ich-was)
|
||||||
- [🔧 TypeScript richtig konfigurieren](#-typescript-richtig-konfigurieren)
|
- [🔧 TypeScript richtig konfigurieren](#-typescript-richtig-konfigurieren)
|
||||||
- [📦 Was ist ESM?](#-was-ist-esm)
|
- [📦 Was ist ESM?](#-was-ist-esm)
|
||||||
- [✅ Wann kann/sollte/muss man **ESM** verwenden?](#-wann-kannsolltemuss-man-esm-verwenden)
|
- [✅ Wann kann/sollte/muss man **ESM** verwenden?](#-wann-kannsolltemuss-man-esm-verwenden)
|
||||||
- [🟢 **Du kannst ESM verwenden**, wenn](#-du-kannst-esm-verwenden-wenn)
|
- [🟢 **Du kannst ESM verwenden**, wenn](#-du-kannst-esm-verwenden-wenn)
|
||||||
- [🟡 **Du solltest ESM verwenden**, wenn](#-du-solltest-esm-verwenden-wenn)
|
- [🟡 **Du solltest ESM verwenden**, wenn](#-du-solltest-esm-verwenden-wenn)
|
||||||
- [🔴 **Du musst ESM verwenden**, wenn](#-du-musst-esm-verwenden-wenn)
|
- [🔴 **Du musst ESM verwenden**, wenn](#-du-musst-esm-verwenden-wenn)
|
||||||
- [⚙️ TypeScript-Konfiguration für ESM](#️-typescript-konfiguration-für-esm)
|
- [⚙️ TypeScript-Konfiguration für ESM](#️-typescript-konfiguration-für-esm)
|
||||||
- [📌 Merkmale von ESM](#-merkmale-von-esm)
|
- [📌 Merkmale von ESM](#-merkmale-von-esm)
|
||||||
- [⚠️ Besonderheiten und Stolperfallen](#️-besonderheiten-und-stolperfallen)
|
- [⚠️ Besonderheiten und Stolperfallen](#️-besonderheiten-und-stolperfallen)
|
||||||
- [✅ Fazit ESM](#-fazit-esm)
|
- [✅ Fazit ESM](#-fazit-esm)
|
||||||
- [🌐 CommonJS-Konfiguration CJS (Alternative)](#-commonjs-konfiguration-cjs-alternative)
|
- [🌐 CommonJS-Konfiguration CJS (Alternative)](#-commonjs-konfiguration-cjs-alternative)
|
||||||
- [📦 Was ist CommonJS?](#-was-ist-commonjs)
|
- [📦 Was ist CommonJS?](#-was-ist-commonjs)
|
||||||
- [✅ Wann kann/sollte/muss man **CommonJS** verwenden?](#-wann-kannsolltemuss-man-commonjs-verwenden)
|
- [✅ Wann kann/sollte/muss man **CommonJS** verwenden?](#-wann-kannsolltemuss-man-commonjs-verwenden)
|
||||||
- [🟢 **Du kannst CJS verwenden**, wenn](#-du-kannst-cjs-verwenden-wenn)
|
- [🟢 **Du kannst CJS verwenden**, wenn](#-du-kannst-cjs-verwenden-wenn)
|
||||||
- [🟡 **Du solltest CJS verwenden**, wenn](#-du-solltest-cjs-verwenden-wenn)
|
- [🟡 **Du solltest CJS verwenden**, wenn](#-du-solltest-cjs-verwenden-wenn)
|
||||||
- [🔴 **Du musst CJS verwenden**, wenn](#-du-musst-cjs-verwenden-wenn)
|
- [🔴 **Du musst CJS verwenden**, wenn](#-du-musst-cjs-verwenden-wenn)
|
||||||
- [⚙️ TypeScript-Konfiguration für CJS](#️-typescript-konfiguration-für-cjs)
|
- [⚙️ TypeScript-Konfiguration für CJS](#️-typescript-konfiguration-für-cjs)
|
||||||
- [📌 Merkmale von CommonJS](#-merkmale-von-commonjs)
|
- [📌 Merkmale von CommonJS](#-merkmale-von-commonjs)
|
||||||
- [✅ Fazit CommonJS](#-fazit-commonjs)
|
- [✅ Fazit CommonJS](#-fazit-commonjs)
|
||||||
- [📄 Fazit: Empfehlungen](#-fazit-empfehlungen)
|
- [📄 Fazit: Empfehlungen](#-fazit-empfehlungen)
|
||||||
- [📁 Dateiendungen in Node.js](#-dateiendungen-in-nodejs)
|
- [📁 Dateiendungen in Node.js](#-dateiendungen-in-nodejs)
|
||||||
- [⚠️ Typische Fehler vermeiden](#️-typische-fehler-vermeiden)
|
- [⚠️ Typische Fehler vermeiden](#️-typische-fehler-vermeiden)
|
||||||
- [🚀 CLI-Build-Tipps (tsc)](#-cli-build-tipps-tsc)
|
- [🚀 CLI-Build-Tipps (tsc)](#-cli-build-tipps-tsc)
|
||||||
- [📍 Weiterführende Themen](#-weiterführende-themen)
|
- [📍 Weiterführende Themen](#-weiterführende-themen)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔢 Begriffe erklärt
|
## 🔢 Begriffe erklärt
|
||||||
|
|
||||||
### JavaScript-Dialekte (Modulsysteme)
|
### JavaScript-Dialekte (Modulsysteme)
|
||||||
|
|
||||||
| Name | Kürzel | Typ | Verwendung heute |
|
| Name | Kürzel | Typ | Verwendung heute |
|
||||||
| ------------------ | ------ | ----------- | ----------------------- |
|
| ------------------ | ------ | ----------- | ----------------------- |
|
||||||
| CommonJS | CJS | `require()` | Ältere Node.js-Projekte |
|
| CommonJS | CJS | `require()` | Ältere Node.js-Projekte |
|
||||||
| ECMAScript Modules | ESM | `import` | Browser, moderne Tools |
|
| ECMAScript Modules | ESM | `import` | Browser, moderne Tools |
|
||||||
|
|
||||||
- **CommonJS:** Nutzt `require()` und `module.exports`. Standard bis Node 12.
|
- **CommonJS:** Nutzt `require()` und `module.exports`. Standard bis Node 12.
|
||||||
- **ESM:** Nutzt `import`/`export`. Standard im Browser und in Node ab Version 14+.
|
- **ESM:** Nutzt `import`/`export`. Standard im Browser und in Node ab Version 14+.
|
||||||
|
|
||||||
### Was ist TypeScript?
|
### Was ist TypeScript?
|
||||||
|
|
||||||
TypeScript ist eine statisch typisierte Obermenge von JavaScript, die zu normalem JS kompiliert wird.
|
TypeScript ist eine statisch typisierte Obermenge von JavaScript, die zu normalem JS kompiliert wird.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔍 Wann verwende ich was?
|
## 🔍 Wann verwende ich was?
|
||||||
|
|
||||||
| Ziel | Modulformat | Empfehlung | Grund |
|
| Ziel | Modulformat | Empfehlung | Grund |
|
||||||
| -------------------------- | ------------ | -------------- | ------------------------------------------ |
|
| -------------------------- | ------------ | -------------- | ------------------------------------------ |
|
||||||
| 📅 Moderne Webanwendung | ESM | Ja | Browser erwartet ESM |
|
| 📅 Moderne Webanwendung | ESM | Ja | Browser erwartet ESM |
|
||||||
| 📄 Node.js CLI-Tool | ESM oder CJS | Beides möglich | ESM zukunftssicher, CJS maximal kompatibel |
|
| 📄 Node.js CLI-Tool | ESM oder CJS | Beides möglich | ESM zukunftssicher, CJS maximal kompatibel |
|
||||||
| 🔐 Legacy-Node-Integration | CJS | Ja | Viele NPM-Pakete sind CJS-only |
|
| 🔐 Legacy-Node-Integration | CJS | Ja | Viele NPM-Pakete sind CJS-only |
|
||||||
| 🔌 Electron Renderer | ESM | Ja (Pflicht) | Chromium-only, kein CJS |
|
| 🔌 Electron Renderer | ESM | Ja (Pflicht) | Chromium-only, kein CJS |
|
||||||
| 🔁 Vite/Webpack-Projekt | ESM | Ja | Toolchain basiert auf ESM |
|
| 🔁 Vite/Webpack-Projekt | ESM | Ja | Toolchain basiert auf ESM |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔧 TypeScript richtig konfigurieren
|
## 🔧 TypeScript richtig konfigurieren
|
||||||
|
|
||||||
Eine vollständige Zusammenfassung zu **ESM (ECMAScript Modules)** – wann du es **verwenden kannst**, **solltest** oder **musst**, sowie alle wesentlichen technischen Eigenschaften. Stil und Umfang entsprechen exakt der vorherigen CommonJS-Zusammenfassung.
|
Eine vollständige Zusammenfassung zu **ESM (ECMAScript Modules)** – wann du es **verwenden kannst**, **solltest** oder **musst**, sowie alle wesentlichen technischen Eigenschaften. Stil und Umfang entsprechen exakt der vorherigen CommonJS-Zusammenfassung.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 📦 Was ist ESM?
|
### 📦 Was ist ESM?
|
||||||
|
|
||||||
**ESM (ECMAScript Modules)** ist das moderne Modulsystem von JavaScript:
|
**ESM (ECMAScript Modules)** ist das moderne Modulsystem von JavaScript:
|
||||||
|
|
||||||
- verwendet `import`/`export`-Syntax
|
- verwendet `import`/`export`-Syntax
|
||||||
- wird nativ von allen modernen Browsern und Node.js (ab v14+) unterstützt
|
- wird nativ von allen modernen Browsern und Node.js (ab v14+) unterstützt
|
||||||
- ist Standard in allen modernen JS-Toolchains (Vite, Webpack, esbuild, etc.)
|
- ist Standard in allen modernen JS-Toolchains (Vite, Webpack, esbuild, etc.)
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// ESM-Stil
|
// ESM-Stil
|
||||||
import fs from 'node:fs/promises';
|
import fs from 'node:fs/promises';
|
||||||
export function read(path) {
|
export function read(path) {
|
||||||
return fs.readFile(path, 'utf-8');
|
return fs.readFile(path, 'utf-8');
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### ✅ Wann kann/sollte/muss man **ESM** verwenden?
|
### ✅ Wann kann/sollte/muss man **ESM** verwenden?
|
||||||
|
|
||||||
#### 🟢 **Du kannst ESM verwenden**, wenn
|
#### 🟢 **Du kannst ESM verwenden**, wenn
|
||||||
|
|
||||||
- du mit **modernen Node.js-Versionen (v16+)** arbeitest
|
- du mit **modernen Node.js-Versionen (v16+)** arbeitest
|
||||||
- du ein **Frontend-Tool** oder ein **Browser-kompatibles Projekt** baust
|
- du ein **Frontend-Tool** oder ein **Browser-kompatibles Projekt** baust
|
||||||
- du Tree-Shaking oder Dynamic `import()` nutzen willst
|
- du Tree-Shaking oder Dynamic `import()` nutzen willst
|
||||||
- du Typkonsistenz mit dem Browser willst (gleiche Syntax wie dort)
|
- du Typkonsistenz mit dem Browser willst (gleiche Syntax wie dort)
|
||||||
|
|
||||||
#### 🟡 **Du solltest ESM verwenden**, wenn
|
#### 🟡 **Du solltest ESM verwenden**, wenn
|
||||||
|
|
||||||
| Situation | Grund |
|
| Situation | Grund |
|
||||||
| ------------------------------------------------------------------- | ---------------------------- |
|
| ------------------------------------------------------------------- | ---------------------------- |
|
||||||
| 🌐 Du entwickelst Webanwendungen mit Vite, Nuxt, Webpack o. ä. | Diese Tools basieren auf ESM |
|
| 🌐 Du entwickelst Webanwendungen mit Vite, Nuxt, Webpack o. ä. | Diese Tools basieren auf ESM |
|
||||||
| 💡 Du möchtest moderne Syntax und Tooling nutzen | ESM ist Standard |
|
| 💡 Du möchtest moderne Syntax und Tooling nutzen | ESM ist Standard |
|
||||||
| 🔄 Du willst `import()` dynamisch verwenden | Nur in ESM verfügbar |
|
| 🔄 Du willst `import()` dynamisch verwenden | Nur in ESM verfügbar |
|
||||||
| 📚 Du schreibst eine wiederverwendbare Bibliothek für neue Projekte | Zukunftssicherheit |
|
| 📚 Du schreibst eine wiederverwendbare Bibliothek für neue Projekte | Zukunftssicherheit |
|
||||||
| 🧩 Du verwendest Deno, Bun oder moderne Plattformen | ESM only |
|
| 🧩 Du verwendest Deno, Bun oder moderne Plattformen | ESM only |
|
||||||
|
|
||||||
#### 🔴 **Du musst ESM verwenden**, wenn
|
#### 🔴 **Du musst ESM verwenden**, wenn
|
||||||
|
|
||||||
- du im **Browser** arbeitest (ohne Bundler) → dort ist `import` Pflicht
|
- du im **Browser** arbeitest (ohne Bundler) → dort ist `import` Pflicht
|
||||||
- du in **Electron-Renderer-Prozessen** arbeitest
|
- du in **Electron-Renderer-Prozessen** arbeitest
|
||||||
- du ein Projekt hast mit `"type": "module"` und `.js`-Dateien → dann interpretiert Node sie nur als ESM
|
- du ein Projekt hast mit `"type": "module"` und `.js`-Dateien → dann interpretiert Node sie nur als ESM
|
||||||
- du ESM-only-Dependencies nutzt (z. B. `chalk@5`, `node-fetch@3`)
|
- du ESM-only-Dependencies nutzt (z. B. `chalk@5`, `node-fetch@3`)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### ⚙️ TypeScript-Konfiguration für ESM
|
### ⚙️ TypeScript-Konfiguration für ESM
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2020",
|
"target": "ES2020",
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"allowSyntheticDefaultImports": true
|
"allowSyntheticDefaultImports": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Und in der `package.json`:
|
Und in der `package.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"type": "module"
|
"type": "module"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Wichtig:** Ohne `"type": "module"` behandelt Node deine `.js`-Dateien **nicht als ESM**, sondern als CommonJS.
|
**Wichtig:** Ohne `"type": "module"` behandelt Node deine `.js`-Dateien **nicht als ESM**, sondern als CommonJS.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 📌 Merkmale von ESM
|
### 📌 Merkmale von ESM
|
||||||
|
|
||||||
| Merkmal | ESM |
|
| Merkmal | ESM |
|
||||||
| ------------------------- | -------------------------------------------- |
|
| ------------------------- | -------------------------------------------- |
|
||||||
| Import-Syntax | `import`, `export` |
|
| Import-Syntax | `import`, `export` |
|
||||||
| Export-Syntax | `export default`, `export {...}` |
|
| Export-Syntax | `export default`, `export {...}` |
|
||||||
| Dateiendung `.js` | **.js** nur mit `"type": "module"` |
|
| Dateiendung `.js` | **.js** nur mit `"type": "module"` |
|
||||||
| `.mjs` | explizit ESM |
|
| `.mjs` | explizit ESM |
|
||||||
| `__dirname`, `__filename` | ❌ nicht vorhanden, nur via `import.meta.url` |
|
| `__dirname`, `__filename` | ❌ nicht vorhanden, nur via `import.meta.url` |
|
||||||
| Dynamische Imports | ✅ `await import('...')` |
|
| Dynamische Imports | ✅ `await import('...')` |
|
||||||
| Tree Shaking | ✅ möglich |
|
| Tree Shaking | ✅ möglich |
|
||||||
| Browser-kompatibel | ✅ nativ |
|
| Browser-kompatibel | ✅ nativ |
|
||||||
| CommonJS-Interop | ❗ mit Einschränkungen (`createRequire`) |
|
| CommonJS-Interop | ❗ mit Einschränkungen (`createRequire`) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### ⚠️ Besonderheiten und Stolperfallen
|
### ⚠️ Besonderheiten und Stolperfallen
|
||||||
|
|
||||||
| Problem | Lösung |
|
| Problem | Lösung |
|
||||||
| --------------------------------------------- | ------------------------------------------- |
|
| --------------------------------------------- | ------------------------------------------- |
|
||||||
| ❌ `__dirname`/`__filename` fehlen | nutze `import.meta.url` + `fileURLToPath()` |
|
| ❌ `__dirname`/`__filename` fehlen | nutze `import.meta.url` + `fileURLToPath()` |
|
||||||
| ❌ `require()` nicht verfügbar | verwende `import`, oder `createRequire()` |
|
| ❌ `require()` nicht verfügbar | verwende `import`, oder `createRequire()` |
|
||||||
| ❌ `.js` muss beim Import angegeben werden | z. B. `import './utils.js'` |
|
| ❌ `.js` muss beim Import angegeben werden | z. B. `import './utils.js'` |
|
||||||
| ❌ viele alte Pakete sind nicht ESM-kompatibel | ggf. CommonJS verwenden |
|
| ❌ viele alte Pakete sind nicht ESM-kompatibel | ggf. CommonJS verwenden |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### ✅ Fazit ESM
|
### ✅ Fazit ESM
|
||||||
|
|
||||||
> **ESM ist der offizielle Standard für moderne JavaScript-Entwicklung** – sowohl im Browser als auch in modernen Node.js-Umgebungen.
|
> **ESM ist der offizielle Standard für moderne JavaScript-Entwicklung** – sowohl im Browser als auch in modernen Node.js-Umgebungen.
|
||||||
|
|
||||||
Du solltest ESM verwenden, wenn du:
|
Du solltest ESM verwenden, wenn du:
|
||||||
|
|
||||||
- neue Projekte startest,
|
- neue Projekte startest,
|
||||||
- moderne Toolchains nutzt,
|
- moderne Toolchains nutzt,
|
||||||
- oder langfristige Kompatibilität willst.
|
- oder langfristige Kompatibilität willst.
|
||||||
|
|
||||||
In Zweifelsfällen gilt: **Wenn du mit aktuellen Tools und Node-Versionen arbeitest, nimm ESM.**
|
In Zweifelsfällen gilt: **Wenn du mit aktuellen Tools und Node-Versionen arbeitest, nimm ESM.**
|
||||||
Nur bei Problemen mit alten Paketen oder Tooling solltest du temporär auf CommonJS zurückfallen.
|
Nur bei Problemen mit alten Paketen oder Tooling solltest du temporär auf CommonJS zurückfallen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🌐 CommonJS-Konfiguration CJS (Alternative)
|
## 🌐 CommonJS-Konfiguration CJS (Alternative)
|
||||||
|
|
||||||
### 📦 Was ist CommonJS?
|
### 📦 Was ist CommonJS?
|
||||||
|
|
||||||
**CommonJS (CJS)** ist das ursprüngliche Modulsystem von Node.js:
|
**CommonJS (CJS)** ist das ursprüngliche Modulsystem von Node.js:
|
||||||
|
|
||||||
- verwendet `require()` zum Importieren
|
- verwendet `require()` zum Importieren
|
||||||
- verwendet `module.exports` oder `exports` zum Exportieren
|
- verwendet `module.exports` oder `exports` zum Exportieren
|
||||||
- keine native Unterstützung für `import`/`export`
|
- keine native Unterstützung für `import`/`export`
|
||||||
- funktioniert nur in Node.js (nicht im Browser ohne Bundler)
|
- funktioniert nur in Node.js (nicht im Browser ohne Bundler)
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// CommonJS-Stil
|
// CommonJS-Stil
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
module.exports = { read: fs.readFileSync };
|
module.exports = { read: fs.readFileSync };
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### ✅ Wann kann/sollte/muss man **CommonJS** verwenden?
|
### ✅ Wann kann/sollte/muss man **CommonJS** verwenden?
|
||||||
|
|
||||||
#### 🟢 **Du kannst CJS verwenden**, wenn
|
#### 🟢 **Du kannst CJS verwenden**, wenn
|
||||||
|
|
||||||
- du ein CLI-Tool oder Node.js-Skript erstellst
|
- du ein CLI-Tool oder Node.js-Skript erstellst
|
||||||
- du maximale **Kompatibilität** ohne ESM-Komplikationen willst
|
- du maximale **Kompatibilität** ohne ESM-Komplikationen willst
|
||||||
- du keine modernen ESM-Features brauchst
|
- du keine modernen ESM-Features brauchst
|
||||||
- du auf Build-Tools verzichtest und direkt `.js`-Dateien startest
|
- du auf Build-Tools verzichtest und direkt `.js`-Dateien startest
|
||||||
|
|
||||||
#### 🟡 **Du solltest CJS verwenden**, wenn
|
#### 🟡 **Du solltest CJS verwenden**, wenn
|
||||||
|
|
||||||
| Situation | Grund |
|
| Situation | Grund |
|
||||||
| ------------------------------------------------------------------- | ------------------------------------------------------ |
|
| ------------------------------------------------------------------- | ------------------------------------------------------ |
|
||||||
| 🔄 Du arbeitest mit älteren Node.js-Versionen (z. B. v12 oder v10) | ESM ist dort nicht stabil |
|
| 🔄 Du arbeitest mit älteren Node.js-Versionen (z. B. v12 oder v10) | ESM ist dort nicht stabil |
|
||||||
| 📦 Du nutzt NPM-Pakete, die **kein ESM unterstützen** | `require()` wird erwartet |
|
| 📦 Du nutzt NPM-Pakete, die **kein ESM unterstützen** | `require()` wird erwartet |
|
||||||
| 🧪 Du verwendest alte Tools, Tests oder Konfigurationen | z. B. alte `mocha`, `gulpfile.js`, `webpack.config.js` |
|
| 🧪 Du verwendest alte Tools, Tests oder Konfigurationen | z. B. alte `mocha`, `gulpfile.js`, `webpack.config.js` |
|
||||||
| 🧱 Du brauchst direkten Zugriff auf `__dirname`, `__filename` | Diese fehlen in ESM |
|
| 🧱 Du brauchst direkten Zugriff auf `__dirname`, `__filename` | Diese fehlen in ESM |
|
||||||
| 📜 Du möchtest `.js`-Dateien ohne `.mjs` oder `type: module` nutzen | CommonJS macht keine Vorgaben für Dateiendungen |
|
| 📜 Du möchtest `.js`-Dateien ohne `.mjs` oder `type: module` nutzen | CommonJS macht keine Vorgaben für Dateiendungen |
|
||||||
|
|
||||||
#### 🔴 **Du musst CJS verwenden**, wenn
|
#### 🔴 **Du musst CJS verwenden**, wenn
|
||||||
|
|
||||||
- das Node.js-Modul, das du importieren willst, **nur `module.exports` exportiert** (kein ESM-Support)
|
- das Node.js-Modul, das du importieren willst, **nur `module.exports` exportiert** (kein ESM-Support)
|
||||||
- dein Projekt oder Tool **nicht mit ESM kompatibel ist** (ältere Tooling oder NPM-Module)
|
- dein Projekt oder Tool **nicht mit ESM kompatibel ist** (ältere Tooling oder NPM-Module)
|
||||||
- du `require()` oder dynamisches Laden (`require(dynamicPath)`) verwendest, was in ESM nicht geht
|
- du `require()` oder dynamisches Laden (`require(dynamicPath)`) verwendest, was in ESM nicht geht
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### ⚙️ TypeScript-Konfiguration für CJS
|
### ⚙️ TypeScript-Konfiguration für CJS
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2020",
|
"target": "ES2020",
|
||||||
"module": "CommonJS",
|
"module": "CommonJS",
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true
|
"esModuleInterop": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Und in der `package.json`:
|
Und in der `package.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"type": "commonjs"
|
"type": "commonjs"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Hinweis:** Das `"type"`-Feld ist für Node wichtig, nicht für TypeScript.
|
**Hinweis:** Das `"type"`-Feld ist für Node wichtig, nicht für TypeScript.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 📌 Merkmale von CommonJS
|
### 📌 Merkmale von CommonJS
|
||||||
|
|
||||||
| Merkmal | CommonJS |
|
| Merkmal | CommonJS |
|
||||||
| ------------------------- | -------------------------- |
|
| ------------------------- | -------------------------- |
|
||||||
| Import-Syntax | `require()` |
|
| Import-Syntax | `require()` |
|
||||||
| Export-Syntax | `module.exports = …` |
|
| Export-Syntax | `module.exports = …` |
|
||||||
| Dateiendung | `.js` (keine `.mjs` nötig) |
|
| Dateiendung | `.js` (keine `.mjs` nötig) |
|
||||||
| Direkt ausführbar | ✅ Ohne zusätzliche Flags |
|
| Direkt ausführbar | ✅ Ohne zusätzliche Flags |
|
||||||
| `__dirname`, `__filename` | ✅ verfügbar |
|
| `__dirname`, `__filename` | ✅ verfügbar |
|
||||||
| Browserkompatibilität | ❌ Nur mit Bundler möglich |
|
| Browserkompatibilität | ❌ Nur mit Bundler möglich |
|
||||||
| Dynamische Importe | ✅ `require(dynamicPath)` |
|
| Dynamische Importe | ✅ `require(dynamicPath)` |
|
||||||
| Tree Shaking | ❌ nicht möglich |
|
| Tree Shaking | ❌ nicht möglich |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### ✅ Fazit CommonJS
|
### ✅ Fazit CommonJS
|
||||||
|
|
||||||
> **CommonJS ist stabil, weit verbreitet und maximal kompatibel.**
|
> **CommonJS ist stabil, weit verbreitet und maximal kompatibel.**
|
||||||
> Wenn du **einfach nur ein Node-Tool oder CLI-Skript baust** und keine besonderen Build-Prozesse oder Browser-Kompatibilität brauchst: **Nutze CommonJS.**
|
> Wenn du **einfach nur ein Node-Tool oder CLI-Skript baust** und keine besonderen Build-Prozesse oder Browser-Kompatibilität brauchst: **Nutze CommonJS.**
|
||||||
|
|
||||||
Für moderne ESM-Projekte im Web oder wenn du zukunftssicher entwickeln willst, solltest du auf ESM setzen – aber CJS bleibt in vielen Fällen die einfachste und robusteste Wahl.
|
Für moderne ESM-Projekte im Web oder wenn du zukunftssicher entwickeln willst, solltest du auf ESM setzen – aber CJS bleibt in vielen Fällen die einfachste und robusteste Wahl.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📄 Fazit: Empfehlungen
|
## 📄 Fazit: Empfehlungen
|
||||||
|
|
||||||
- **Neue Projekte:** Nutze ESM mit `"type": "module"`
|
- **Neue Projekte:** Nutze ESM mit `"type": "module"`
|
||||||
- **Bestehende Tools nutzen `require()`?** Dann CJS
|
- **Bestehende Tools nutzen `require()`?** Dann CJS
|
||||||
- **Browser + Node gemeinsam nutzen?** ESM-only + klare Trennung von `shared/`, `client/`, `server/`
|
- **Browser + Node gemeinsam nutzen?** ESM-only + klare Trennung von `shared/`, `client/`, `server/`
|
||||||
- **Tooling wie Vite, Nuxt, Webpack?** Immer ESM
|
- **Tooling wie Vite, Nuxt, Webpack?** Immer ESM
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📁 Dateiendungen in Node.js
|
## 📁 Dateiendungen in Node.js
|
||||||
|
|
||||||
| Dateiendung | Verhalten |
|
| Dateiendung | Verhalten |
|
||||||
| ----------- | ------------------- |
|
| ----------- | ------------------- |
|
||||||
| `.js` | Hängt von `type` ab |
|
| `.js` | Hängt von `type` ab |
|
||||||
| `.mjs` | Immer ESM |
|
| `.mjs` | Immer ESM |
|
||||||
| `.cjs` | Immer CommonJS |
|
| `.cjs` | Immer CommonJS |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⚠️ Typische Fehler vermeiden
|
## ⚠️ Typische Fehler vermeiden
|
||||||
|
|
||||||
- **`SyntaxError: Cannot use import statement outside a module`**
|
- **`SyntaxError: Cannot use import statement outside a module`**
|
||||||
→ `type` fehlt in `package.json`
|
→ `type` fehlt in `package.json`
|
||||||
|
|
||||||
- **`Cannot find module` bei relativen Imports**
|
- **`Cannot find module` bei relativen Imports**
|
||||||
→ `.js` fehlt am Ende beim ESM-Import
|
→ `.js` fehlt am Ende beim ESM-Import
|
||||||
|
|
||||||
- **`__dirname` ist not defined**
|
- **`__dirname` ist not defined**
|
||||||
→ Du nutzt ESM, verwende `import.meta.url`
|
→ Du nutzt ESM, verwende `import.meta.url`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🚀 CLI-Build-Tipps (tsc)
|
## 🚀 CLI-Build-Tipps (tsc)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx tsc # Kompiliert Projekt laut tsconfig.json
|
npx tsc # Kompiliert Projekt laut tsconfig.json
|
||||||
chmod +x dist/index.js # Macht CLI-Datei ausführbar
|
chmod +x dist/index.js # Macht CLI-Datei ausführbar
|
||||||
```
|
```
|
||||||
|
|
||||||
Header für CLI-Datei:
|
Header für CLI-Datei:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📍 Weiterführende Themen
|
## 📍 Weiterführende Themen
|
||||||
|
|
||||||
- Dual-Exports für NPM (ESM + CJS gleichzeitig)
|
- Dual-Exports für NPM (ESM + CJS gleichzeitig)
|
||||||
- "exports"-Feld in `package.json`
|
- "exports"-Feld in `package.json`
|
||||||
- Tools wie `tsup`, `vite`, `esbuild` als Alternativen zu `tsc`
|
- Tools wie `tsup`, `vite`, `esbuild` als Alternativen zu `tsc`
|
||||||
- Einstieg in CLI-Tools: `commander`, `yargs`, `chalk`, `ora`
|
- Einstieg in CLI-Tools: `commander`, `yargs`, `chalk`, `ora`
|
||||||
|
@ -1,64 +1,64 @@
|
|||||||
# Gewindetabellen
|
# Gewindetabellen
|
||||||
|
|
||||||
## 📏 **Praxis-Gewindetabelle (zöllig, G = BSPP)**
|
## 📏 **Praxis-Gewindetabelle (zöllig, G = BSPP)**
|
||||||
|
|
||||||
| Gewindebezeichnung | ⌀ Außengewinde (mm) | ⌀ Innengewinde (mm) | Typische Anwendung |
|
| Gewindebezeichnung | ⌀ Außengewinde (mm) | ⌀ Innengewinde (mm) | Typische Anwendung |
|
||||||
| ------------------ | ------------------- | ------------------- | ---------------------------------- |
|
| ------------------ | ------------------- | ------------------- | ---------------------------------- |
|
||||||
| **G 1/8"** | \~9,7 mm | \~8,5 mm | Druckluft, Manometer |
|
| **G 1/8"** | \~9,7 mm | \~8,5 mm | Druckluft, Manometer |
|
||||||
| **G 1/4"** | \~13,2 mm | \~11,5 mm | Kleingeräte, Kaffeemaschinen |
|
| **G 1/4"** | \~13,2 mm | \~11,5 mm | Kleingeräte, Kaffeemaschinen |
|
||||||
| **G 3/8"** | \~16,6 mm | \~14,5 mm | Geräteventile, Mini-Zulaufschlauch |
|
| **G 3/8"** | \~16,6 mm | \~14,5 mm | Geräteventile, Mini-Zulaufschlauch |
|
||||||
| **G 1/2"** | \~20,95 mm | \~18,6 mm | Wasserhahn, Spülarmatur |
|
| **G 1/2"** | \~20,95 mm | \~18,6 mm | Wasserhahn, Spülarmatur |
|
||||||
| **G 3/4"** | \~26,4 mm | \~24,0 mm | Waschmaschine, Gartenschlauch |
|
| **G 3/4"** | \~26,4 mm | \~24,0 mm | Waschmaschine, Gartenschlauch |
|
||||||
| **G 1"** | \~33,25 mm | \~30,3 mm | Gartenwasserleitungen, Heizkreise |
|
| **G 1"** | \~33,25 mm | \~30,3 mm | Gartenwasserleitungen, Heizkreise |
|
||||||
| **G 1 1/4"** | \~41,9 mm | \~38,8 mm | Hausanschluss, Regenwassernutzung |
|
| **G 1 1/4"** | \~41,9 mm | \~38,8 mm | Hausanschluss, Regenwassernutzung |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 📌 Hinweise
|
### 📌 Hinweise
|
||||||
|
|
||||||
- Die Werte sind **gemittelte Praxiswerte**. Es gibt leichte Toleranzen je nach Hersteller.
|
- Die Werte sind **gemittelte Praxiswerte**. Es gibt leichte Toleranzen je nach Hersteller.
|
||||||
- Es handelt sich um **zylindrische Whitworth-Rohrgewinde (BSPP / G)**, **nicht kegelig**.
|
- Es handelt sich um **zylindrische Whitworth-Rohrgewinde (BSPP / G)**, **nicht kegelig**.
|
||||||
- Zur **Identifikation** reicht in der Regel eine Schieblehre und ein Blick in diese Tabelle.
|
- Zur **Identifikation** reicht in der Regel eine Schieblehre und ein Blick in diese Tabelle.
|
||||||
- Die Angabe „Zoll“ hat **nichts** mit dem Außendurchmesser zu tun – das ist reine Gewindeklassifizierung aus der Rohrnorm.
|
- Die Angabe „Zoll“ hat **nichts** mit dem Außendurchmesser zu tun – das ist reine Gewindeklassifizierung aus der Rohrnorm.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Klar – hier kommt eine **praxisorientierte Bohrtabelle für metrische ISO-Gewinde (M-Gewinde)** von **M1 bis M12**, wie sie beim Innengewindeschneiden (z. B. per Hand mit Schneideisen oder Gewindebohrer) verwendet wird.
|
Klar – hier kommt eine **praxisorientierte Bohrtabelle für metrische ISO-Gewinde (M-Gewinde)** von **M1 bis M12**, wie sie beim Innengewindeschneiden (z. B. per Hand mit Schneideisen oder Gewindebohrer) verwendet wird.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📏 **Bohrtabelle für metrische ISO-Regelgewinde (M-Gewinde nach DIN 13-1)**
|
## 📏 **Bohrtabelle für metrische ISO-Regelgewinde (M-Gewinde nach DIN 13-1)**
|
||||||
|
|
||||||
| Gewinde | Steigung (mm) | Kernloch-Ø (mm) (Bohrerdurchmesser) | Hinweis |
|
| Gewinde | Steigung (mm) | Kernloch-Ø (mm) (Bohrerdurchmesser) | Hinweis |
|
||||||
| ------- | ------------- | ----------------------------------- | ---------------------- |
|
| ------- | ------------- | ----------------------------------- | ---------------------- |
|
||||||
| M1 | 0.25 | 0.75 | selten, Feinmechanik |
|
| M1 | 0.25 | 0.75 | selten, Feinmechanik |
|
||||||
| M1.2 | 0.25 | 0.95 | z. B. Elektronik |
|
| M1.2 | 0.25 | 0.95 | z. B. Elektronik |
|
||||||
| M1.6 | 0.35 | 1.25 | sehr fein |
|
| M1.6 | 0.35 | 1.25 | sehr fein |
|
||||||
| M2 | 0.4 | 1.6 | Standard M2 |
|
| M2 | 0.4 | 1.6 | Standard M2 |
|
||||||
| M2.5 | 0.45 | 2.05 | beliebt bei Modellbau |
|
| M2.5 | 0.45 | 2.05 | beliebt bei Modellbau |
|
||||||
| M3 | 0.5 | 2.5 | sehr verbreitet |
|
| M3 | 0.5 | 2.5 | sehr verbreitet |
|
||||||
| M4 | 0.7 | 3.3 | Klassiker |
|
| M4 | 0.7 | 3.3 | Klassiker |
|
||||||
| M5 | 0.8 | 4.2 | oft bei Maschinen |
|
| M5 | 0.8 | 4.2 | oft bei Maschinen |
|
||||||
| M6 | 1.0 | 5.0 | Standardgröße |
|
| M6 | 1.0 | 5.0 | Standardgröße |
|
||||||
| M7 | 1.0 | 6.0 | eher selten |
|
| M7 | 1.0 | 6.0 | eher selten |
|
||||||
| M8 | 1.25 | 6.8 | Standard M8 |
|
| M8 | 1.25 | 6.8 | Standard M8 |
|
||||||
| M9 | 1.25 | 7.8 | Sondermaß |
|
| M9 | 1.25 | 7.8 | Sondermaß |
|
||||||
| M10 | 1.5 | 8.5 | Maschinenbau |
|
| M10 | 1.5 | 8.5 | Maschinenbau |
|
||||||
| M11 | 1.5 | 9.5 | selten |
|
| M11 | 1.5 | 9.5 | selten |
|
||||||
| M12 | 1.75 | 10.2 | oft für tragende Teile |
|
| M12 | 1.75 | 10.2 | oft für tragende Teile |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 📌 Hinweise Bohrtabelle
|
### 📌 Hinweise Bohrtabelle
|
||||||
|
|
||||||
- Dies sind die **Regelgewinde** – bei **Feingewinden** (z. B. M10x1) brauchst du kleinere Bohrer.
|
- Dies sind die **Regelgewinde** – bei **Feingewinden** (z. B. M10x1) brauchst du kleinere Bohrer.
|
||||||
- Werte gelten für **100 % Gewindeüberdeckung**. In der Praxis reicht oft eine leicht größere Bohrung für leichtere Schnitte (z. B. bei Alu oder weichen Werkstoffen).
|
- Werte gelten für **100 % Gewindeüberdeckung**. In der Praxis reicht oft eine leicht größere Bohrung für leichtere Schnitte (z. B. bei Alu oder weichen Werkstoffen).
|
||||||
- Bei harter Werkstoffwahl ggf. Spiralbohrer vorher anspitzen oder mit Zentrierbohrer vorbohren.
|
- Bei harter Werkstoffwahl ggf. Spiralbohrer vorher anspitzen oder mit Zentrierbohrer vorbohren.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 🧰 Beispiel zur Borhtabelle
|
### 🧰 Beispiel zur Borhtabelle
|
||||||
|
|
||||||
Du willst ein **M6-Gewinde** schneiden? → **5,0 mm Bohrer** nehmen → dann Gewindebohrer M6 einsetzen.
|
Du willst ein **M6-Gewinde** schneiden? → **5,0 mm Bohrer** nehmen → dann Gewindebohrer M6 einsetzen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -1,108 +1,108 @@
|
|||||||
# Let's Encrypt: Fehlerbehebung bei Challenge-Timeout unter Plesk
|
# Let's Encrypt: Fehlerbehebung bei Challenge-Timeout unter Plesk
|
||||||
|
|
||||||
- [Let's Encrypt: Fehlerbehebung bei Challenge-Timeout unter Plesk](#lets-encrypt-fehlerbehebung-bei-challenge-timeout-unter-plesk)
|
- [Let's Encrypt: Fehlerbehebung bei Challenge-Timeout unter Plesk](#lets-encrypt-fehlerbehebung-bei-challenge-timeout-unter-plesk)
|
||||||
- [🧩 Problemstellung](#-problemstellung)
|
- [🧩 Problemstellung](#-problemstellung)
|
||||||
- [🧠 Ursache](#-ursache)
|
- [🧠 Ursache](#-ursache)
|
||||||
- [✅ Lösung](#-lösung)
|
- [✅ Lösung](#-lösung)
|
||||||
- [📍 Schritt-für-Schritt-Anleitung in Plesk:](#-schritt-für-schritt-anleitung-in-plesk)
|
- [📍 Schritt-für-Schritt-Anleitung in Plesk:](#-schritt-für-schritt-anleitung-in-plesk)
|
||||||
- [🔎 Test](#-test)
|
- [🔎 Test](#-test)
|
||||||
- [🔁 Danach](#-danach)
|
- [🔁 Danach](#-danach)
|
||||||
- [✅ Status: **Funktioniert**](#-status-funktioniert)
|
- [✅ Status: **Funktioniert**](#-status-funktioniert)
|
||||||
|
|
||||||
## 🧩 Problemstellung
|
## 🧩 Problemstellung
|
||||||
|
|
||||||
Bei der Ausstellung eines SSL/TLS-Zertifikats für `gamingblogs.de` in Plesk trat folgender Fehler auf:
|
Bei der Ausstellung eines SSL/TLS-Zertifikats für `gamingblogs.de` in Plesk trat folgender Fehler auf:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|
||||||
Let's Encrypt-SSL/TLS-Zertifikat konnte nicht ausgestellt werden.
|
Let's Encrypt-SSL/TLS-Zertifikat konnte nicht ausgestellt werden.
|
||||||
Detail: Timeout during connect (likely firewall problem)
|
Detail: Timeout during connect (likely firewall problem)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Trotz funktionierendem Webserver und anderen Domains auf dem gleichen Server schlug die Zertifikatsanforderung fehl.
|
Trotz funktionierendem Webserver und anderen Domains auf dem gleichen Server schlug die Zertifikatsanforderung fehl.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧠 Ursache
|
## 🧠 Ursache
|
||||||
|
|
||||||
Let's Encrypt konnte die Validierungs-URL
|
Let's Encrypt konnte die Validierungs-URL
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|
||||||
[http://gamingblogs.de/.well-known/acme-challenge/](http://gamingblogs.de/.well-known/acme-challenge/)<token>
|
[http://gamingblogs.de/.well-known/acme-challenge/](http://gamingblogs.de/.well-known/acme-challenge/)<token>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
nicht erfolgreich aufrufen, weil der Webserver **alle HTTP-Anfragen sofort auf HTTPS umgeleitet hat**, obwohl noch **kein gültiges Zertifikat** vorhanden war.
|
nicht erfolgreich aufrufen, weil der Webserver **alle HTTP-Anfragen sofort auf HTTPS umgeleitet hat**, obwohl noch **kein gültiges Zertifikat** vorhanden war.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✅ Lösung
|
## ✅ Lösung
|
||||||
|
|
||||||
Damit Let's Encrypt den Challenge-Pfad über HTTP erreichen kann, muss der HTTPS-Redirect **ausgenommen werden**.
|
Damit Let's Encrypt den Challenge-Pfad über HTTP erreichen kann, muss der HTTPS-Redirect **ausgenommen werden**.
|
||||||
|
|
||||||
### 📍 Schritt-für-Schritt-Anleitung in Plesk:
|
### 📍 Schritt-für-Schritt-Anleitung in Plesk:
|
||||||
|
|
||||||
1. Öffne **Plesk**
|
1. Öffne **Plesk**
|
||||||
2. Navigiere zu
|
2. Navigiere zu
|
||||||
`Websites & Domains → gamingblogs.de → Apache & nginx-Einstellungen`
|
`Websites & Domains → gamingblogs.de → Apache & nginx-Einstellungen`
|
||||||
3. Scrolle zu **"Zusätzliche Apache-Anweisungen"**
|
3. Scrolle zu **"Zusätzliche Apache-Anweisungen"**
|
||||||
4. Trage Folgendes in **beide Felder (HTTP und HTTPS)** ein:
|
4. Trage Folgendes in **beide Felder (HTTP und HTTPS)** ein:
|
||||||
|
|
||||||
```apache
|
```apache
|
||||||
<IfModule mod_rewrite.c>
|
<IfModule mod_rewrite.c>
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/ [NC]
|
RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/ [NC]
|
||||||
RewriteRule ^ - [L]
|
RewriteRule ^ - [L]
|
||||||
</IfModule>
|
</IfModule>
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Falls ein HTTP-zu-HTTPS-Redirect aktiv ist, ergänze **nur im HTTP-Feld**:
|
5. Falls ein HTTP-zu-HTTPS-Redirect aktiv ist, ergänze **nur im HTTP-Feld**:
|
||||||
|
|
||||||
```apache
|
```apache
|
||||||
<IfModule mod_rewrite.c>
|
<IfModule mod_rewrite.c>
|
||||||
RewriteEngine On
|
RewriteEngine On
|
||||||
RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/ [NC]
|
RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/ [NC]
|
||||||
RewriteRule ^ - [L]
|
RewriteRule ^ - [L]
|
||||||
RewriteCond %{HTTPS} off
|
RewriteCond %{HTTPS} off
|
||||||
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||||
</IfModule>
|
</IfModule>
|
||||||
```
|
```
|
||||||
|
|
||||||
6. Speichern und warten, bis Plesk die Konfiguration neu lädt
|
6. Speichern und warten, bis Plesk die Konfiguration neu lädt
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔎 Test
|
## 🔎 Test
|
||||||
|
|
||||||
Vom externen System:
|
Vom externen System:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -I http://gamingblogs.de/.well-known/acme-challenge/test
|
curl -I http://gamingblogs.de/.well-known/acme-challenge/test
|
||||||
```
|
```
|
||||||
|
|
||||||
**Erwartetes Ergebnis:**
|
**Erwartetes Ergebnis:**
|
||||||
|
|
||||||
```http
|
```http
|
||||||
HTTP/1.1 404 Not Found
|
HTTP/1.1 404 Not Found
|
||||||
```
|
```
|
||||||
|
|
||||||
⚠️ Kein Redirect auf HTTPS, kein Timeout → Let's Encrypt kann jetzt validieren.
|
⚠️ Kein Redirect auf HTTPS, kein Timeout → Let's Encrypt kann jetzt validieren.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔁 Danach
|
## 🔁 Danach
|
||||||
|
|
||||||
In Plesk:
|
In Plesk:
|
||||||
|
|
||||||
1. Zurück zu `Websites & Domains → gamingblogs.de`
|
1. Zurück zu `Websites & Domains → gamingblogs.de`
|
||||||
2. Auf **"SSL/TLS-Zertifikat" (Let's Encrypt)** klicken
|
2. Auf **"SSL/TLS-Zertifikat" (Let's Encrypt)** klicken
|
||||||
3. Zertifikat neu **beantragen**
|
3. Zertifikat neu **beantragen**
|
||||||
4. Erfolgreiche Ausstellung wird bestätigt
|
4. Erfolgreiche Ausstellung wird bestätigt
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✅ Status: **Funktioniert**
|
## ✅ Status: **Funktioniert**
|
||||||
|
|
||||||
Datum der Umsetzung: 2025-05-22
|
Datum der Umsetzung: 2025-05-22
|
@ -1,52 +1,52 @@
|
|||||||
# Plesk ausgesperrt bei Rechnerwechsel
|
# Plesk ausgesperrt bei Rechnerwechsel
|
||||||
|
|
||||||
## Inhalt
|
## Inhalt
|
||||||
|
|
||||||
- [Plesk ausgesperrt bei Rechnerwechsel](#plesk-ausgesperrt-bei-rechnerwechsel)
|
- [Plesk ausgesperrt bei Rechnerwechsel](#plesk-ausgesperrt-bei-rechnerwechsel)
|
||||||
- [Inhalt](#inhalt)
|
- [Inhalt](#inhalt)
|
||||||
- [Problembeschreibung](#problembeschreibung)
|
- [Problembeschreibung](#problembeschreibung)
|
||||||
- [Workarround](#workarround)
|
- [Workarround](#workarround)
|
||||||
- [Nachhaltige Lösung des Problems](#nachhaltige-lösung-des-problems)
|
- [Nachhaltige Lösung des Problems](#nachhaltige-lösung-des-problems)
|
||||||
|
|
||||||
## Problembeschreibung
|
## Problembeschreibung
|
||||||
|
|
||||||
Es kommt öfter vor, das ich aus der Plesk Weboberfläche automatisch ausgeloggt werde und ein erneuter Login anschliessend nicht mehr möglich ist.
|
Es kommt öfter vor, das ich aus der Plesk Weboberfläche automatisch ausgeloggt werde und ein erneuter Login anschliessend nicht mehr möglich ist.
|
||||||
Die genaue Ursache ist mir nicht eindeutig bekannt aber ich vermute das im Browser irgendwelche Sessions gelöscht werden.
|
Die genaue Ursache ist mir nicht eindeutig bekannt aber ich vermute das im Browser irgendwelche Sessions gelöscht werden.
|
||||||
Als erstes habe ich in meinem Brave-Browser den Schutz für explizit diese Seite deaktiviert.
|
Als erstes habe ich in meinem Brave-Browser den Schutz für explizit diese Seite deaktiviert.
|
||||||
Um mich wieder einloggen zu können, muss ich die Session auf dem Server von hand aus der Datenbank löschen.
|
Um mich wieder einloggen zu können, muss ich die Session auf dem Server von hand aus der Datenbank löschen.
|
||||||
|
|
||||||
### Workarround
|
### Workarround
|
||||||
|
|
||||||
**Plesk Version:** Plesk Obsidian Web Admin Edition 18.0.70
|
**Plesk Version:** Plesk Obsidian Web Admin Edition 18.0.70
|
||||||
|
|
||||||
Bei Plesk gibt es manchmal die gloreiche Meldung:
|
Bei Plesk gibt es manchmal die gloreiche Meldung:
|
||||||
|
|
||||||
> Sie konnten nicht angemeldet werden.
|
> Sie konnten nicht angemeldet werden.
|
||||||
> **Ein anderer Benutzer mit demselben Benutzernamen (benutzername) ist bereits bei Plesk angemeldet.**
|
> **Ein anderer Benutzer mit demselben Benutzernamen (benutzername) ist bereits bei Plesk angemeldet.**
|
||||||
|
|
||||||
Ärgerlich wenn das gerade der Adminzugang ist.
|
Ärgerlich wenn das gerade der Adminzugang ist.
|
||||||
Falls Du gerade noch SSH Zugang hast dann:
|
Falls Du gerade noch SSH Zugang hast dann:
|
||||||
|
|
||||||
login und wechsel zum root, anschliessend:
|
login und wechsel zum root, anschliessend:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
plesk db "DELETE FROM sessions WHERE login = 'admin';"
|
plesk db "DELETE FROM sessions WHERE login = 'admin';"
|
||||||
```
|
```
|
||||||
|
|
||||||
**oder**
|
**oder**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mysql -uadmin -p$(cat /etc/psa/.psa.shadow) psa -e "DELETE FROM sessions WHERE login = 'admin';"
|
mysql -uadmin -p$(cat /etc/psa/.psa.shadow) psa -e "DELETE FROM sessions WHERE login = 'admin';"
|
||||||
```
|
```
|
||||||
|
|
||||||
anschliessend:
|
anschliessend:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
systemctl restart psa
|
systemctl restart psa
|
||||||
```
|
```
|
||||||
|
|
||||||
und dann ganz normal Login wie gewohnt.
|
und dann ganz normal Login wie gewohnt.
|
||||||
|
|
||||||
### Nachhaltige Lösung des Problems
|
### Nachhaltige Lösung des Problems
|
||||||
|
|
||||||
aktuell nicht bekannt!
|
aktuell nicht bekannt!
|
||||||
|
@ -1,152 +1,152 @@
|
|||||||
# Erstellung eines Installationsmediums für Rust + MSVC (Offline)
|
# Erstellung eines Installationsmediums für Rust + MSVC (Offline)
|
||||||
|
|
||||||
Dieser Artikel beschreibt, wie du ein **vollständiges Installationsmedium** für die **Rust-Toolchain mit MSVC** unter Windows vorbereitest, damit du Rust auf anderen Rechnern **ohne Internetzugang** einrichten kannst.
|
Dieser Artikel beschreibt, wie du ein **vollständiges Installationsmedium** für die **Rust-Toolchain mit MSVC** unter Windows vorbereitest, damit du Rust auf anderen Rechnern **ohne Internetzugang** einrichten kannst.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Ziel
|
## Ziel
|
||||||
|
|
||||||
Ein USB-Stick oder Offline-Verzeichnis mit:
|
Ein USB-Stick oder Offline-Verzeichnis mit:
|
||||||
|
|
||||||
- Rust-Installer (offlinefähig)
|
- Rust-Installer (offlinefähig)
|
||||||
- Visual Studio Build Tools (komplett inkl. MSVC)
|
- Visual Studio Build Tools (komplett inkl. MSVC)
|
||||||
- Optional: vorkompilierte Ziel-Toolchains
|
- Optional: vorkompilierte Ziel-Toolchains
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Rust Offline-Installer vorbereiten
|
## 1. Rust Offline-Installer vorbereiten
|
||||||
|
|
||||||
### 1.1 Rustup Offline-Installer besorgen
|
### 1.1 Rustup Offline-Installer besorgen
|
||||||
|
|
||||||
Gehe auf:
|
Gehe auf:
|
||||||
|
|
||||||
https://forge.rust-lang.org/infra/release-archives.html
|
https://forge.rust-lang.org/infra/release-archives.html
|
||||||
|
|
||||||
Lade von dort:
|
Lade von dort:
|
||||||
|
|
||||||
- `rust-<version>-x86_64-pc-windows-msvc.msi`
|
- `rust-<version>-x86_64-pc-windows-msvc.msi`
|
||||||
- `cargo-<version>-x86_64-pc-windows-msvc.msi` (optional)
|
- `cargo-<version>-x86_64-pc-windows-msvc.msi` (optional)
|
||||||
|
|
||||||
Oder direkt über:
|
Oder direkt über:
|
||||||
|
|
||||||
https://static.rust-lang.org/dist/
|
https://static.rust-lang.org/dist/
|
||||||
|
|
||||||
### 1.2 Installation ohne Internet
|
### 1.2 Installation ohne Internet
|
||||||
|
|
||||||
Auf dem Zielrechner:
|
Auf dem Zielrechner:
|
||||||
|
|
||||||
- Führe `.msi`-Datei lokal aus
|
- Führe `.msi`-Datei lokal aus
|
||||||
- Setze den `Path` manuell oder automatisch via Skript
|
- Setze den `Path` manuell oder automatisch via Skript
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Visual Studio Build Tools offline installieren
|
## 2. Visual Studio Build Tools offline installieren
|
||||||
|
|
||||||
### 2.1 Installer herunterladen
|
### 2.1 Installer herunterladen
|
||||||
|
|
||||||
Lade den **Visual Studio Installer** von:
|
Lade den **Visual Studio Installer** von:
|
||||||
|
|
||||||
https://visualstudio.microsoft.com/de/visual-cpp-build-tools/
|
https://visualstudio.microsoft.com/de/visual-cpp-build-tools/
|
||||||
|
|
||||||
Starte dann:
|
Starte dann:
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
vs_BuildTools.exe --layout C:\VSOffline --lang de-DE
|
vs_BuildTools.exe --layout C:\VSOffline --lang de-DE
|
||||||
```
|
```
|
||||||
|
|
||||||
Dieser Befehl erstellt einen vollständigen Offline-Installer im Verzeichnis `C:\VSOffline`.
|
Dieser Befehl erstellt einen vollständigen Offline-Installer im Verzeichnis `C:\VSOffline`.
|
||||||
|
|
||||||
### 2.2 Auswahl der Workloads
|
### 2.2 Auswahl der Workloads
|
||||||
|
|
||||||
Wähle beim interaktiven Download (GUI oder CLI):
|
Wähle beim interaktiven Download (GUI oder CLI):
|
||||||
|
|
||||||
- **C++ Build Tools**
|
- **C++ Build Tools**
|
||||||
- Workload-Komponenten:
|
- Workload-Komponenten:
|
||||||
- MSVC v14.x (x64/x86)
|
- MSVC v14.x (x64/x86)
|
||||||
- Windows 10/11 SDK
|
- Windows 10/11 SDK
|
||||||
- CMake-Tools (optional)
|
- CMake-Tools (optional)
|
||||||
|
|
||||||
> 💡 Achtung: Download-Größe ca. 4–6 GB!
|
> 💡 Achtung: Download-Größe ca. 4–6 GB!
|
||||||
|
|
||||||
### 2.3 Installation auf Zielsystem (Offline)
|
### 2.3 Installation auf Zielsystem (Offline)
|
||||||
|
|
||||||
Auf dem Zielrechner:
|
Auf dem Zielrechner:
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
C:\VSOffline\vs_BuildTools.exe --noweb --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --quiet --wait
|
C:\VSOffline\vs_BuildTools.exe --noweb --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --quiet --wait
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternativ über `vs_setup.exe`, je nach Version.
|
Alternativ über `vs_setup.exe`, je nach Version.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. Optional: Toolchains, Crates & Targets vorbereiten
|
## 3. Optional: Toolchains, Crates & Targets vorbereiten
|
||||||
|
|
||||||
Falls du zusätzliche Targets (z. B. Linux oder ARM) brauchst:
|
Falls du zusätzliche Targets (z. B. Linux oder ARM) brauchst:
|
||||||
|
|
||||||
### 3.1 Ziel-Toolchain lokal laden
|
### 3.1 Ziel-Toolchain lokal laden
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
rustup target add x86_64-unknown-linux-gnu --print
|
rustup target add x86_64-unknown-linux-gnu --print
|
||||||
```
|
```
|
||||||
|
|
||||||
Lade die `.tar.gz` von:
|
Lade die `.tar.gz` von:
|
||||||
|
|
||||||
https://static.rust-lang.org/dist/
|
https://static.rust-lang.org/dist/
|
||||||
|
|
||||||
Speichere diese im `dist/`-Ordner und installiere offline via:
|
Speichere diese im `dist/`-Ordner und installiere offline via:
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
rustup toolchain link <name> <pfad_zur_toolchain>
|
rustup toolchain link <name> <pfad_zur_toolchain>
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Automatisierung via USB-Stick
|
## 4. Automatisierung via USB-Stick
|
||||||
|
|
||||||
### Dateistruktur auf Stick
|
### Dateistruktur auf Stick
|
||||||
|
|
||||||
```text
|
```text
|
||||||
USB-STICK/
|
USB-STICK/
|
||||||
├── rust/
|
├── rust/
|
||||||
│ └── rust-1.xx.x-x86_64-pc-windows-msvc.msi
|
│ └── rust-1.xx.x-x86_64-pc-windows-msvc.msi
|
||||||
├── vsbuildtools/
|
├── vsbuildtools/
|
||||||
│ └── setup + Offline-Daten
|
│ └── setup + Offline-Daten
|
||||||
├── install.cmd
|
├── install.cmd
|
||||||
```
|
```
|
||||||
|
|
||||||
### Beispiel `install.cmd`
|
### Beispiel `install.cmd`
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
@echo off
|
@echo off
|
||||||
echo [1/2] Installiere Rust...
|
echo [1/2] Installiere Rust...
|
||||||
start /wait rust\rust-*.msi
|
start /wait rust\rust-*.msi
|
||||||
|
|
||||||
echo [2/2] Installiere Visual Studio Build Tools...
|
echo [2/2] Installiere Visual Studio Build Tools...
|
||||||
start /wait vsbuildtools\vs_BuildTools.exe --noweb --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --quiet --wait
|
start /wait vsbuildtools\vs_BuildTools.exe --noweb --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --quiet --wait
|
||||||
|
|
||||||
echo Fertig. Bitte PC neu starten!
|
echo Fertig. Bitte PC neu starten!
|
||||||
pause
|
pause
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Validierung
|
## 5. Validierung
|
||||||
|
|
||||||
Nach der Offline-Installation auf Zielsystem:
|
Nach der Offline-Installation auf Zielsystem:
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
cargo new testprojekt
|
cargo new testprojekt
|
||||||
cd testprojekt
|
cd testprojekt
|
||||||
cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
|
|
||||||
Ergebnis:
|
Ergebnis:
|
||||||
|
|
||||||
target\release\testprojekt.exe
|
target\release\testprojekt.exe
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Fazit
|
## Fazit
|
||||||
|
|
||||||
Mit dieser Methode kannst du eine vollständige Rust- und MSVC-Umgebung offline auf jedem Windows-System aufsetzen – ideal für abgeschottete Systeme ohne Internetverbindung.
|
Mit dieser Methode kannst du eine vollständige Rust- und MSVC-Umgebung offline auf jedem Windows-System aufsetzen – ideal für abgeschottete Systeme ohne Internetverbindung.
|
||||||
|
@ -1,152 +1,152 @@
|
|||||||
# Rust-Toolchain mit MSVC unter Windows einrichten
|
# Rust-Toolchain mit MSVC unter Windows einrichten
|
||||||
|
|
||||||
Dieser Artikel beschreibt die vollständige Einrichtung einer produktionsfähigen Rust-Toolchain mit **MSVC (Microsoft Visual C++)** unter **Windows**, einschließlich Erstellung einer `.exe`-Datei aus einem Beispielprogramm.
|
Dieser Artikel beschreibt die vollständige Einrichtung einer produktionsfähigen Rust-Toolchain mit **MSVC (Microsoft Visual C++)** unter **Windows**, einschließlich Erstellung einer `.exe`-Datei aus einem Beispielprogramm.
|
||||||
|
|
||||||
## Inhalt
|
## Inhalt
|
||||||
|
|
||||||
- [Rust-Toolchain mit MSVC unter Windows einrichten](#rust-toolchain-mit-msvc-unter-windows-einrichten)
|
- [Rust-Toolchain mit MSVC unter Windows einrichten](#rust-toolchain-mit-msvc-unter-windows-einrichten)
|
||||||
- [Inhalt](#inhalt)
|
- [Inhalt](#inhalt)
|
||||||
- [Voraussetzungen](#voraussetzungen)
|
- [Voraussetzungen](#voraussetzungen)
|
||||||
- [1. Rust installieren](#1-rust-installieren)
|
- [1. Rust installieren](#1-rust-installieren)
|
||||||
- [2. Visual Studio Build Tools installieren](#2-visual-studio-build-tools-installieren)
|
- [2. Visual Studio Build Tools installieren](#2-visual-studio-build-tools-installieren)
|
||||||
- [Schritt-für-Schritt](#schritt-für-schritt)
|
- [Schritt-für-Schritt](#schritt-für-schritt)
|
||||||
- [3. Umgebungsvariablen setzen (optional)](#3-umgebungsvariablen-setzen-optional)
|
- [3. Umgebungsvariablen setzen (optional)](#3-umgebungsvariablen-setzen-optional)
|
||||||
- [4. Beispielprojekt erstellen](#4-beispielprojekt-erstellen)
|
- [4. Beispielprojekt erstellen](#4-beispielprojekt-erstellen)
|
||||||
- [5. Projekt kompilieren](#5-projekt-kompilieren)
|
- [5. Projekt kompilieren](#5-projekt-kompilieren)
|
||||||
- [Debug-Build (schnell, nicht optimiert)](#debug-build-schnell-nicht-optimiert)
|
- [Debug-Build (schnell, nicht optimiert)](#debug-build-schnell-nicht-optimiert)
|
||||||
- [Release-Build (optimiert, kleine `.exe`)](#release-build-optimiert-kleine-exe)
|
- [Release-Build (optimiert, kleine `.exe`)](#release-build-optimiert-kleine-exe)
|
||||||
- [6. Optional: `.exe` testen](#6-optional-exe-testen)
|
- [6. Optional: `.exe` testen](#6-optional-exe-testen)
|
||||||
- [7. Troubleshooting](#7-troubleshooting)
|
- [7. Troubleshooting](#7-troubleshooting)
|
||||||
- [8. Alternative: Toolchain in einem Offline-Installer vorbereiten](#8-alternative-toolchain-in-einem-offline-installer-vorbereiten)
|
- [8. Alternative: Toolchain in einem Offline-Installer vorbereiten](#8-alternative-toolchain-in-einem-offline-installer-vorbereiten)
|
||||||
- [Zusammenfassung](#zusammenfassung)
|
- [Zusammenfassung](#zusammenfassung)
|
||||||
- [Weiterführende Themen](#weiterführende-themen)
|
- [Weiterführende Themen](#weiterführende-themen)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Voraussetzungen
|
## Voraussetzungen
|
||||||
|
|
||||||
- Windows 10 oder 11 (64 Bit)
|
- Windows 10 oder 11 (64 Bit)
|
||||||
- Administratorrechte
|
- Administratorrechte
|
||||||
- Mindestens 2 GB freier Speicherplatz
|
- Mindestens 2 GB freier Speicherplatz
|
||||||
|
|
||||||
## 1. Rust installieren
|
## 1. Rust installieren
|
||||||
|
|
||||||
Lade das offizielle Rust-Installationsprogramm herunter und führe es aus:
|
Lade das offizielle Rust-Installationsprogramm herunter und führe es aus:
|
||||||
|
|
||||||
<https://rustup.rs>
|
<https://rustup.rs>
|
||||||
|
|
||||||
Beim Setup:
|
Beim Setup:
|
||||||
|
|
||||||
- **Toolchain wählen**: `default host triple: x86_64-pc-windows-msvc`
|
- **Toolchain wählen**: `default host triple: x86_64-pc-windows-msvc`
|
||||||
- Folge dem Assistenten, um `rustc`, `cargo` und `rustup` zu installieren.
|
- Folge dem Assistenten, um `rustc`, `cargo` und `rustup` zu installieren.
|
||||||
|
|
||||||
Verifiziere die Installation:
|
Verifiziere die Installation:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
rustc --version
|
rustc --version
|
||||||
cargo --version
|
cargo --version
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. Visual Studio Build Tools installieren
|
## 2. Visual Studio Build Tools installieren
|
||||||
|
|
||||||
Die Rust-Toolchain mit MSVC benötigt den **"C++ Build Tools"**-Teil von Visual Studio.
|
Die Rust-Toolchain mit MSVC benötigt den **"C++ Build Tools"**-Teil von Visual Studio.
|
||||||
|
|
||||||
### Schritt-für-Schritt
|
### Schritt-für-Schritt
|
||||||
|
|
||||||
1. Lade den **Visual Studio Installer**:
|
1. Lade den **Visual Studio Installer**:
|
||||||
- <https://visualstudio.microsoft.com/de/visual-cpp-build-tools/>
|
- <https://visualstudio.microsoft.com/de/visual-cpp-build-tools/>
|
||||||
|
|
||||||
2. Wähle bei der Installation:
|
2. Wähle bei der Installation:
|
||||||
- ✅ **C++ Build Tools**
|
- ✅ **C++ Build Tools**
|
||||||
- Und in der rechten Spalte:
|
- Und in der rechten Spalte:
|
||||||
- ✅ "MSVC v14.x - VS 2022 C++ x64/x86-Buildtools"
|
- ✅ "MSVC v14.x - VS 2022 C++ x64/x86-Buildtools"
|
||||||
- ✅ "Windows 10 SDK" oder "Windows 11 SDK" (je nach Zielsystem)
|
- ✅ "Windows 10 SDK" oder "Windows 11 SDK" (je nach Zielsystem)
|
||||||
- ✅ "C++ CMake-Tools für Windows" (optional für CMake-Projekte)
|
- ✅ "C++ CMake-Tools für Windows" (optional für CMake-Projekte)
|
||||||
|
|
||||||
3. Installiere alles und starte das System neu, falls verlangt.
|
3. Installiere alles und starte das System neu, falls verlangt.
|
||||||
|
|
||||||
## 3. Umgebungsvariablen setzen (optional)
|
## 3. Umgebungsvariablen setzen (optional)
|
||||||
|
|
||||||
Falls du die Buildtools über Kommandozeile verwenden willst, öffne:
|
Falls du die Buildtools über Kommandozeile verwenden willst, öffne:
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
|
"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
|
||||||
```
|
```
|
||||||
|
|
||||||
Das setzt temporär alle notwendigen Umgebungsvariablen für den Build-Prozess.
|
Das setzt temporär alle notwendigen Umgebungsvariablen für den Build-Prozess.
|
||||||
|
|
||||||
## 4. Beispielprojekt erstellen
|
## 4. Beispielprojekt erstellen
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
cargo new hello_world
|
cargo new hello_world
|
||||||
cd hello_world
|
cd hello_world
|
||||||
```
|
```
|
||||||
|
|
||||||
Beispielcode in `src/main.rs`:
|
Beispielcode in `src/main.rs`:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hallo Welt – kompiliert mit MSVC!");
|
println!("Hallo Welt – kompiliert mit MSVC!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 5. Projekt kompilieren
|
## 5. Projekt kompilieren
|
||||||
|
|
||||||
### Debug-Build (schnell, nicht optimiert)
|
### Debug-Build (schnell, nicht optimiert)
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
cargo build
|
cargo build
|
||||||
```
|
```
|
||||||
|
|
||||||
### Release-Build (optimiert, kleine `.exe`)
|
### Release-Build (optimiert, kleine `.exe`)
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
|
|
||||||
Die fertige `.exe` liegt unter:
|
Die fertige `.exe` liegt unter:
|
||||||
|
|
||||||
.\target\release\hello_world.exe
|
.\target\release\hello_world.exe
|
||||||
|
|
||||||
## 6. Optional: `.exe` testen
|
## 6. Optional: `.exe` testen
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
.\target\release\hello_world.exe
|
.\target\release\hello_world.exe
|
||||||
```
|
```
|
||||||
|
|
||||||
## 7. Troubleshooting
|
## 7. Troubleshooting
|
||||||
|
|
||||||
- **Fehlermeldung `link.exe not found`?**
|
- **Fehlermeldung `link.exe not found`?**
|
||||||
→ Build-Tools sind nicht korrekt installiert (siehe Schritt 2)
|
→ Build-Tools sind nicht korrekt installiert (siehe Schritt 2)
|
||||||
|
|
||||||
- **Fehlermeldung zu fehlendem SDK?**
|
- **Fehlermeldung zu fehlendem SDK?**
|
||||||
→ Stelle sicher, dass du das passende Windows SDK mit installiert hast
|
→ Stelle sicher, dass du das passende Windows SDK mit installiert hast
|
||||||
|
|
||||||
- **MSVC und GNU Toolchain gleichzeitig installiert?**
|
- **MSVC und GNU Toolchain gleichzeitig installiert?**
|
||||||
→ Du kannst über `rustup` zwischen beiden wechseln:
|
→ Du kannst über `rustup` zwischen beiden wechseln:
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
rustup show
|
rustup show
|
||||||
rustup default stable-x86_64-pc-windows-msvc
|
rustup default stable-x86_64-pc-windows-msvc
|
||||||
```
|
```
|
||||||
|
|
||||||
## 8. Alternative: Toolchain in einem Offline-Installer vorbereiten
|
## 8. Alternative: Toolchain in einem Offline-Installer vorbereiten
|
||||||
|
|
||||||
Wenn du das Setup auf mehreren Rechnern ohne Internetzugang durchführen möchtest, siehe [separater Artikel zur Erstellung eines Installationsmediums](./rust-offline-installation.md).
|
Wenn du das Setup auf mehreren Rechnern ohne Internetzugang durchführen möchtest, siehe [separater Artikel zur Erstellung eines Installationsmediums](./rust-offline-installation.md).
|
||||||
|
|
||||||
## Zusammenfassung
|
## Zusammenfassung
|
||||||
|
|
||||||
| Komponente | Aufgabe |
|
| Komponente | Aufgabe |
|
||||||
|------------------|----------------------------------|
|
|------------------|----------------------------------|
|
||||||
| Rustup | Verwaltung von Toolchains |
|
| Rustup | Verwaltung von Toolchains |
|
||||||
| Cargo | Buildsystem und Paketmanager |
|
| Cargo | Buildsystem und Paketmanager |
|
||||||
| MSVC Build Tools | C++-Compiler/Linker für Windows |
|
| MSVC Build Tools | C++-Compiler/Linker für Windows |
|
||||||
| `vcvars64.bat` | Aktiviert Build-Umgebung |
|
| `vcvars64.bat` | Aktiviert Build-Umgebung |
|
||||||
| `cargo build` | Erstellt `.exe` mit Rust und MSVC |
|
| `cargo build` | Erstellt `.exe` mit Rust und MSVC |
|
||||||
|
|
||||||
## Weiterführende Themen
|
## Weiterführende Themen
|
||||||
|
|
||||||
- Einbindung von Ressourcen und Icons in die `.exe`
|
- Einbindung von Ressourcen und Icons in die `.exe`
|
||||||
- Verwendung von `cc`/`bindgen` für C-Bindings
|
- Verwendung von `cc`/`bindgen` für C-Bindings
|
||||||
- Cross-Kompilierung mit `x86_64-pc-windows-gnu` oder Linux-Zielsystemen
|
- Cross-Kompilierung mit `x86_64-pc-windows-gnu` oder Linux-Zielsystemen
|
||||||
- Automatisierter Build via Makefile oder PowerShell
|
- Automatisierter Build via Makefile oder PowerShell
|
||||||
|
158
dokus/webserver/nginx-proxy-manager-setup.md
Normal file
158
dokus/webserver/nginx-proxy-manager-setup.md
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
|
||||||
|
# NGINX Proxy Manager als Reverse Proxy für Node.js-Apps
|
||||||
|
|
||||||
|
>**Letzte Änderung:** 27.06.2025
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- [NGINX Proxy Manager als Reverse Proxy für Node.js-Apps](#nginx-proxy-manager-als-reverse-proxy-für-nodejs-apps)
|
||||||
|
- [Ziel](#ziel)
|
||||||
|
- [Voraussetzungen](#voraussetzungen)
|
||||||
|
- [Verzeichnisstruktur](#verzeichnisstruktur)
|
||||||
|
- [docker-compose.yml](#docker-composeyml)
|
||||||
|
- [Starten](#starten)
|
||||||
|
- [Zugriff auf Web-GUI](#zugriff-auf-web-gui)
|
||||||
|
- [Proxy-Host anlegen](#proxy-host-anlegen)
|
||||||
|
- [Ergebnis](#ergebnis)
|
||||||
|
- [Hinweise](#hinweise)
|
||||||
|
- [Optional: Node.js-Apps als systemd-Service verwalten](#optional-nodejs-apps-als-systemd-service-verwalten)
|
||||||
|
- [Fertig](#fertig)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
|
||||||
|
- Node.js-Apps im LAN per HTTPS erreichbar machen
|
||||||
|
- Let's Encrypt Zertifikate automatisch verwalten
|
||||||
|
- Einfaches Management über Web-GUI
|
||||||
|
- Kein manuelles Bearbeiten von NGINX-Konfigurationen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
- Server mit Debian 12 oder kompatibel
|
||||||
|
- Docker und Docker Compose installiert
|
||||||
|
- Ports 80/443 sind frei
|
||||||
|
- Fritzbox leitet Ports 80/443 auf den Server weiter
|
||||||
|
- Domain zeigt per A-Record auf die öffentliche IP
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verzeichnisstruktur
|
||||||
|
|
||||||
|
Empfohlenes Setup unter `/opt/nginx-proxy-manager/`:
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
/opt/nginx-proxy-manager/
|
||||||
|
├── docker-compose.yml
|
||||||
|
├── data/ # Konfigurationsdaten von NGINX Proxy Manager
|
||||||
|
└── letsencrypt/ # SSL-Zertifikate
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## docker-compose.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
nginx-proxy-manager:
|
||||||
|
image: 'jc21/nginx-proxy-manager:latest'
|
||||||
|
container_name: nginx-proxy-manager
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- '80:80' # HTTP
|
||||||
|
- '443:443' # HTTPS
|
||||||
|
- '81:81' # Admin UI
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
|
- ./letsencrypt:/etc/letsencrypt
|
||||||
|
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Berlin
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Starten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/nginx-proxy-manager
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Zugriff auf Web-GUI
|
||||||
|
|
||||||
|
- URL: `http://<SERVER-IP>:81`
|
||||||
|
- Standard-Zugang:
|
||||||
|
- Benutzer: `admin@example.com`
|
||||||
|
- Passwort: `changeme`
|
||||||
|
- Zugangsdaten nach erstem Login ändern.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Proxy-Host anlegen
|
||||||
|
|
||||||
|
1. „Proxy Hosts“ → „Add Proxy Host“
|
||||||
|
2. Domain Name: `app1.domain.de`
|
||||||
|
3. Scheme: `http`
|
||||||
|
4. Forward Hostname/IP: `192.168.178.11`
|
||||||
|
5. Forward Port: `3000`
|
||||||
|
6. SSL aktivieren → „Request a new SSL Certificate“ → Let's Encrypt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ergebnis
|
||||||
|
|
||||||
|
- Externe Anfragen an `app1.domain.de` werden via HTTPS von NGINX Proxy Manager entgegengenommen.
|
||||||
|
- Intern wird die Anfrage an `192.168.178.11:3000` (Node.js-App) weitergeleitet.
|
||||||
|
- Zertifikate werden automatisch verwaltet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hinweise
|
||||||
|
|
||||||
|
✅ Kein systemweiter NGINX mehr erforderlich.
|
||||||
|
✅ Ports 80/443 werden vollständig vom Container belegt.
|
||||||
|
✅ Einfach skalierbar für mehrere Domains und Apps.
|
||||||
|
✅ Wartbar über die Weboberfläche, keine manuelle Konfigurationsarbeit.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Optional: Node.js-Apps als systemd-Service verwalten
|
||||||
|
|
||||||
|
Beispiel für eine Datei `/etc/systemd/system/myapp.service`:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Meine Node.js App
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/bin/node /opt/myapp/index.js
|
||||||
|
Restart=on-failure
|
||||||
|
User=www-data
|
||||||
|
Environment=NODE_ENV=production
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Aktivieren und starten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl enable myapp
|
||||||
|
systemctl start myapp
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fertig
|
||||||
|
|
||||||
|
Dein Setup ist jetzt produktionsbereit.
|
@ -1,177 +1,177 @@
|
|||||||
# Einführung in die `desktop.ini`-Datei: Verwendung und Anpassung von Ordnern in Windows
|
# Einführung in die `desktop.ini`-Datei: Verwendung und Anpassung von Ordnern in Windows
|
||||||
|
|
||||||
*2025 - Adam Skotarczak*
|
*2025 - Adam Skotarczak*
|
||||||
|
|
||||||
Die `desktop.ini`-Datei ist eine wichtige, jedoch wenig bekannte Datei in Windows, die zur Konfiguration und Anpassung von Ordnern verwendet wird. Sie ermöglicht es Benutzern, das Erscheinungsbild und Verhalten von Ordnern anzupassen, indem sie Einstellungen wie Symbole, Tooltips und Ordnerspezifikationen definiert. In diesem Artikel werden wir die Funktionsweise der `desktop.ini`-Datei ausführlich erklären und alle Optionen und Attribute vorstellen, die in dieser Datei verwendet werden können.
|
Die `desktop.ini`-Datei ist eine wichtige, jedoch wenig bekannte Datei in Windows, die zur Konfiguration und Anpassung von Ordnern verwendet wird. Sie ermöglicht es Benutzern, das Erscheinungsbild und Verhalten von Ordnern anzupassen, indem sie Einstellungen wie Symbole, Tooltips und Ordnerspezifikationen definiert. In diesem Artikel werden wir die Funktionsweise der `desktop.ini`-Datei ausführlich erklären und alle Optionen und Attribute vorstellen, die in dieser Datei verwendet werden können.
|
||||||
|
|
||||||
## Inhaltsverzeichnis
|
## Inhaltsverzeichnis
|
||||||
|
|
||||||
- [Einführung in die `desktop.ini`-Datei: Verwendung und Anpassung von Ordnern in Windows](#einführung-in-die-desktopini-datei-verwendung-und-anpassung-von-ordnern-in-windows)
|
- [Einführung in die `desktop.ini`-Datei: Verwendung und Anpassung von Ordnern in Windows](#einführung-in-die-desktopini-datei-verwendung-und-anpassung-von-ordnern-in-windows)
|
||||||
- [Inhaltsverzeichnis](#inhaltsverzeichnis)
|
- [Inhaltsverzeichnis](#inhaltsverzeichnis)
|
||||||
- [Was ist die `desktop.ini`-Datei?](#was-ist-die-desktopini-datei)
|
- [Was ist die `desktop.ini`-Datei?](#was-ist-die-desktopini-datei)
|
||||||
- [Grundlegende Struktur der `desktop.ini`](#grundlegende-struktur-der-desktopini)
|
- [Grundlegende Struktur der `desktop.ini`](#grundlegende-struktur-der-desktopini)
|
||||||
- [Wichtige Optionen und Attribute](#wichtige-optionen-und-attribute)
|
- [Wichtige Optionen und Attribute](#wichtige-optionen-und-attribute)
|
||||||
- [Optionen in der `[General]`-Sektion](#optionen-in-der-general-sektion)
|
- [Optionen in der `[General]`-Sektion](#optionen-in-der-general-sektion)
|
||||||
- [Optionen in der `[View]`-Sektion](#optionen-in-der-view-sektion)
|
- [Optionen in der `[View]`-Sektion](#optionen-in-der-view-sektion)
|
||||||
- [Optionen in der `[Icon]`-Sektion](#optionen-in-der-icon-sektion)
|
- [Optionen in der `[Icon]`-Sektion](#optionen-in-der-icon-sektion)
|
||||||
- [Optionen in der `[LocalizedFileNames]`-Sektion](#optionen-in-der-localizedfilenames-sektion)
|
- [Optionen in der `[LocalizedFileNames]`-Sektion](#optionen-in-der-localizedfilenames-sektion)
|
||||||
- [Optionen in der `[ShellClassInfo]`-Sektion](#optionen-in-der-shellclassinfo-sektion)
|
- [Optionen in der `[ShellClassInfo]`-Sektion](#optionen-in-der-shellclassinfo-sektion)
|
||||||
- [Kommentare in der `desktop.ini`](#kommentare-in-der-desktopini)
|
- [Kommentare in der `desktop.ini`](#kommentare-in-der-desktopini)
|
||||||
- [Die Bedeutung von Attributen und Rechten der `desktop.ini`](#die-bedeutung-von-attributen-und-rechten-der-desktopini)
|
- [Die Bedeutung von Attributen und Rechten der `desktop.ini`](#die-bedeutung-von-attributen-und-rechten-der-desktopini)
|
||||||
- [Rechte für die `desktop.ini` unter Windows setzen](#rechte-für-die-desktopini-unter-windows-setzen)
|
- [Rechte für die `desktop.ini` unter Windows setzen](#rechte-für-die-desktopini-unter-windows-setzen)
|
||||||
- [Verwendung der `desktop.ini` auf NAS-Laufwerken](#verwendung-der-desktopini-auf-nas-laufwerken)
|
- [Verwendung der `desktop.ini` auf NAS-Laufwerken](#verwendung-der-desktopini-auf-nas-laufwerken)
|
||||||
- [Fazit](#fazit)
|
- [Fazit](#fazit)
|
||||||
|
|
||||||
## Was ist die `desktop.ini`-Datei?
|
## Was ist die `desktop.ini`-Datei?
|
||||||
|
|
||||||
Die `desktop.ini`-Datei ist eine Systemdatei in Microsoft Windows, die zur Anpassung von Ordnersymbolen, Tooltips und anderen Ordnerattributen verwendet wird. Diese Datei ermöglicht es, das Aussehen und Verhalten eines Ordners zu verändern, ohne dass zusätzliche Software erforderlich ist. Sie befindet sich normalerweise im Ordner, für den sie Einstellungen vornimmt, und beeinflusst nur diesen Ordner.
|
Die `desktop.ini`-Datei ist eine Systemdatei in Microsoft Windows, die zur Anpassung von Ordnersymbolen, Tooltips und anderen Ordnerattributen verwendet wird. Diese Datei ermöglicht es, das Aussehen und Verhalten eines Ordners zu verändern, ohne dass zusätzliche Software erforderlich ist. Sie befindet sich normalerweise im Ordner, für den sie Einstellungen vornimmt, und beeinflusst nur diesen Ordner.
|
||||||
|
|
||||||
## Grundlegende Struktur der `desktop.ini`
|
## Grundlegende Struktur der `desktop.ini`
|
||||||
|
|
||||||
Die `desktop.ini`-Datei ist eine INI-Datei, die aus verschiedenen Sektionen und Key-Value-Paaren besteht. Sie enthält spezifische Anweisungen für den Ordner, in dem sie sich befindet. Die wichtigsten Sektionen sind:
|
Die `desktop.ini`-Datei ist eine INI-Datei, die aus verschiedenen Sektionen und Key-Value-Paaren besteht. Sie enthält spezifische Anweisungen für den Ordner, in dem sie sich befindet. Die wichtigsten Sektionen sind:
|
||||||
|
|
||||||
- `[General]`: Enthält grundlegende Informationen zum Ordner, wie den Namen und den Tooltip.
|
- `[General]`: Enthält grundlegende Informationen zum Ordner, wie den Namen und den Tooltip.
|
||||||
- `[View]`: Steuert die Anzeigeeinstellungen des Ordners.
|
- `[View]`: Steuert die Anzeigeeinstellungen des Ordners.
|
||||||
- `[Icon]`: Definiert das Symbol des Ordners.
|
- `[Icon]`: Definiert das Symbol des Ordners.
|
||||||
- `[LocalizedFileNames]`: Bietet die Möglichkeit, Ordnernamen in verschiedenen Sprachen anzuzeigen.
|
- `[LocalizedFileNames]`: Bietet die Möglichkeit, Ordnernamen in verschiedenen Sprachen anzuzeigen.
|
||||||
- `[ShellClassInfo]`: Beinhaltet erweiterte Einstellungen für den Ordner, wie das Symbol und zusätzliche Eigenschaften.
|
- `[ShellClassInfo]`: Beinhaltet erweiterte Einstellungen für den Ordner, wie das Symbol und zusätzliche Eigenschaften.
|
||||||
|
|
||||||
## Wichtige Optionen und Attribute
|
## Wichtige Optionen und Attribute
|
||||||
|
|
||||||
### Optionen in der `[General]`-Sektion
|
### Optionen in der `[General]`-Sektion
|
||||||
|
|
||||||
- **`Name`**: Der Name des Ordners, der im Windows Explorer angezeigt wird.
|
- **`Name`**: Der Name des Ordners, der im Windows Explorer angezeigt wird.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
Name=Mein Ordner
|
Name=Mein Ordner
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`InfoTip`**: Ein Tooltip, der angezeigt wird, wenn der Benutzer mit der Maus über den Ordner fährt.
|
- **`InfoTip`**: Ein Tooltip, der angezeigt wird, wenn der Benutzer mit der Maus über den Ordner fährt.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
InfoTip=Dies ist ein wichtiger Ordner.
|
InfoTip=Dies ist ein wichtiger Ordner.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Optionen in der `[View]`-Sektion
|
### Optionen in der `[View]`-Sektion
|
||||||
|
|
||||||
- **`Mode`**: Bestimmt die Ansicht des Ordners. Mögliche Werte:
|
- **`Mode`**: Bestimmt die Ansicht des Ordners. Mögliche Werte:
|
||||||
- `0`: Liste
|
- `0`: Liste
|
||||||
- `1`: Details
|
- `1`: Details
|
||||||
- `2`: Große Symbole
|
- `2`: Große Symbole
|
||||||
- `3`: Kleine Symbole
|
- `3`: Kleine Symbole
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
Mode=2 ; Setze den Ordner auf "Große Symbole"
|
Mode=2 ; Setze den Ordner auf "Große Symbole"
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`FolderType`**: Bestimmt den Typ des Ordners, z. B. `Documents`, `Music`, `Pictures`.
|
- **`FolderType`**: Bestimmt den Typ des Ordners, z. B. `Documents`, `Music`, `Pictures`.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
FolderType=Documents ; Ordnertyp auf Dokumente setzen
|
FolderType=Documents ; Ordnertyp auf Dokumente setzen
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`IconAreaImage`**: Setzt ein Hintergrundbild für den Ordnerbereich.
|
- **`IconAreaImage`**: Setzt ein Hintergrundbild für den Ordnerbereich.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
IconAreaImage=C:\Bilder\Hintergrund.png
|
IconAreaImage=C:\Bilder\Hintergrund.png
|
||||||
```
|
```
|
||||||
|
|
||||||
### Optionen in der `[Icon]`-Sektion
|
### Optionen in der `[Icon]`-Sektion
|
||||||
|
|
||||||
- **`IconFile`**: Der Pfad zu einer Datei, die das Ordnersymbol enthält (z. B. `.ico`, `.dll`, `.exe`).
|
- **`IconFile`**: Der Pfad zu einer Datei, die das Ordnersymbol enthält (z. B. `.ico`, `.dll`, `.exe`).
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
IconFile=C:\Windows\System32\shell32.dll
|
IconFile=C:\Windows\System32\shell32.dll
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`IconIndex`**: Der Index des Symbols in der Datei, wenn mehrere Symbole in einer Datei vorhanden sind.
|
- **`IconIndex`**: Der Index des Symbols in der Datei, wenn mehrere Symbole in einer Datei vorhanden sind.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
IconIndex=5
|
IconIndex=5
|
||||||
```
|
```
|
||||||
|
|
||||||
### Optionen in der `[LocalizedFileNames]`-Sektion
|
### Optionen in der `[LocalizedFileNames]`-Sektion
|
||||||
|
|
||||||
- **`@`**: Erlaubt die Anzeige von Ordnernamen in verschiedenen Sprachen.
|
- **`@`**: Erlaubt die Anzeige von Ordnernamen in verschiedenen Sprachen.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[LocalizedFileNames]
|
[LocalizedFileNames]
|
||||||
@="Projektordner"
|
@="Projektordner"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Optionen in der `[ShellClassInfo]`-Sektion
|
### Optionen in der `[ShellClassInfo]`-Sektion
|
||||||
|
|
||||||
- **`NoSharing`**: Verhindert die Freigabe des Ordners über das Netzwerk.
|
- **`NoSharing`**: Verhindert die Freigabe des Ordners über das Netzwerk.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
NoSharing=1 ; Verhindert die Netzwerkfreigabe
|
NoSharing=1 ; Verhindert die Netzwerkfreigabe
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`ConfirmFileOp`**: Steuert, ob eine Bestätigung beim Kopieren von Dateien erforderlich ist.
|
- **`ConfirmFileOp`**: Steuert, ob eine Bestätigung beim Kopieren von Dateien erforderlich ist.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
ConfirmFileOp=0 ; Keine Bestätigung erforderlich
|
ConfirmFileOp=0 ; Keine Bestätigung erforderlich
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`InfoTip`**: Eine zusätzliche Option zur Festlegung eines Tooltips.
|
- **`InfoTip`**: Eine zusätzliche Option zur Festlegung eines Tooltips.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
InfoTip=Dieser Ordner enthält Projektdateien.
|
InfoTip=Dieser Ordner enthält Projektdateien.
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`IconFile` und `IconIndex`**: Wiederholung der Optionen zur Festlegung des Ordnersymbols.
|
- **`IconFile` und `IconIndex`**: Wiederholung der Optionen zur Festlegung des Ordnersymbols.
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
IconFile=C:\Windows\System32\shell32.dll
|
IconFile=C:\Windows\System32\shell32.dll
|
||||||
IconIndex=5
|
IconIndex=5
|
||||||
```
|
```
|
||||||
|
|
||||||
## Kommentare in der `desktop.ini`
|
## Kommentare in der `desktop.ini`
|
||||||
|
|
||||||
In der `desktop.ini`-Datei können **Kommentare** durch das Hinzufügen eines **Semikolons (`;`)** am Anfang einer Zeile eingefügt werden. Alles, was nach einem Semikolon in einer Zeile steht, wird von Windows ignoriert und dient lediglich der Dokumentation.
|
In der `desktop.ini`-Datei können **Kommentare** durch das Hinzufügen eines **Semikolons (`;`)** am Anfang einer Zeile eingefügt werden. Alles, was nach einem Semikolon in einer Zeile steht, wird von Windows ignoriert und dient lediglich der Dokumentation.
|
||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
; Dies ist ein Kommentar
|
; Dies ist ein Kommentar
|
||||||
[.ShellClassInfo]
|
[.ShellClassInfo]
|
||||||
IconFile=C:\Windows\System32\shell32.dll
|
IconFile=C:\Windows\System32\shell32.dll
|
||||||
IconIndex=23
|
IconIndex=23
|
||||||
```
|
```
|
||||||
|
|
||||||
## Die Bedeutung von Attributen und Rechten der `desktop.ini`
|
## Die Bedeutung von Attributen und Rechten der `desktop.ini`
|
||||||
|
|
||||||
Die `desktop.ini`-Datei muss bestimmte **Dateiattribute** besitzen, damit sie korrekt funktioniert:
|
Die `desktop.ini`-Datei muss bestimmte **Dateiattribute** besitzen, damit sie korrekt funktioniert:
|
||||||
|
|
||||||
- **Schreibgeschützt (`+r`)**: Verhindert, dass die Datei überschrieben wird.
|
- **Schreibgeschützt (`+r`)**: Verhindert, dass die Datei überschrieben wird.
|
||||||
- **Versteckt (`+h`)**: Stellt sicher, dass die Datei im Windows Explorer nicht angezeigt wird.
|
- **Versteckt (`+h`)**: Stellt sicher, dass die Datei im Windows Explorer nicht angezeigt wird.
|
||||||
- **System (`+s`)**: Kennzeichnet die Datei als Systemdatei, sodass Windows sie als Konfigurationsdatei erkennt.
|
- **System (`+s`)**: Kennzeichnet die Datei als Systemdatei, sodass Windows sie als Konfigurationsdatei erkennt.
|
||||||
|
|
||||||
Die `desktop.ini`-Datei sollte auch die entsprechenden **Dateisystemrechte** haben, um sicherzustellen, dass sie nicht versehentlich gelöscht oder verändert wird.
|
Die `desktop.ini`-Datei sollte auch die entsprechenden **Dateisystemrechte** haben, um sicherzustellen, dass sie nicht versehentlich gelöscht oder verändert wird.
|
||||||
|
|
||||||
## Rechte für die `desktop.ini` unter Windows setzen
|
## Rechte für die `desktop.ini` unter Windows setzen
|
||||||
|
|
||||||
Damit die `desktop.ini`-Datei korrekt funktioniert, müssen unter Windows bestimmte **Dateirechte und Attribute** gesetzt werden:
|
Damit die `desktop.ini`-Datei korrekt funktioniert, müssen unter Windows bestimmte **Dateirechte und Attribute** gesetzt werden:
|
||||||
|
|
||||||
- **Schreibschutz setzen**: Um zu verhindern, dass die Datei überschrieben wird, kann das Schreibschutz-Attribut aktiviert werden. Dies kann über die Eingabeaufforderung mit dem Befehl `attrib +r desktop.ini` erreicht werden.
|
- **Schreibschutz setzen**: Um zu verhindern, dass die Datei überschrieben wird, kann das Schreibschutz-Attribut aktiviert werden. Dies kann über die Eingabeaufforderung mit dem Befehl `attrib +r desktop.ini` erreicht werden.
|
||||||
|
|
||||||
- **Versteckt setzen**: Damit die Datei im Explorer nicht angezeigt wird, muss das versteckte Attribut gesetzt werden. Dies kann mit `attrib +h desktop.ini` erfolgen.
|
- **Versteckt setzen**: Damit die Datei im Explorer nicht angezeigt wird, muss das versteckte Attribut gesetzt werden. Dies kann mit `attrib +h desktop.ini` erfolgen.
|
||||||
|
|
||||||
- **Systemdateiattribut setzen**: Um die Datei als Systemdatei zu kennzeichnen, sodass Windows sie korrekt als Konfigurationsdatei behandelt, muss das Systemattribut gesetzt werden. Verwenden Sie dazu `attrib +s desktop.ini`.
|
- **Systemdateiattribut setzen**: Um die Datei als Systemdatei zu kennzeichnen, sodass Windows sie korrekt als Konfigurationsdatei behandelt, muss das Systemattribut gesetzt werden. Verwenden Sie dazu `attrib +s desktop.ini`.
|
||||||
|
|
||||||
Die richtigen Attribute können alle auf einmal gesetzt werden, indem Sie den folgenden Befehl verwenden:
|
Die richtigen Attribute können alle auf einmal gesetzt werden, indem Sie den folgenden Befehl verwenden:
|
||||||
|
|
||||||
```cmd
|
```cmd
|
||||||
attrib +r +h +s desktop.ini
|
attrib +r +h +s desktop.ini
|
||||||
```
|
```
|
||||||
|
|
||||||
## Verwendung der `desktop.ini` auf NAS-Laufwerken
|
## Verwendung der `desktop.ini` auf NAS-Laufwerken
|
||||||
|
|
||||||
Die `desktop.ini`-Datei kann auch auf **NAS-Laufwerken** verwendet werden, solange das Laufwerk ein **Windows-kompatibles Dateisystem** wie **NTFS** verwendet. Es gibt jedoch einige wichtige Aspekte zu beachten:
|
Die `desktop.ini`-Datei kann auch auf **NAS-Laufwerken** verwendet werden, solange das Laufwerk ein **Windows-kompatibles Dateisystem** wie **NTFS** verwendet. Es gibt jedoch einige wichtige Aspekte zu beachten:
|
||||||
|
|
||||||
- Das NAS muss ein unterstütztes Dateisystem verwenden.
|
- Das NAS muss ein unterstütztes Dateisystem verwenden.
|
||||||
- Die Berechtigungen für die Datei und die Ordnersichtbarkeit müssen so konfiguriert werden, dass Windows sie korrekt lesen kann.
|
- Die Berechtigungen für die Datei und die Ordnersichtbarkeit müssen so konfiguriert werden, dass Windows sie korrekt lesen kann.
|
||||||
|
|
||||||
## Fazit
|
## Fazit
|
||||||
|
|
||||||
Die `desktop.ini`-Datei ist ein mächtiges Werkzeug zur Anpassung von Ordnern in Windows. Sie ermöglicht es, das Aussehen und Verhalten von Ordnern zu verändern, ohne zusätzliche Software zu benötigen. Durch die Verwendung von Kommentaren und Attributen können Benutzer ihre Ordnerspezifikationen einfach und effektiv anpassen. Ob auf lokalen Laufwerken oder NAS-Systemen – die `desktop.ini` bleibt eine vielseitige Lösung für die Ordneranpassung in Windows.
|
Die `desktop.ini`-Datei ist ein mächtiges Werkzeug zur Anpassung von Ordnern in Windows. Sie ermöglicht es, das Aussehen und Verhalten von Ordnern zu verändern, ohne zusätzliche Software zu benötigen. Durch die Verwendung von Kommentaren und Attributen können Benutzer ihre Ordnerspezifikationen einfach und effektiv anpassen. Ob auf lokalen Laufwerken oder NAS-Systemen – die `desktop.ini` bleibt eine vielseitige Lösung für die Ordneranpassung in Windows.
|
||||||
|
1122
package-lock.json
generated
1122
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
48
package.json
48
package.json
@ -1,24 +1,24 @@
|
|||||||
{
|
{
|
||||||
"name": "tools",
|
"name": "tools",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"bin": {
|
"bin": {
|
||||||
"link-collector": "./dist/index.js"
|
"link-collector": "./dist/index.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"postbuild": "node tools/dist/fscopy.js -s tools/dist/collector/link_collector.js -t tools/collector/link_collector.js && npm run clean",
|
"postbuild": "node tools/dist/fscopy.js -s tools/dist/collector/link_collector.js -t tools/collector/link_collector.js && npm run clean",
|
||||||
"scan": "node tools/collector/link_collector.js",
|
"scan": "node tools/collector/link_collector.js",
|
||||||
"clean": "node ./tools/dist/fsdel.js ./tools/dist/collector/link_collector.js"
|
"clean": "node ./tools/dist/fsdel.js ./tools/dist/collector/link_collector.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fs": "^0.0.1-security",
|
"fs": "^0.0.1-security",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.15.29",
|
"@types/node": "^22.15.29",
|
||||||
"esbuild": "^0.25.5"
|
"esbuild": "^0.25.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
60
scan.cmd
60
scan.cmd
@ -1,29 +1,31 @@
|
|||||||
@echo off
|
@echo off
|
||||||
REM ------------------------------------------------------------
|
REM ------------------------------------------------------------
|
||||||
REM Python-Wrapper für ein definiertes Skript mit Parametern
|
REM Python-Wrapper für ein definiertes Skript mit Parametern
|
||||||
REM Führt ein festgelegtes Python-Skript aus und prüft, ob Python installiert ist
|
REM Führt ein festgelegtes Python-Skript aus und prüft, ob Python installiert ist
|
||||||
REM ------------------------------------------------------------
|
REM
|
||||||
|
REM Wird durch (./tools/collector/link_collector.py) und `npm run scan` abgeloest!
|
||||||
REM ==== KONFIGURATION =====
|
REM ------------------------------------------------------------
|
||||||
set SCRIPT=tools\collector\link_collector.py
|
|
||||||
set PYTHON=python
|
REM ==== KONFIGURATION =====
|
||||||
REM ========================
|
set SCRIPT=tools\collector\link_collector.py
|
||||||
|
set PYTHON=python
|
||||||
chcp 65001 >nul
|
REM ========================
|
||||||
|
|
||||||
where %PYTHON% >nul 2>&1
|
chcp 65001 >nul
|
||||||
if errorlevel 1 (
|
|
||||||
echo.
|
where %PYTHON% >nul 2>&1
|
||||||
echo ❌ Python wurde nicht gefunden.
|
if errorlevel 1 (
|
||||||
echo.
|
echo.
|
||||||
echo Bitte installiere Python von:
|
echo ❌ Python wurde nicht gefunden.
|
||||||
echo https://www.python.org/downloads/windows/
|
echo.
|
||||||
echo.
|
echo Bitte installiere Python von:
|
||||||
echo Alternativ: Stelle sicher, dass python.exe im PATH ist.
|
echo https://www.python.org/downloads/windows/
|
||||||
pause
|
echo.
|
||||||
exit /b 1
|
echo Alternativ: Stelle sicher, dass python.exe im PATH ist.
|
||||||
)
|
pause
|
||||||
|
exit /b 1
|
||||||
REM Skript ausführen mit allen übergebenen Parametern
|
)
|
||||||
%PYTHON% %SCRIPT% %*
|
|
||||||
pause
|
REM Skript ausführen mit allen übergebenen Parametern
|
||||||
|
%PYTHON% %SCRIPT% %*
|
||||||
|
pause
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
// Verzeichnis relativ zum Script, das durchsucht wird
|
// Verzeichnis relativ zum Script, das durchsucht wird
|
||||||
"root_dirs": [
|
"root_dirs": [
|
||||||
"dokus"
|
"dokus"
|
||||||
],
|
],
|
||||||
|
|
||||||
// Nur Dateien mit dieser Endung (wird erweitert)
|
// Nur Dateien mit dieser Endung (wird erweitert)
|
||||||
"extensions": [".md"],
|
"extensions": [".md"],
|
||||||
|
|
||||||
// Zielpfad für die Linkausgabe (Markdown-Datei)
|
// Zielpfad für die Linkausgabe (Markdown-Datei)
|
||||||
"output_file": "README.md",
|
"output_file": "README.md",
|
||||||
|
|
||||||
// Optional: Log für bereits verarbeitete Dateien. Dateien die dort
|
// Optional: Log für bereits verarbeitete Dateien. Dateien die dort
|
||||||
// enthalten sind, werden nicht nochmals verabeitet.
|
// enthalten sind, werden nicht nochmals verabeitet.
|
||||||
"processed_log": "processed.log"
|
"processed_log": "processed.log"
|
||||||
}
|
}
|
||||||
|
@ -57,19 +57,19 @@ class ArgParser {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
static showHelp() {
|
static showHelp() {
|
||||||
console.log(`
|
console.log(`
|
||||||
(C) 2025 - Adam Skotarczak (ionivation.com)
|
(C) 2025 - Adam Skotarczak (ionivation.com)
|
||||||
|
|
||||||
🛈 Tool das Verzeichnisse nach Markdown-Dateien durchsucht und diese an eine definierte Liste anhängt als Markdown-Link.
|
🛈 Tool das Verzeichnisse nach Markdown-Dateien durchsucht und diese an eine definierte Liste anhängt als Markdown-Link.
|
||||||
Verwendung: ts-node link_collector.ts [OPTIONEN]
|
Verwendung: ts-node link_collector.ts [OPTIONEN]
|
||||||
|
|
||||||
-s, --scan Kommagetrennte Liste von Verzeichnissen zum Durchsuchen (relativ zum Aufrufpfad)
|
-s, --scan Kommagetrennte Liste von Verzeichnissen zum Durchsuchen (relativ zum Aufrufpfad)
|
||||||
-x, --ignore Kommagetrennte Liste von Verzeichnissen, die ignoriert werden sollen
|
-x, --ignore Kommagetrennte Liste von Verzeichnissen, die ignoriert werden sollen
|
||||||
--reset Löscht das Logfile 'processed.log' und beendet sich
|
--reset Löscht das Logfile 'processed.log' und beendet sich
|
||||||
-h, --hilfe Zeigt diese Hilfe
|
-h, --hilfe Zeigt diese Hilfe
|
||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
ts-node link_collector.ts -s docs,notes -x "docs/alt"
|
ts-node link_collector.ts -s docs,notes -x "docs/alt"
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,164 +1,164 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# Gibt das Verzeichnis zurück, in dem dieses Skript liegt
|
# Gibt das Verzeichnis zurück, in dem dieses Skript liegt
|
||||||
def script_dir():
|
def script_dir():
|
||||||
return Path(__file__).parent.resolve()
|
return Path(__file__).parent.resolve()
|
||||||
|
|
||||||
# Lädt die JSONC-Konfiguration (Kommentare via // werden ignoriert)
|
# Lädt die JSONC-Konfiguration (Kommentare via // werden ignoriert)
|
||||||
def load_config(filename="config.jsonc"):
|
def load_config(filename="config.jsonc"):
|
||||||
config_path = script_dir() / filename
|
config_path = script_dir() / filename
|
||||||
if not config_path.exists():
|
if not config_path.exists():
|
||||||
print(" ⚠ Konfigurationsdatei nicht gefunden:", config_path)
|
print(" ⚠ Konfigurationsdatei nicht gefunden:", config_path)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
with open(config_path, encoding="utf-8") as f:
|
with open(config_path, encoding="utf-8") as f:
|
||||||
# Entfernt //-Kommentare vor dem Parsen
|
# Entfernt //-Kommentare vor dem Parsen
|
||||||
return json.loads("".join(line for line in f if not line.strip().startswith("//")))
|
return json.loads("".join(line for line in f if not line.strip().startswith("//")))
|
||||||
|
|
||||||
# Parsen der Kommandozeilenargumente
|
# Parsen der Kommandozeilenargumente
|
||||||
def parse_args():
|
def parse_args():
|
||||||
args = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
parsed = {
|
parsed = {
|
||||||
"scan": None, # Verzeichnisse zum Scannen (List[str])
|
"scan": None, # Verzeichnisse zum Scannen (List[str])
|
||||||
"ignore": [], # Verzeichnisse, die ignoriert werden sollen (List[str])
|
"ignore": [], # Verzeichnisse, die ignoriert werden sollen (List[str])
|
||||||
"reset": False, # Setzt das Logfile zurück
|
"reset": False, # Setzt das Logfile zurück
|
||||||
"hilfe": False, # Zeigt die Hilfe an
|
"hilfe": False, # Zeigt die Hilfe an
|
||||||
}
|
}
|
||||||
|
|
||||||
# Argumente durchgehen und zuweisen
|
# Argumente durchgehen und zuweisen
|
||||||
while args:
|
while args:
|
||||||
arg = args.pop(0)
|
arg = args.pop(0)
|
||||||
if arg in ("-h", "--hilfe"):
|
if arg in ("-h", "--hilfe"):
|
||||||
parsed["hilfe"] = True
|
parsed["hilfe"] = True
|
||||||
elif arg == "--reset":
|
elif arg == "--reset":
|
||||||
parsed["reset"] = True
|
parsed["reset"] = True
|
||||||
elif arg in ("-s", "--scan") and args:
|
elif arg in ("-s", "--scan") and args:
|
||||||
parsed["scan"] = [entry.strip() for entry in args.pop(0).split(",") if entry.strip()]
|
parsed["scan"] = [entry.strip() for entry in args.pop(0).split(",") if entry.strip()]
|
||||||
elif arg in ("-x", "--ignore") and args:
|
elif arg in ("-x", "--ignore") and args:
|
||||||
parsed["ignore"] = [entry.strip() for entry in args.pop(0).split(",") if entry.strip()]
|
parsed["ignore"] = [entry.strip() for entry in args.pop(0).split(",") if entry.strip()]
|
||||||
else:
|
else:
|
||||||
print(f" ⚠ Unbekannter Parameter: {arg}")
|
print(f" ⚠ Unbekannter Parameter: {arg}")
|
||||||
parsed["hilfe"] = True
|
parsed["hilfe"] = True
|
||||||
break
|
break
|
||||||
|
|
||||||
return parsed
|
return parsed
|
||||||
|
|
||||||
# Ausgabe der Hilfetexte für CLI-Nutzer
|
# Ausgabe der Hilfetexte für CLI-Nutzer
|
||||||
def show_help():
|
def show_help():
|
||||||
print("""
|
print("""
|
||||||
(C) 2025 - Adam Skotarczak (ionivation.com)
|
(C) 2025 - Adam Skotarczak (ionivation.com)
|
||||||
|
|
||||||
🛈 Tool das Verzeichnisse nach Markdown-Dateien durchsucht und diese an eine definierte Liste anhängt als Markdown-Link.
|
🛈 Tool das Verzeichnisse nach Markdown-Dateien durchsucht und diese an eine definierte Liste anhängt als Markdown-Link.
|
||||||
Verwendung: python3 link_collector.py [OPTIONEN]
|
Verwendung: python3 link_collector.py [OPTIONEN]
|
||||||
|
|
||||||
-s, --scan Kommagetrennte Liste von Verzeichnissen zum Durchsuchen (relativ zum Aufrufpfad)
|
-s, --scan Kommagetrennte Liste von Verzeichnissen zum Durchsuchen (relativ zum Aufrufpfad)
|
||||||
-x, --ignore Kommagetrennte Liste von Verzeichnissen, die ignoriert werden sollen
|
-x, --ignore Kommagetrennte Liste von Verzeichnissen, die ignoriert werden sollen
|
||||||
--reset Löscht das Logfile 'processed.log' und beendet sich
|
--reset Löscht das Logfile 'processed.log' und beendet sich
|
||||||
-h, --hilfe Zeigt diese Hilfe
|
-h, --hilfe Zeigt diese Hilfe
|
||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
python3 link_collector.py -s docs,notes -x "docs/alt"
|
python3 link_collector.py -s docs,notes -x "docs/alt"
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# Generator: Findet Markdown-Dateien (rekursiv), ignoriert dabei definierte Pfade
|
# Generator: Findet Markdown-Dateien (rekursiv), ignoriert dabei definierte Pfade
|
||||||
def find_md_files(root_dirs, ignore_dirs, extensions):
|
def find_md_files(root_dirs, ignore_dirs, extensions):
|
||||||
for root in root_dirs:
|
for root in root_dirs:
|
||||||
for dirpath, _, filenames in os.walk(root):
|
for dirpath, _, filenames in os.walk(root):
|
||||||
# Ignorierpfade überspringen
|
# Ignorierpfade überspringen
|
||||||
if any(str(Path(dirpath)).startswith(str(ignored)) for ignored in ignore_dirs):
|
if any(str(Path(dirpath)).startswith(str(ignored)) for ignored in ignore_dirs):
|
||||||
continue
|
continue
|
||||||
for fname in filenames:
|
for fname in filenames:
|
||||||
if any(fname.endswith(ext) for ext in extensions):
|
if any(fname.endswith(ext) for ext in extensions):
|
||||||
yield Path(dirpath) / fname
|
yield Path(dirpath) / fname
|
||||||
|
|
||||||
# Extrahiert den ersten Markdown-Titel (# ...) als Linktext
|
# Extrahiert den ersten Markdown-Titel (# ...) als Linktext
|
||||||
def extract_title(filepath):
|
def extract_title(filepath):
|
||||||
try:
|
try:
|
||||||
with open(filepath, encoding="utf-8") as f:
|
with open(filepath, encoding="utf-8") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
if line.strip().startswith("#"):
|
if line.strip().startswith("#"):
|
||||||
return line.strip("# ").strip()
|
return line.strip("# ").strip()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"⚠ Fehler beim Lesen von {filepath}: {e}")
|
print(f"⚠ Fehler beim Lesen von {filepath}: {e}")
|
||||||
# Fallback: Dateiname ohne Endung
|
# Fallback: Dateiname ohne Endung
|
||||||
return filepath.stem
|
return filepath.stem
|
||||||
|
|
||||||
# Liest bereits verarbeitete Dateien aus dem Log (Pfadangaben im POSIX-Format)
|
# Liest bereits verarbeitete Dateien aus dem Log (Pfadangaben im POSIX-Format)
|
||||||
def load_processed(logfile):
|
def load_processed(logfile):
|
||||||
if not logfile.exists():
|
if not logfile.exists():
|
||||||
return set()
|
return set()
|
||||||
with open(logfile, encoding="utf-8") as f:
|
with open(logfile, encoding="utf-8") as f:
|
||||||
# Vereinheitlichung auf POSIX-Konvention
|
# Vereinheitlichung auf POSIX-Konvention
|
||||||
return set(Path(line.strip()).as_posix() for line in f)
|
return set(Path(line.strip()).as_posix() for line in f)
|
||||||
|
|
||||||
# Hängt neue Markdown-Links ans Output-Dokument an
|
# Hängt neue Markdown-Links ans Output-Dokument an
|
||||||
def append_to_output(output_path, links):
|
def append_to_output(output_path, links):
|
||||||
with open(output_path, "a", encoding="utf-8") as f:
|
with open(output_path, "a", encoding="utf-8") as f:
|
||||||
for line in links:
|
for line in links:
|
||||||
f.write(line + "\n")
|
f.write(line + "\n")
|
||||||
|
|
||||||
# Ergänzt das Logfile um neu verarbeitete Dateien (POSIX-Format)
|
# Ergänzt das Logfile um neu verarbeitete Dateien (POSIX-Format)
|
||||||
def update_processed(log_path, new_paths):
|
def update_processed(log_path, new_paths):
|
||||||
with open(log_path, "a", encoding="utf-8") as f:
|
with open(log_path, "a", encoding="utf-8") as f:
|
||||||
for path in new_paths:
|
for path in new_paths:
|
||||||
f.write(path.as_posix() + "\n")
|
f.write(path.as_posix() + "\n")
|
||||||
|
|
||||||
# Hauptfunktion mit gesamtem Ablauf
|
# Hauptfunktion mit gesamtem Ablauf
|
||||||
def main():
|
def main():
|
||||||
config = load_config()
|
config = load_config()
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
|
|
||||||
if args["hilfe"]:
|
if args["hilfe"]:
|
||||||
show_help()
|
show_help()
|
||||||
return
|
return
|
||||||
|
|
||||||
log_path = script_dir() / config.get("processed_log", "processed.log")
|
log_path = script_dir() / config.get("processed_log", "processed.log")
|
||||||
|
|
||||||
# Optionaler Reset des Logs
|
# Optionaler Reset des Logs
|
||||||
if args["reset"]:
|
if args["reset"]:
|
||||||
if log_path.exists():
|
if log_path.exists():
|
||||||
log_path.unlink()
|
log_path.unlink()
|
||||||
print("🧹 Logfile gelöscht:", log_path)
|
print("🧹 Logfile gelöscht:", log_path)
|
||||||
else:
|
else:
|
||||||
print("ℹ Logfile existierte nicht:", log_path)
|
print("ℹ Logfile existierte nicht:", log_path)
|
||||||
return
|
return
|
||||||
|
|
||||||
cwd = Path.cwd()
|
cwd = Path.cwd()
|
||||||
output_file = cwd / config.get("output_file", "output.md")
|
output_file = cwd / config.get("output_file", "output.md")
|
||||||
|
|
||||||
# Verzeichnisse aus CLI oder Konfiguration
|
# Verzeichnisse aus CLI oder Konfiguration
|
||||||
root_dirs = args["scan"] or config.get("root_dirs", [])
|
root_dirs = args["scan"] or config.get("root_dirs", [])
|
||||||
root_dirs = [Path(d).resolve() for d in root_dirs if d.strip()]
|
root_dirs = [Path(d).resolve() for d in root_dirs if d.strip()]
|
||||||
ignore_dirs = [Path(x).resolve() for x in args["ignore"]]
|
ignore_dirs = [Path(x).resolve() for x in args["ignore"]]
|
||||||
|
|
||||||
extensions = config.get("extensions", [".md"])
|
extensions = config.get("extensions", [".md"])
|
||||||
processed = load_processed(log_path)
|
processed = load_processed(log_path)
|
||||||
|
|
||||||
new_links = []
|
new_links = []
|
||||||
new_processed = []
|
new_processed = []
|
||||||
|
|
||||||
# Dateien durchsuchen und neue Markdown-Dateien verlinken
|
# Dateien durchsuchen und neue Markdown-Dateien verlinken
|
||||||
for md_file in find_md_files(root_dirs, ignore_dirs, extensions):
|
for md_file in find_md_files(root_dirs, ignore_dirs, extensions):
|
||||||
if md_file.resolve() == output_file.resolve():
|
if md_file.resolve() == output_file.resolve():
|
||||||
continue # nicht sich selbst verlinken
|
continue # nicht sich selbst verlinken
|
||||||
rel_path = md_file.relative_to(cwd)
|
rel_path = md_file.relative_to(cwd)
|
||||||
rel_path_posix = rel_path.as_posix()
|
rel_path_posix = rel_path.as_posix()
|
||||||
if rel_path_posix in processed:
|
if rel_path_posix in processed:
|
||||||
continue # bereits im Logfile
|
continue # bereits im Logfile
|
||||||
title = extract_title(md_file)
|
title = extract_title(md_file)
|
||||||
new_links.append(f"- [{title}]({rel_path_posix})")
|
new_links.append(f"- [{title}]({rel_path_posix})")
|
||||||
new_processed.append(rel_path)
|
new_processed.append(rel_path)
|
||||||
|
|
||||||
# Ergebnisse schreiben
|
# Ergebnisse schreiben
|
||||||
if new_links:
|
if new_links:
|
||||||
append_to_output(output_file, new_links)
|
append_to_output(output_file, new_links)
|
||||||
update_processed(log_path, new_processed)
|
update_processed(log_path, new_processed)
|
||||||
print(f"✔ {len(new_links)} neue Links hinzugefügt.")
|
print(f"✔ {len(new_links)} neue Links hinzugefügt.")
|
||||||
else:
|
else:
|
||||||
print(" ℹ Keine neuen Dateien gefunden.")
|
print(" ℹ Keine neuen Dateien gefunden.")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
dokus/helix__editor_einfuehrung_de.md
|
dokus/helix__editor_einfuehrung_de.md
|
||||||
dokus/windows/desktop_ini.md
|
dokus/windows/desktop_ini.md
|
||||||
|
dokus/webserver/nginx-proxy-manager-setup.md
|
||||||
|
dokus/rust/rust-offline-installation.md
|
||||||
|
dokus/rust/rust-toolchain-msvc.md
|
||||||
|
dokus/plesk/lets-encrypt-plesk.md
|
||||||
dokus/plesk/plesk-benutzer-schon-vorhanden.md
|
dokus/plesk/plesk-benutzer-schon-vorhanden.md
|
||||||
dokus/mechanik/gewindetabellen.md
|
dokus/mechanik/gewindetabellen.md
|
||||||
dokus/js-ts/js-ts-dialekte.md
|
dokus/js-ts/js-ts-dialekte.md
|
||||||
dokus/git/git-remote-branch.md
|
dokus/git/git-remote-branch.md
|
||||||
dokus/git/git-ssh-remote.md
|
dokus/git/git-ssh-remote.md
|
||||||
|
dokus/git/git-submodule-leitfaden.md
|
||||||
dokus/git/git.md
|
dokus/git/git.md
|
||||||
dokus/asciidoc/asciidoctor-theme-bug-workaround.md
|
dokus/asciidoc/asciidoctor-theme-bug-workaround.md
|
||||||
dokus/apache-plesk/lets-encrypt-plesk.md
|
|
||||||
dokus/git/git-submodule-leitfaden.md
|
|
||||||
dokus/rust/rust-toolchain-msvc.md
|
|
||||||
dokus/rust/rust-offline-installation.md
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
// Verzeichnis relativ zum Script, das durchsucht wird
|
// Verzeichnis relativ zum Script, das durchsucht wird
|
||||||
"root_dirs": [
|
"root_dirs": [
|
||||||
"dokus"
|
"dokus"
|
||||||
],
|
],
|
||||||
|
|
||||||
// Nur Dateien mit dieser Endung (wird erweitert)
|
// Nur Dateien mit dieser Endung (wird erweitert)
|
||||||
"extensions": [".md"],
|
"extensions": [".md"],
|
||||||
|
|
||||||
// Zielpfad für die Linkausgabe (Markdown-Datei)
|
// Zielpfad für die Linkausgabe (Markdown-Datei)
|
||||||
"output_file": "README.md",
|
"output_file": "README.md",
|
||||||
|
|
||||||
// Optional: Log für bereits verarbeitete Dateien. Dateien die dort
|
// Optional: Log für bereits verarbeitete Dateien. Dateien die dort
|
||||||
// enthalten sind, werden nicht nochmals verabeitet.
|
// enthalten sind, werden nicht nochmals verabeitet.
|
||||||
"processed_log": "processed.log"
|
"processed_log": "processed.log"
|
||||||
}
|
}
|
||||||
|
@ -1,225 +1,225 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import * as path from 'node:path';
|
import * as path from 'node:path';
|
||||||
|
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import { dirname } from 'node:path';
|
import { dirname } from 'node:path';
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
type Config = {
|
type Config = {
|
||||||
root_dirs?: string[];
|
root_dirs?: string[];
|
||||||
output_file?: string;
|
output_file?: string;
|
||||||
processed_log?: string;
|
processed_log?: string;
|
||||||
extensions?: string[];
|
extensions?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type Args = {
|
type Args = {
|
||||||
scan: string[] | null;
|
scan: string[] | null;
|
||||||
ignore: string[];
|
ignore: string[];
|
||||||
reset: boolean;
|
reset: boolean;
|
||||||
hilfe: boolean;
|
hilfe: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScriptInfo {
|
class ScriptInfo {
|
||||||
static dir(): string {
|
static dir(): string {
|
||||||
return path.dirname(__filename);
|
return path.dirname(__filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cwd(): string {
|
static cwd(): string {
|
||||||
return process.cwd();
|
return process.cwd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigLoader {
|
class ConfigLoader {
|
||||||
static load(filename = 'config.jsonc'): Config {
|
static load(filename = 'config.jsonc'): Config {
|
||||||
const configPath = path.join(ScriptInfo.dir(), filename);
|
const configPath = path.join(ScriptInfo.dir(), filename);
|
||||||
if (!fs.existsSync(configPath)) {
|
if (!fs.existsSync(configPath)) {
|
||||||
console.error(` ⚠ Konfigurationsdatei nicht gefunden: ${configPath}`);
|
console.error(` ⚠ Konfigurationsdatei nicht gefunden: ${configPath}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
const raw = fs.readFileSync(configPath, 'utf8');
|
const raw = fs.readFileSync(configPath, 'utf8');
|
||||||
const clean = raw
|
const clean = raw
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.filter(line => !line.trim().startsWith('//'))
|
.filter(line => !line.trim().startsWith('//'))
|
||||||
.join('');
|
.join('');
|
||||||
return JSON.parse(clean);
|
return JSON.parse(clean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArgParser {
|
class ArgParser {
|
||||||
static parse(): Args {
|
static parse(): Args {
|
||||||
const argv = process.argv.slice(2);
|
const argv = process.argv.slice(2);
|
||||||
const result: Args = { scan: null, ignore: [], reset: false, hilfe: false };
|
const result: Args = { scan: null, ignore: [], reset: false, hilfe: false };
|
||||||
|
|
||||||
while (argv.length) {
|
while (argv.length) {
|
||||||
const arg = argv.shift();
|
const arg = argv.shift();
|
||||||
if (!arg) break;
|
if (!arg) break;
|
||||||
|
|
||||||
if (arg === '-h' || arg === '--hilfe') {
|
if (arg === '-h' || arg === '--hilfe') {
|
||||||
result.hilfe = true;
|
result.hilfe = true;
|
||||||
} else if (arg === '--reset') {
|
} else if (arg === '--reset') {
|
||||||
result.reset = true;
|
result.reset = true;
|
||||||
} else if ((arg === '-s' || arg === '--scan') && argv.length) {
|
} else if ((arg === '-s' || arg === '--scan') && argv.length) {
|
||||||
result.scan = argv.shift()!.split(',').map(x => x.trim()).filter(Boolean);
|
result.scan = argv.shift()!.split(',').map(x => x.trim()).filter(Boolean);
|
||||||
} else if ((arg === '-x' || arg === '--ignore') && argv.length) {
|
} else if ((arg === '-x' || arg === '--ignore') && argv.length) {
|
||||||
result.ignore = argv.shift()!.split(',').map(x => x.trim()).filter(Boolean);
|
result.ignore = argv.shift()!.split(',').map(x => x.trim()).filter(Boolean);
|
||||||
} else {
|
} else {
|
||||||
console.warn(` ⚠ Unbekannter Parameter: ${arg}`);
|
console.warn(` ⚠ Unbekannter Parameter: ${arg}`);
|
||||||
result.hilfe = true;
|
result.hilfe = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static showHelp(): void {
|
static showHelp(): void {
|
||||||
console.log(`
|
console.log(`
|
||||||
(C) 2025 - Adam Skotarczak (ionivation.com)
|
(C) 2025 - Adam Skotarczak (ionivation.com)
|
||||||
|
|
||||||
🛈 Tool das Verzeichnisse nach Markdown-Dateien durchsucht und diese an eine definierte Liste anhängt als Markdown-Link.
|
🛈 Tool das Verzeichnisse nach Markdown-Dateien durchsucht und diese an eine definierte Liste anhängt als Markdown-Link.
|
||||||
Verwendung: ts-node link_collector.ts [OPTIONEN]
|
Verwendung: ts-node link_collector.ts [OPTIONEN]
|
||||||
|
|
||||||
-s, --scan Kommagetrennte Liste von Verzeichnissen zum Durchsuchen (relativ zum Aufrufpfad)
|
-s, --scan Kommagetrennte Liste von Verzeichnissen zum Durchsuchen (relativ zum Aufrufpfad)
|
||||||
-x, --ignore Kommagetrennte Liste von Verzeichnissen, die ignoriert werden sollen
|
-x, --ignore Kommagetrennte Liste von Verzeichnissen, die ignoriert werden sollen
|
||||||
--reset Löscht das Logfile 'processed.log' und beendet sich
|
--reset Löscht das Logfile 'processed.log' und beendet sich
|
||||||
-h, --hilfe Zeigt diese Hilfe
|
-h, --hilfe Zeigt diese Hilfe
|
||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
ts-node link_collector.ts -s docs,notes -x "docs/alt"
|
ts-node link_collector.ts -s docs,notes -x "docs/alt"
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FileScanner {
|
class FileScanner {
|
||||||
static *find(rootDirs: string[], ignoreDirs: string[], extensions: string[]): Generator<string> {
|
static *find(rootDirs: string[], ignoreDirs: string[], extensions: string[]): Generator<string> {
|
||||||
for (const root of rootDirs) {
|
for (const root of rootDirs) {
|
||||||
const absRoot = path.resolve(root);
|
const absRoot = path.resolve(root);
|
||||||
const stack = [absRoot];
|
const stack = [absRoot];
|
||||||
|
|
||||||
while (stack.length) {
|
while (stack.length) {
|
||||||
const current = stack.pop()!;
|
const current = stack.pop()!;
|
||||||
const rel = path.relative(ScriptInfo.cwd(), current).replace(/\\/g, '/');
|
const rel = path.relative(ScriptInfo.cwd(), current).replace(/\\/g, '/');
|
||||||
if (ignoreDirs.some(ignored => rel.startsWith(ignored))) continue;
|
if (ignoreDirs.some(ignored => rel.startsWith(ignored))) continue;
|
||||||
|
|
||||||
const entries = fs.readdirSync(current, { withFileTypes: true });
|
const entries = fs.readdirSync(current, { withFileTypes: true });
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
const fullPath = path.join(current, entry.name);
|
const fullPath = path.join(current, entry.name);
|
||||||
if (entry.isDirectory()) {
|
if (entry.isDirectory()) {
|
||||||
stack.push(fullPath);
|
stack.push(fullPath);
|
||||||
} else if (extensions.some(ext => entry.name.endsWith(ext))) {
|
} else if (extensions.some(ext => entry.name.endsWith(ext))) {
|
||||||
yield fullPath;
|
yield fullPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TitleExtractor {
|
class TitleExtractor {
|
||||||
static extract(filepath: string): string {
|
static extract(filepath: string): string {
|
||||||
try {
|
try {
|
||||||
const content = fs.readFileSync(filepath, 'utf8');
|
const content = fs.readFileSync(filepath, 'utf8');
|
||||||
for (const line of content.split('\n')) {
|
for (const line of content.split('\n')) {
|
||||||
if (line.trim().startsWith('#')) {
|
if (line.trim().startsWith('#')) {
|
||||||
return line.replace(/^#+/, '').trim();
|
return line.replace(/^#+/, '').trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`⚠ Fehler beim Lesen von ${filepath}: ${e}`);
|
console.error(`⚠ Fehler beim Lesen von ${filepath}: ${e}`);
|
||||||
}
|
}
|
||||||
return path.basename(filepath, path.extname(filepath));
|
return path.basename(filepath, path.extname(filepath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProcessedLog {
|
class ProcessedLog {
|
||||||
private readonly logPath: string;
|
private readonly logPath: string;
|
||||||
private entries: Set<string>;
|
private entries: Set<string>;
|
||||||
|
|
||||||
constructor(filename: string) {
|
constructor(filename: string) {
|
||||||
this.logPath = path.join(ScriptInfo.dir(), filename);
|
this.logPath = path.join(ScriptInfo.dir(), filename);
|
||||||
this.entries = new Set<string>();
|
this.entries = new Set<string>();
|
||||||
this.load();
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
private load() {
|
private load() {
|
||||||
if (!fs.existsSync(this.logPath)) return;
|
if (!fs.existsSync(this.logPath)) return;
|
||||||
const lines = fs.readFileSync(this.logPath, 'utf8').split('\n').map(x => x.trim()).filter(Boolean);
|
const lines = fs.readFileSync(this.logPath, 'utf8').split('\n').map(x => x.trim()).filter(Boolean);
|
||||||
this.entries = new Set(lines.map(p => p.replace(/\\/g, '/')));
|
this.entries = new Set(lines.map(p => p.replace(/\\/g, '/')));
|
||||||
}
|
}
|
||||||
|
|
||||||
has(posixPath: string): boolean {
|
has(posixPath: string): boolean {
|
||||||
return this.entries.has(posixPath);
|
return this.entries.has(posixPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(newPaths: string[]): void {
|
update(newPaths: string[]): void {
|
||||||
const content = newPaths.map(p => p.replace(/\\/g, '/')).join('\n') + '\n';
|
const content = newPaths.map(p => p.replace(/\\/g, '/')).join('\n') + '\n';
|
||||||
fs.appendFileSync(this.logPath, content, 'utf8');
|
fs.appendFileSync(this.logPath, content, 'utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
reset(): void {
|
reset(): void {
|
||||||
if (fs.existsSync(this.logPath)) {
|
if (fs.existsSync(this.logPath)) {
|
||||||
fs.unlinkSync(this.logPath);
|
fs.unlinkSync(this.logPath);
|
||||||
console.log('🧹 Logfile gelöscht:', this.logPath);
|
console.log('🧹 Logfile gelöscht:', this.logPath);
|
||||||
} else {
|
} else {
|
||||||
console.log('ℹ Logfile existierte nicht:', this.logPath);
|
console.log('ℹ Logfile existierte nicht:', this.logPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MarkdownAppender {
|
class MarkdownAppender {
|
||||||
static append(outputFile: string, links: string[]): void {
|
static append(outputFile: string, links: string[]): void {
|
||||||
const content = links.join('\n') + '\n';
|
const content = links.join('\n') + '\n';
|
||||||
fs.appendFileSync(outputFile, content, 'utf8');
|
fs.appendFileSync(outputFile, content, 'utf8');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Einstiegspunkt
|
// Einstiegspunkt
|
||||||
function main() {
|
function main() {
|
||||||
const config = ConfigLoader.load();
|
const config = ConfigLoader.load();
|
||||||
const args = ArgParser.parse();
|
const args = ArgParser.parse();
|
||||||
|
|
||||||
if (args.hilfe) {
|
if (args.hilfe) {
|
||||||
ArgParser.showHelp();
|
ArgParser.showHelp();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const log = new ProcessedLog(config.processed_log || 'processed.log');
|
const log = new ProcessedLog(config.processed_log || 'processed.log');
|
||||||
|
|
||||||
if (args.reset) {
|
if (args.reset) {
|
||||||
log.reset();
|
log.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cwd = ScriptInfo.cwd();
|
const cwd = ScriptInfo.cwd();
|
||||||
const outputFile = path.resolve(cwd, config.output_file || 'output.md');
|
const outputFile = path.resolve(cwd, config.output_file || 'output.md');
|
||||||
const rootDirs = (args.scan || config.root_dirs || []).map(d => path.resolve(d));
|
const rootDirs = (args.scan || config.root_dirs || []).map(d => path.resolve(d));
|
||||||
const ignoreDirs = (args.ignore || []).map(d => path.relative(cwd, path.resolve(d)).replace(/\\/g, '/'));
|
const ignoreDirs = (args.ignore || []).map(d => path.relative(cwd, path.resolve(d)).replace(/\\/g, '/'));
|
||||||
const extensions = config.extensions || ['.md'];
|
const extensions = config.extensions || ['.md'];
|
||||||
|
|
||||||
const newLinks: string[] = [];
|
const newLinks: string[] = [];
|
||||||
const newProcessed: string[] = [];
|
const newProcessed: string[] = [];
|
||||||
|
|
||||||
for (const absPath of FileScanner.find(rootDirs, ignoreDirs, extensions)) {
|
for (const absPath of FileScanner.find(rootDirs, ignoreDirs, extensions)) {
|
||||||
const relPath = path.relative(cwd, absPath).replace(/\\/g, '/');
|
const relPath = path.relative(cwd, absPath).replace(/\\/g, '/');
|
||||||
if (path.resolve(absPath) === outputFile || log.has(relPath)) continue;
|
if (path.resolve(absPath) === outputFile || log.has(relPath)) continue;
|
||||||
|
|
||||||
const title = TitleExtractor.extract(absPath);
|
const title = TitleExtractor.extract(absPath);
|
||||||
newLinks.push(`- [${title}](${relPath})`);
|
newLinks.push(`- [${title}](${relPath})`);
|
||||||
newProcessed.push(relPath);
|
newProcessed.push(relPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newLinks.length > 0) {
|
if (newLinks.length > 0) {
|
||||||
MarkdownAppender.append(outputFile, newLinks);
|
MarkdownAppender.append(outputFile, newLinks);
|
||||||
log.update(newProcessed);
|
log.update(newProcessed);
|
||||||
console.log(`✔ ${newLinks.length} neue Links hinzugefügt.`);
|
console.log(`✔ ${newLinks.length} neue Links hinzugefügt.`);
|
||||||
} else {
|
} else {
|
||||||
console.log(' ℹ Keine neuen Dateien gefunden.');
|
console.log(' ℹ Keine neuen Dateien gefunden.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
||||||
|
@ -1,80 +1,80 @@
|
|||||||
#!/usr/bin/env ts-node
|
#!/usr/bin/env ts-node
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Robust plattformunabhängiger Dateikopierer
|
* Robust plattformunabhängiger Dateikopierer
|
||||||
* Verwendung: node fscopy.ts -s <quelle> -t <ziel>
|
* Verwendung: node fscopy.ts -s <quelle> -t <ziel>
|
||||||
* Optionen: -h | --help
|
* Optionen: -h | --help
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
|
||||||
function showHelp(): void {
|
function showHelp(): void {
|
||||||
console.log(`
|
console.log(`
|
||||||
Copy Files with node.js
|
Copy Files with node.js
|
||||||
Verwendung:
|
Verwendung:
|
||||||
node fscopy.ts -s <quelle> -q <ziel>
|
node fscopy.ts -s <quelle> -q <ziel>
|
||||||
|
|
||||||
Parameter:
|
Parameter:
|
||||||
-s, --source Pfad zur Quelldatei (z.B. static/.htaccess)
|
-s, --source Pfad zur Quelldatei (z.B. static/.htaccess)
|
||||||
-t, --target Pfad zur Zieldatei (z.B. dist/app/.htaccess)
|
-t, --target Pfad zur Zieldatei (z.B. dist/app/.htaccess)
|
||||||
-h, --help Diese Hilfe anzeigen
|
-h, --help Diese Hilfe anzeigen
|
||||||
`);
|
`);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseArgs(): { source: string; ziel: string } {
|
function parseArgs(): { source: string; ziel: string } {
|
||||||
const args = process.argv.slice(2);
|
const args = process.argv.slice(2);
|
||||||
let source = "";
|
let source = "";
|
||||||
let ziel = "";
|
let ziel = "";
|
||||||
|
|
||||||
for (let i = 0; i < args.length; i++) {
|
for (let i = 0; i < args.length; i++) {
|
||||||
switch (args[i]) {
|
switch (args[i]) {
|
||||||
case "-s":
|
case "-s":
|
||||||
case "--source":
|
case "--source":
|
||||||
source = args[++i];
|
source = args[++i];
|
||||||
break;
|
break;
|
||||||
case "-t":
|
case "-t":
|
||||||
case "--target":
|
case "--target":
|
||||||
ziel = args[++i];
|
ziel = args[++i];
|
||||||
break;
|
break;
|
||||||
case "-h":
|
case "-h":
|
||||||
case "--help":
|
case "--help":
|
||||||
showHelp();
|
showHelp();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.error(`Unbekannter Parameter: ${args[i]}`);
|
console.error(`Unbekannter Parameter: ${args[i]}`);
|
||||||
showHelp();
|
showHelp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!source || !ziel) {
|
if (!source || !ziel) {
|
||||||
console.error("❌ Quelle und Ziel müssen angegeben werden.");
|
console.error("❌ Quelle und Ziel müssen angegeben werden.");
|
||||||
showHelp();
|
showHelp();
|
||||||
}
|
}
|
||||||
|
|
||||||
return { source, ziel };
|
return { source, ziel };
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyFile(source: string, ziel: string): void {
|
function copyFile(source: string, ziel: string): void {
|
||||||
const zielVerzeichnis = path.dirname(ziel);
|
const zielVerzeichnis = path.dirname(ziel);
|
||||||
fs.mkdir(zielVerzeichnis, { recursive: true }, (mkdirErr) => {
|
fs.mkdir(zielVerzeichnis, { recursive: true }, (mkdirErr) => {
|
||||||
if (mkdirErr) {
|
if (mkdirErr) {
|
||||||
console.error(`❌ Zielverzeichnis konnte nicht erstellt werden: ${mkdirErr.message}`);
|
console.error(`❌ Zielverzeichnis konnte nicht erstellt werden: ${mkdirErr.message}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.copyFile(source, ziel, (copyErr) => {
|
fs.copyFile(source, ziel, (copyErr) => {
|
||||||
if (copyErr) {
|
if (copyErr) {
|
||||||
console.error(`❌ Fehler beim Kopieren: ${copyErr.message}`);
|
console.error(`❌ Fehler beim Kopieren: ${copyErr.message}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`✔ Datei erfolgreich kopiert: ${source} → ${ziel}`);
|
console.log(`✔ Datei erfolgreich kopiert: ${source} → ${ziel}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ausführung
|
// Ausführung
|
||||||
const { source, ziel } = parseArgs();
|
const { source, ziel } = parseArgs();
|
||||||
copyFile(source, ziel);
|
copyFile(source, ziel);
|
||||||
|
@ -1,41 +1,41 @@
|
|||||||
#!/usr/bin/env ts-node
|
#!/usr/bin/env ts-node
|
||||||
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Löscht eine Datei am angegebenen Pfad.
|
* Löscht eine Datei am angegebenen Pfad.
|
||||||
*
|
*
|
||||||
* @param filePath - Pfad zur Datei, die gelöscht werden soll
|
* @param filePath - Pfad zur Datei, die gelöscht werden soll
|
||||||
*/
|
*/
|
||||||
function deleteFile(filePath: string): void {
|
function deleteFile(filePath: string): void {
|
||||||
const resolvedPath = path.resolve(filePath);
|
const resolvedPath = path.resolve(filePath);
|
||||||
|
|
||||||
if (!fs.existsSync(resolvedPath)) {
|
if (!fs.existsSync(resolvedPath)) {
|
||||||
console.error(`❌ Datei nicht gefunden: ${resolvedPath}`);
|
console.error(`❌ Datei nicht gefunden: ${resolvedPath}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.unlinkSync(resolvedPath);
|
fs.unlinkSync(resolvedPath);
|
||||||
console.log(`✔ Datei gelöscht: ${resolvedPath}`);
|
console.log(`✔ Datei gelöscht: ${resolvedPath}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`❌ Fehler beim Löschen: ${(err as Error).message}`);
|
console.error(`❌ Fehler beim Löschen: ${(err as Error).message}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kommandozeilenargumente
|
// Kommandozeilenargumente
|
||||||
const [, , arg] = process.argv;
|
const [, , arg] = process.argv;
|
||||||
|
|
||||||
if (!arg || arg === '-h' || arg === '--help') {
|
if (!arg || arg === '-h' || arg === '--help') {
|
||||||
console.log(`Verwendung:
|
console.log(`Verwendung:
|
||||||
ts-node delete.ts <dateipfad>
|
ts-node delete.ts <dateipfad>
|
||||||
|
|
||||||
Beispiel:
|
Beispiel:
|
||||||
ts-node delete.ts ./log/output.txt`);
|
ts-node delete.ts ./log/output.txt`);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Datei löschen
|
// Datei löschen
|
||||||
deleteFile(arg);
|
deleteFile(arg);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2020",
|
"target": "ES2020",
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"outDir": "./tools/dist",
|
"outDir": "./tools/dist",
|
||||||
"rootDir": "./tools/src",
|
"rootDir": "./tools/src",
|
||||||
"strict": true
|
"strict": true
|
||||||
},
|
},
|
||||||
"include": ["tools/src"]
|
"include": ["tools/src"]
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user