Metadata-Version: 2.4
Name: fnb
Version: 0.13.0
Summary: Fetch'n'Backup - Simple two-step backup tool with rsync
Author-email: "Shota Takahashi (KMI)" <shotakaha@kmi.nagoya-u.ac.jp>
License: MIT
License-File: LICENSE
Keywords: backup,cli,fetch,rsync,sync
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Archiving :: Backup
Classifier: Topic :: Utilities
Requires-Python: >=3.12
Requires-Dist: loguru>=0.7.0
Requires-Dist: pexpect>=4.9.0
Requires-Dist: platformdirs>=4.3.8
Requires-Dist: pydantic>=2.11.7
Requires-Dist: python-dotenv>=1.1.1
Requires-Dist: typer>=0.16.0
Provides-Extra: dev
Requires-Dist: commitizen>=4.8.3; extra == 'dev'
Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.4.7; extra == 'dev'
Requires-Dist: mkdocs-material[imaging]>=9.6.15; extra == 'dev'
Requires-Dist: mkdocs-static-i18n>=1.2.0; extra == 'dev'
Requires-Dist: mkdocstrings[python]>=0.30.0; extra == 'dev'
Requires-Dist: pip-audit>=2.7.3; extra == 'dev'
Requires-Dist: pre-commit>=4.2.0; extra == 'dev'
Requires-Dist: pytest-cov>=6.2.1; extra == 'dev'
Requires-Dist: pytest>=8.4.1; extra == 'dev'
Requires-Dist: ruff>=0.12.4; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.4.7; extra == 'docs'
Requires-Dist: mkdocs-material[imaging]>=9.6.15; extra == 'docs'
Requires-Dist: mkdocs-static-i18n>=1.2.0; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.30.0; extra == 'docs'
Description-Content-Type: text/markdown

# fnb — Fetch'n'Backup

[![PyPI version](https://badge.fury.io/py/fnb.svg)](https://pypi.org/project/fnb/)
[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://gitlab.com/qumasan/fnb/-/blob/main/LICENSE)
[![Test Coverage](https://img.shields.io/badge/coverage-80%25-brightgreen.svg)](https://gitlab.com/qumasan/fnb/-/jobs)

**fnb** is a simple two-step backup tool, powered by `rsync`.
It gives you two handy commands:
`fetch` (to pull from remote), and
`backup` (to save to somewhere safe).

Under the hood? Just good old `rsync` — no magic, just sharp automation.

- Simple config. Sharp execution. Safe data.
- Use them one by one, or `sync` them all in one go.

---

## 🚀 Features

1. **Fetch** — Retrieve data from a remote server to your local machine
2. **Backup** — Save local data to external storage
3. **Sync** — Run Fetch and Backup together in one go
4. **Init** — Generate an initial config file (`fnb.toml`)
5. **Structured Logging** — Built-in logging with configurable verbosity levels and file output

---

## ⚙️ Installation

### From PyPI (Recommended)

```bash
pip install fnb
# または
uv pip install fnb
```

### From Source

```bash
git clone https://gitlab.com/qumasan/fnb.git
cd fnb
uv pip install -e .
```

**Requirements**: Python 3.12 or higher is required.

---

## 🧰 Quick Start

```bash
# Initialize configuration files (fnb.toml and .env files)
fnb init

# Check the current config
fnb status

# Fetch: remote -> local
fnb fetch TARGET_LABEL

# Backup: local -> external
fnb backup TARGET_LABEL

# Run Fetch → Backup in one go
fnb sync TARGET_LABEL

# Check version
fnb version

# Logging and Verbosity Control
# Adjust log level for detailed output
fnb fetch TARGET_LABEL --log-level DEBUG
fnb sync TARGET_LABEL --verbose      # Same as --log-level DEBUG
fnb backup TARGET_LABEL --quiet      # Same as --log-level WARNING

# Log files are automatically saved to:
# macOS: ~/Library/Logs/fnb/fnb.log
# Linux: ~/.local/share/fnb/fnb.log
```

---

## 🔧 Configuration

fnb uses TOML configuration files with sections for `fetch` and `backup` operations:

```toml
[fetch.SECTION_NAME]
label = "TARGET_LABEL"
summary = "Fetch data from remote server"
host = "user@remote-host"
source = "~/path/to/source/"
target = "./local/backup/path/"
options = ["-auvz", "--delete", '--rsync-path="~/.local/bin/rsync"']
enabled = true

[backup.SECTION_NAME]
label = "TARGET_LABEL"
summary = "Backup data to cloud storage"
host = "none"          # Local operation
source = "./local/backup/path/"  # Output from fetch
target = "./cloud/backup/path/"
options = ["-auvz", "--delete"]
enabled = true
```

### Configuration File Priority (highest to lowest)

1. `./fnb.toml` — Project-local configuration
2. `~/.config/fnb/config.toml` — Global user configuration (XDG standard)
3. `C:\Users\username\AppData\Local\fnb\config.toml` — Windows global configuration
4. `./config/*.toml` — Split configuration for development/operations

---

## 📊 Logging

fnb includes built-in structured logging powered by [loguru](https://loguru.readthedocs.io/). All operations are logged with configurable verbosity levels.

### Log Levels

- **DEBUG** — Detailed debugging information, command traces, and internal state
- **INFO** — General operational information, task progress, success/failure messages (default)
- **WARNING** — Important notices, non-critical issues, fallback actions
- **ERROR** — Error conditions, operation failures, critical issues

### Log Output

**Console Output (stderr)**
- Colored, structured format with timestamps
- User-facing messages on stdout (status, progress)
- Internal logging on stderr (debug, technical details)

**Log Files (automatic)**
- **macOS**: `~/Library/Logs/fnb/fnb.log`
- **Linux**: `~/.local/share/fnb/fnb.log`
- **Windows**: `%APPDATA%\qumasan\fnb\Logs\fnb.log`

### File Log Management

- **Rotation**: Automatic rotation when files reach 10MB
- **Retention**: Keeps logs for 7 days
- **Compression**: Old logs compressed with gzip
- **Disable**: Set `FNB_DISABLE_FILE_LOGGING=1` to disable file logging

### Command Examples

```bash
# Default INFO level logging
fnb sync logs

# Verbose debugging output
fnb fetch logs --verbose
fnb sync logs --log-level DEBUG

# Quiet mode (warnings and errors only)
fnb backup logs --quiet
fnb fetch logs --log-level WARNING

# Custom log level
fnb sync logs --log-level ERROR
```

---

## 🔐 Authentication

SSH password input can be automated using `pexpect`.
You can also define connection settings in a `.env` file if needed.
Run `fnb init env` to create the initial `.env` file.

---

## 🆕 What's New in v0.13.0

### 🛡️ Reliability Fixes

- **Failures are no longer silently swallowed** - `fetch`/`backup`/`sync` now exit with code 1 on rsync failure instead of always reporting success
- **`sync` stops before `backup` if `fetch` fails** - prevents an incomplete local copy from overwriting or deleting good data on the backup target
- **`--config` auto-detection unified** - `fetch` and `backup` now discover the config file the same way `status` and `sync` already did
- **`.env` template fixed** - `fnb init env` now generates `FNB_PASSWORD_*` (was `RFB_PASSWORD_*`, which the code never read)

### ⚡ Faster CI

- **Pipeline cut from ~183s to ~43s** - verification jobs now run in parallel instead of sequential stages

### 🛠️ Development Workflow Improvements (v0.12.3)

- **Restructured Task File** - Reorganized task definitions following standardized pattern for better organization and clarity
- **Enhanced Task Management** - New convenience tasks: `env:setup`, `env:clean`, `status`, `log`, `push`, `push:tags`, `push:release`
- **Improved Type Safety** - Fixed type checking issues in `options.py` for stricter type compliance
- **Dependency Updates** - Updated 68 packages to latest versions

### 📚 Expanded Documentation (v0.12.3)

- **Release Note Templates** - New `docs:release` task for structured release documentation
- **Version Management** - Simplified with `bump:auto`, `bump:patch`, `bump:minor`, `bump:major` commands
- **Release Notes Structure** - vX.Y.Z release notes in docs/releases/ with comprehensive information

### 📖 ReadTheDocs Documentation Platform Integration (v0.11.2)

- **Versioned Documentation** - Automatic documentation builds for each Git tag
- **Multi-format Output** - HTML, EPUB, and HTMLZip formats available
- **Version Selector** - Easy switching between documentation versions
- **Public Documentation** - Professional documentation hosting at https://fnb.readthedocs.io/

### 🔧 Enhanced Documentation Infrastructure (v0.11.2)

- **Automated Builds** - Documentation automatically builds on tag push
- **Material Theme Support** - Full mkdocs-material compatibility with ReadTheDocs
- **Stable URLs** - Each version accessible at predictable URLs
- **Search Integration** - Full-text search across all versions

---

## 🧪 Development

- `Python 3.12+` — Version requirement
- `uv` — Package management
- `Typer` — CLI framework
- `Pydantic` — Configuration validation
- `pexpect` — SSH automation
- `python-dotenv` — Environment variable support
- `pytest` — Testing framework (80% coverage)
- `mkdocs-material` — Documentation with i18n support
- `pre-commit` — Run checks before each commit
- `ruff` — Fast Python linter and formatter
- `commitizen` — Conventional commit tagging and changelog automation
- `renovate` — Automated dependency management

### Release Management

This project uses automated semantic versioning with structured release workflow:

#### Complete Release Workflow

**Option 1: Automated Full Release** (v0.12.3)
```bash
task release:full  # test → format → bump → release
```

**Option 2: Step-by-Step Release** (New in v0.12.3)
```bash
# Step 1: Verify changes and run tests
task test:ci           # Run all tests and checks

# Step 2: Preview and execute version bump
task bump:check        # Preview version changes
task bump:patch        # Bump patch version (or bump:minor/bump:major)

# Step 3: Create release notes from template
task docs:release -- X.Y.Z  # Create vX.Y.Z.md from template
# Edit docs/releases/vX.Y.Z.md with detailed release information

# Step 4: Commit release notes
git add docs/releases/vX.Y.Z.md mkdocs.yml
git commit -m "docs: add vX.Y.Z release notes"

# Step 5: Push release to GitLab with notes file
task push:release -- X.Y.Z  # Creates GitLab release with release notes

# Step 6: Verify TestPyPI deployment (automatic on tag push)
VERSION=X.Y.Z task verify:testpypi

# Step 7: Production PyPI deployment (when ready)
task publish:prod
```

#### Release Timeline

1. **Code Changes** → Commit with conventional commit format
2. **Version Bump** → `task version:bump` creates tag and updates files
3. **Tag Push** → `task release` pushes tags and creates GitLab release
4. **TestPyPI Deploy** → Automatic CI deployment on tag push
5. **Release Notes** → Manual creation of detailed release documentation
6. **Documentation** → Update navigation and release index
7. **PyPI Deploy** → Manual production deployment when ready

**Current Version**: v0.13.0 - [View Release](https://gitlab.com/qumasan/fnb/-/releases/0.13.0)

### CI/CD Pipeline

GitLab CI/CD pipeline provides automated testing, building, and deployment.
Verification jobs (`test`, `code-quality`, `docs-quality`, `build-package`) run **in parallel** rather than in sequential stages, cutting typical pipeline time from ~183s to ~43s.

**Stages:**
- `renovate`: Automated dependency management (optional)
- `test`: Unit tests, code quality, Renovate-specific tests (each job syncs only the dependencies it needs)
- `docs-quality`: Documentation build validation — skipped on MRs that don't touch docs-related files
- `build`: Package building with `uv build` (no virtual environment needed)
- `deploy-test`: **TestPyPI deployment (automatic on tag push)** 🚀
- `deploy-prod`: PyPI deployment (manual approval for safety)

**Automated Workflows:**
```bash
# Deployment (v0.10.0)
tag push → [Auto TestPyPI] → Local Verification → [Manual PyPI]

# Dependency Management (v0.11.0)
Monday 6am JST → [Renovate Scan] → [Auto MR] → [Enhanced Testing]
```

**Optional CI Variables:**
```bash
# GitLab Settings → CI/CD → Variables
TESTPYPI_API_TOKEN  # TestPyPI API token for testing releases
PYPI_API_TOKEN      # PyPI API token for production releases
RENOVATE_TOKEN      # GitLab token for automated dependency updates (new in v0.11.0)
```

**Local CI Simulation:**
```bash
# Run tests as they run in CI (unit tests only)
task test:ci

# Run unit tests only (fast feedback)
task test:unit

# Run integration tests only
task test:integration

# Run all tests
task test

# Verify TestPyPI deployment
VERSION=0.12.3 task verify:testpypi

# Dependency management tasks (new in v0.11.0)
task deps:update    # Update all dependencies
task deps:test      # Test with updated dependencies
task deps:security  # Check for security vulnerabilities
```

### Test Structure

Tests are organized into two directories for optimal development workflow:

- **tests/unit/**: 9 files, 124 tests - Fast unit tests (1.65s)
- **tests/integration/**: 1 file, 23 tests - Comprehensive workflow tests (3.25s)

Both directory-based and marker-based execution are supported:
```bash
# Directory-based (recommended)
task test:unit          # tests/unit/ only
task test:integration   # tests/integration/ only

# Marker-based (backward compatibility)
pytest -m "not integration"  # unit tests
pytest -m "integration"      # integration tests
```

### Test Coverage

Current test coverage is **80%** with comprehensive error handling and integration testing:

- **Unit Tests**: 124 tests covering all modules
- **Integration Tests**: 23 tests covering complete workflows
- **Test Execution**: ~0.61s for unit tests, full test suite in <5s

See [CLAUDE.md](./CLAUDE.md) for detailed test structure and module-level coverage information.

## 🪪 License

MIT

## 🛠️ Contributing

This project is maintained in two repositories:

- 🛠️ Development, Issues, Merge Requests: [GitLab](https://gitlab.com/qumasan/fnb)
- 🌏 Public Mirror and Discussions: GitHub
- 📦 PyPI Package: [fnb](https://pypi.org/project/fnb/)
- 📖 Documentation: [ReadTheDocs](https://fnb.readthedocs.io/) with versioned documentation
- 📖 Legacy Docs: [GitLab Pages](https://qumasan.gitlab.io/fnb/) (maintained for reference)

Please use **GitLab** for development contributions, bug reports, and feature requests.
For documentation viewing and community discussions, feel free to visit the GitHub mirror.

### Development Workflow

See [CLAUDE.md](./CLAUDE.md) for detailed development guidelines including:
- Testing and coverage requirements (80%+)
- Version management and release workflow
- GitLab integration best practices
