Metadata-Version: 2.4
Name: dotfilesmanager
Version: 1.17.3
Summary: dotfile管理工具，支持多平台
Author-email: xyz1001 <zgzf1001@gmail.com>
License-Expression: MIT
Project-URL: Repository, https://github.com/xyz1001/dotfilesmanager
Keywords: python,dotfiles
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click<8.2,>=8.1.8
Requires-Dist: questionary==2.1.0
Requires-Dist: prompt-toolkit<3.0.52,>=3.0.37
Requires-Dist: platformdirs==4.3.6
Requires-Dist: PyYAML>=6.0
Requires-Dist: cryptography<47,>=46.0.6
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Provides-Extra: typecheck
Requires-Dist: mypy<1.15,>=1.14; extra == "typecheck"
Requires-Dist: types-PyYAML<6.0.12.20250326,>=6.0.12.20241221; extra == "typecheck"
Dynamic: license-file

# 📂 dotfilesmanager (dfm)

**Language:** [Chinese/中文](README_zh.md)

<p align="center">
  <a href="https://pypi.org/project/dotfilesmanager/">
    <img src="https://img.shields.io/pypi/v/dotfilesmanager?color=blue&logo=pypi&logoColor=white" alt="PyPI version">
  </a>
  <a href="https://pypi.org/project/dotfilesmanager/">
    <img src="https://img.shields.io/pypi/pyversions/dotfilesmanager?color=brightgreen&logo=python&logoColor=white" alt="Python Versions">
  </a>
  <a href="https://github.com/xyz1001/dotfilesmanager/blob/main/LICENSE">
    <img src="https://img.shields.io/github/license/xyz1001/dotfilesmanager?color=orange" alt="License">
  </a>
</p>

`dotfilesmanager` (or `dfm` for short) is a **minimal, lightweight, and cross-platform** configuration file (dotfiles) manager.

Unlike traditional synchronization or copying tools, `dfm` uses a **“move the original file + automatically create a symlink”** workflow. It centrally archives your configuration files in `~/dotfiles` under your home directory and creates symbolic links at their original locations. This lets you synchronize and back up configurations across machines while preserving their native real-time update behavior.

---

## ✨ Core Features

- 🚀 **Immediate effect**: Uses symlinks, so configuration changes take effect immediately without manual copying or synchronization.
- 💻 **Native cross-platform support**: Consistently supports Linux, macOS, Windows, and Android (Termux).
- 🧠 **Smart path recommendations**: When sharing configurations across platforms, automatically recommends the most suitable path according to the target system (for example, `~/.config` on macOS and an AppData path on Windows).
- 🔍 **Clear view**: Automatically generates a read-only directory of links organized by platform under `~/dotfiles/view/` for easy overview.
- 🩺 **Health diagnostics**: Includes a one-command check to quickly locate and fix broken symlinks, configuration conflicts, and other issues.

---

## 🆚 Positioning and comparison

- **Central repository + live paths**: `dfm` moves originals into a central `~/dotfiles` repository and places symlinks at live configuration paths, so edits take effect immediately. Its path mappings explicitly cover Linux, macOS, Windows, Android, and Termux, with platform-specific destinations recorded in `dfm.yaml`.
- **Compared with GNU Stow**: Both can create symlinks, but GNU Stow primarily provides a simpler Unix package-to-home-directory symlink model. `dfm` additionally provides cross-platform path mappings and `share` and `view` workflows.
- **Encryption scope**: `dfm` supports structured selected field/value encryption as well as whole-file encryption.
- **Boundaries**: `dfm` is neither a template engine nor a secret manager. Git or another external transport remains responsible for synchronizing the repository. Symlink creation and permissions are platform-dependent.

---

## 💾 Installation

Install with `pip` in one step:

```bash
pip install dotfilesmanager
```

After installation, you can use the **`dfm`** command directly from the command line.

---

## ⌨️ Shell Autocompletion

Click's completion feature only generates completion scripts; it does not install or enable them automatically. Save the script to the appropriate location for your Shell, or output it and load it manually:

```bash
# Bash: common bash-completion directory (or source into the current Shell)
_DFM_COMPLETE=bash_source dfm > ~/.local/share/bash-completion/completions/dfm

# Zsh: completion function directory
_DFM_COMPLETE=zsh_source dfm > ~/.zfunc/_dfm

# Fish: completion script directory
_DFM_COMPLETE=fish_source dfm > ~/.config/fish/completions/dfm.fish
```

Before first use, create the directories above yourself and configure your Shell to load the scripts: for Bash, run `source` or reload bash-completion; for Zsh, add `~/.zfunc` to `fpath` and run `compinit`; Fish loads from its completions directory. Autocompletion is not enabled automatically by these steps.

---

## 🏁 Quick Start

### 🛠️ Scenario 1: Add a local configuration to management

Enter a file or directory path to add it to `~/dotfiles`:

```bash
dfm add ~/.bashrc
```

> 💡 **Interactive wizard**
>
> In an interactive terminal (TTY), `dfm` automatically detects and asks whether you also want to share this configuration on other platforms (such as Windows / macOS / Android), and intelligently recommends a default path.
> 
> If this configuration belongs only to the current system and does not need to be shared across platforms, use the `--system` option:
> ```bash
> dfm add ~/.bashrc --system
> ```

> **Legacy encryption:** `dfm add ~/.secret-config --encrypt` is retained for compatibility with
> the older git-crypt workflow. For current encryption features, see the encryption section below.

### 🔄 Scenario 2: Restore configurations on a new machine or system

After cloning your `~/dotfiles` repository to a new machine, rebuild all symbolic links with one command:

```bash
dfm install
```

To install only a specific configuration:

```bash
dfm install <saved-config-path>
```

### 🤝 Scenario 3: Share an existing configuration across systems or at a new path

To use a configuration already managed by `dfm` on the current system at a different path:

```bash
dfm share <saved-config-path> <new-install-target>
```

### 🗑️ Scenario 4: Stop managing a configuration and restore the file

When you no longer want `dfm` to manage a configuration and want to restore it to its original state:

```bash
dfm rm <path>
```
This safely removes the symbolic link and **restores the original file or directory without data loss** from `~/dotfiles` to its initial installation path.

> [!TIP]
> To completely remove this configuration's associations on all systems and delete its source file from `~/dotfiles`, use:
> ```bash
> dfm rm <path> --all
> ```

---

## 📑 Common Commands

| Command | Description |
| :--- | :--- |
| **`dfm add <path>`** | Manage a configuration file or directory by moving it into `~/dotfiles` and creating a link at its original location. |
| **`dfm rm <path>`** | Stop managing a configuration, remove the symbolic link, and put the file back in its original location. |
| **`dfm install [<path>]`** | Rebuild symbolic links for all (or a specified) configuration files for the current system. |
| **`dfm share <saved> <new>`** | Share an existing configuration with the current system and install it at the specified new path. |
| **`dfm view`** | Generate a clearly categorized read-only link view under `~/dotfiles/view` for easy management and inspection. |
| **`dfm doctor`** | Scan and diagnose the current system's configurations for broken links, conflicts, or unregistered files. |
| **`dfm setup`** | **(Windows only)** Check and enable Developer Mode so ordinary user permissions can create symbolic links. |

---

## 🔧 Platform Notes

### 🪟 Windows Users
* Creating symbolic links on Windows usually requires administrator privileges or Developer Mode.
* If you encounter a permissions error while running a command, execute **`dfm setup`**. It will guide you through enabling Developer Mode via UAC, after which you can use `dfm` normally with standard user permissions.

### 🤖 Android (Termux) Users
* `dfm` fully supports the Termux environment on Android (the system identifier is `android`).
* You can rebuild or share Unix-style configuration files on mobile devices.

---

## 📂 Storage and Configuration Management

* **Physical storage**: The originals of all managed files are stored in `~/dotfiles/files/`.
* **Data manifest**: `dfm.yaml` is the only automatically generated configuration file and persists path mappings for each configuration across platforms.
* **Version control recommendation**: We strongly recommend initializing the entire `~/dotfiles` directory as a Git repository and pushing it to GitHub or another platform for backup.
  > [!TIP]
  > We recommend adding `/view/` to your `.gitignore` to avoid committing generated temporary view files to the Git repository.

### 🔐 Encryption

The prerequisite is a usable GPG default/self key. Configure the encryption rules
in `dfm.yaml`, then run `dfm init` before using the modes below.

Encryption works transparently through Git clean/smudge filters: configured files
remain plaintext in the unlocked working tree; Git automatically encrypts them
when staging or committing (clean) and decrypts them on checkout (smudge), so
ordinary Git use remains seamless.

#### 1. Whole-file encryption

Use this for a file whose entire contents should be protected, including binary files:

```bash
dfm encrypt path/to/file --full
```

The content is stored as one `ENCv1:` envelope. `--full` cannot be combined with
`--key` or `--map`; a full-file rule takes precedence over field rules.

#### 2. Field encryption

Use this when only selected values should be protected:

```bash
dfm encrypt path/to/settings.conf --key password --key email
```

Repeat `--key` for each field, or omit it to enter a comma-separated list
interactively. You can also configure regular-expression `patterns`; only capture
group 1 is encrypted, while the rest of each match remains unchanged:

```yaml
encryption:
  rules:
    "*.ini":
      patterns: ["(?m)^token\\s*=\\s*([^\\r\\n]*)$"]
```

Patterns describe the plaintext form. Git stores the protected form and restores
the plaintext in the worktree; use simple single-line values rather than multiline
or block values. A key that is not present is ignored, but a newly added key must
occur in the target file.

#### 3. Keyword/literal mapping

Use this when repeated literal values should be replaced by reversible names:

```bash
dfm encrypt path/to/settings.conf --map
dfm encrypt path/to/settings.conf --key password --map
```

`--map` can be combined with `--key`, but not with `--full`. It requires an unlocked
repository with a plaintext `.git-filters/map.yaml`; run `dfm unlock` if that map is
missing or still encrypted. Field encryption runs first, then matching literals
are replaced with frames such as `{{dfm:ENDPOINT}}`, which smudge reverses. Do not
write reserved `{{dfm:` frame syntax as plaintext.

**Shared notes.** Run `dfm lock` or `dfm unlock` only with a clean tracked worktree.
To stop encrypting one file, first unlock the repository, then run
`dfm unencrypt path/to/file`. This leaves the file plaintext in the index, so a
future commit can expose it; review the staged diff before committing.
