Automated installer for Metin2 community systems — directive-driven source merge.
Project description
metin2-installer
Automated installer for Metin2 community systems. Reads the directive files produced by the community's "system" tutorials and applies them to a Client/Server source tree without copy/paste mistakes. Backup-first, atomic-write, Windows-native.
Status: v0.1.0 (initial public release) Python: 3.12+ Platform: Windows 11 (primary), Linux / macOS (supported)
Install
Primary install path (recommended):
uv tool install metin2-installer
Secondary install path:
pipx install metin2-installer
Both produce a metin2-install binary on the PATH. No C toolchain required — every
runtime dependency ships prebuilt Windows wheels.
Quick Start
Preview what the installer would do, without touching your source tree:
metin2-install dry-run path/to/system-folder path/to/your/source-tree
Apply the system:
metin2-install install path/to/system-folder path/to/your/source-tree
The install command always shows a summary + unified diff first, then prompts y/N
before writing a single byte.
Directive Format
A "system" is a folder containing a 1. Svn/ subdirectory. Files under 1. Svn/
are either NEW files (dropped in as-is) or MODIFY files carrying one or more
directives:
// Search for:
<code block to find in the target file>
// Add after:
<code block to insert immediately after the match>
Supported directive keywords:
| Keyword | Effect |
|---|---|
// Search for: |
Anchor block — located in the target file |
// Add after: |
Insert immediately after the anchor |
// Add before: |
Insert immediately before the anchor |
// Add for: |
Synonym of Add after: |
// Replace for: |
Replace the anchor with the following block |
Directives can carry an optional scope hint: // Search for: (in CHARACTER::Update).
The parser is typo-tolerant — the real-world typos // Seach for: (missing r) and
// Replace for (missing colon) are accepted.
Install Flow
- Scan — walk
<system>/1. Svn/recursively, classify each file as NEW or MODIFY. - Plan — for every MODIFY file, run the matcher and compute the new file content. Record a SHA-256 of the target file at plan time.
- Preview — print a summary table and a unified diff for every modified file.
- Confirm — prompt y/N (default No). Nothing is written until you confirm.
- Backup — mirror every file about to change into
<target>/.metin2-installer/backups/<timestamp>-<system>/. - Apply — write each file atomically. Re-hash before write; abort if the file changed on disk since the preview. Validate after write.
- Report — print counts, backup path, and a machine-readable
apply.log.jsonlinside the backup directory.
Conflict UX
If a // Search for: block cannot be located in its target file, the installer pauses
and offers three choices:
- Skip this block — continue the run, record the skip in the final report.
- Abort entire installation — stop the run; no partial writes are left behind.
- Edit the target file manually, then retry — opens
$EDITOR(ornotepad.exeon Windows if$EDITORis unset) at the anchor line. After the editor exits, the installer re-runs the matcher for the conflicted block only. If the re-planned match succeeds, the run continues. If it still fails, the two-choice (skip/abort) prompt is shown — no infinite retry.
GUI editors note: If you set EDITOR=code, VSCode forks and returns immediately,
which causes the re-plan to run on the unedited file. Use EDITOR="code --wait" for
VSCode, EDITOR="notepad++ -multiInst -nosession" for Notepad++, or rely on the
built-in notepad.exe fallback which blocks correctly.
Backup Layout
Every apply run writes a timestamped backup mirror:
<target>/.metin2-installer/
├── backups/
│ └── 20260415T140530-<system-name>/
│ ├── MANIFEST.json # list of mirrored files
│ ├── apply.log.jsonl # structured per-directive events
│ └── <mirror of every file about to change>
└── installed.json # write-only manifest of installed systems
Recovery
If an apply goes wrong, restore from the backup mirror with a single robocopy:
robocopy <target>\.metin2-installer\backups\<timestamp>-<system>\ <target>\ /E /XD .metin2-installer
(Linux / macOS equivalent: rsync -a --exclude .metin2-installer <backup>/ <target>/.)
The backup path and full restore command are also printed to stderr whenever the tool aborts mid-run.
Flags
| Flag | Effect |
|---|---|
--yes, -y |
Bypass the y/N confirmation gate (alias for --non-interactive) |
--non-interactive |
Run without prompts |
--on-conflict=skip|abort |
Pre-answer the conflict prompt |
--verbose, -v |
Echo individual block-apply events to stderr |
--no-color |
Suppress ANSI color output (also honors NO_COLOR env var) |
--backup-dir=<path> |
Override the default backup root |
Exit codes: 0 success · 1 user aborted · 2 parser/match error · 3 internal error.
Safety
- Nothing is written until you confirm. The preview diff is always shown first.
- Every write is atomic. Temp file +
fsync+os.replace— no half-written files. - Every write is backed up. A mirror of every file about to change is created before the first byte is written.
- Every write is validated. The installer re-reads the file and asserts the new content is present; a failed assertion aborts the run.
- Ctrl-C is safe. The backup path is printed to stderr and no
.tmpsidecar is left behind.
Out of Scope (v1)
- Fuzzy matching / 3-way merge (exact match only — correctness over speed)
- Uninstall / idempotency detection (Phase 5 / v2)
- GUI (core is a library; a GUI can wrap it later)
- SQL execution /
.quest/.eix/.epktoolchains (v3+) - Automatic rollback on failure (backup + manual rollback is the v1 contract)
License
MIT (see pyproject.toml).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file metin2_installer-0.1.1.tar.gz.
File metadata
- Download URL: metin2_installer-0.1.1.tar.gz
- Upload date:
- Size: 410.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bd287bb1ec85d17c298ef335d4884897668890446e85bd34c042ca146e216c4
|
|
| MD5 |
df7a4f3c9020408b24c25ee85b30a25e
|
|
| BLAKE2b-256 |
7cc4255ca56f109b26f6cc8f7509a09d27ac7e3eb22adfbc37423289708e2c77
|
Provenance
The following attestation bundles were made for metin2_installer-0.1.1.tar.gz:
Publisher:
publish.yml on diogonevesofc/automacao_install_sistemas
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
metin2_installer-0.1.1.tar.gz -
Subject digest:
7bd287bb1ec85d17c298ef335d4884897668890446e85bd34c042ca146e216c4 - Sigstore transparency entry: 1314846510
- Sigstore integration time:
-
Permalink:
diogonevesofc/automacao_install_sistemas@8a58414532cced9910fdf76a1933765a5d04fc22 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/diogonevesofc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8a58414532cced9910fdf76a1933765a5d04fc22 -
Trigger Event:
push
-
Statement type:
File details
Details for the file metin2_installer-0.1.1-py3-none-any.whl.
File metadata
- Download URL: metin2_installer-0.1.1-py3-none-any.whl
- Upload date:
- Size: 51.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2620a6ed840350b0fa8530653f112acdea993b2257318bc9deeb029805deea5c
|
|
| MD5 |
a204c82a6c8928a3d45b7c21704e5a57
|
|
| BLAKE2b-256 |
ba0cdfaee5f4ecd304a979904702670b2f3381dfb844516c999ad2dcc20dc229
|
Provenance
The following attestation bundles were made for metin2_installer-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on diogonevesofc/automacao_install_sistemas
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
metin2_installer-0.1.1-py3-none-any.whl -
Subject digest:
2620a6ed840350b0fa8530653f112acdea993b2257318bc9deeb029805deea5c - Sigstore transparency entry: 1314846649
- Sigstore integration time:
-
Permalink:
diogonevesofc/automacao_install_sistemas@8a58414532cced9910fdf76a1933765a5d04fc22 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/diogonevesofc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8a58414532cced9910fdf76a1933765a5d04fc22 -
Trigger Event:
push
-
Statement type: