{"id":29554993,"url":"https://github.com/jftuga/py-file-versioning","last_synced_at":"2026-02-19T01:31:30.264Z","repository":{"id":273807634,"uuid":"919468662","full_name":"jftuga/py-file-versioning","owner":"jftuga","description":"Python CLI tool and library to version files","archived":false,"fork":false,"pushed_at":"2025-02-13T13:17:17.000Z","size":34,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-25T12:51:28.631Z","etag":null,"topics":["api","command-line","command-line-tool","devops","file-version","python","python-api","system-administration","versioning"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/py-file-versioning/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jftuga.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-01-20T12:54:28.000Z","updated_at":"2025-02-12T13:48:04.000Z","dependencies_parsed_at":"2025-01-23T04:28:30.702Z","dependency_job_id":"6ea1600e-4b5b-4429-b7fe-ddce44ab6177","html_url":"https://github.com/jftuga/py-file-versioning","commit_stats":null,"previous_names":["jftuga/py-file-versioning"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/jftuga/py-file-versioning","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jftuga%2Fpy-file-versioning","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jftuga%2Fpy-file-versioning/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jftuga%2Fpy-file-versioning/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jftuga%2Fpy-file-versioning/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jftuga","download_url":"https://codeload.github.com/jftuga/py-file-versioning/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jftuga%2Fpy-file-versioning/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29600752,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T00:59:38.239Z","status":"ssl_error","status_checked_at":"2026-02-19T00:59:36.936Z","response_time":162,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","command-line","command-line-tool","devops","file-version","python","python-api","system-administration","versioning"],"created_at":"2025-07-18T08:37:43.455Z","updated_at":"2026-02-19T01:31:30.239Z","avatar_url":"https://github.com/jftuga.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# py-file-versioning\n\nA flexible file versioning system with compression support, written in Python.\n\n**NOTE: The cli tool and API are still under development and will not be stable until v1.0.0 is released**\n\n## Table of Contents\n\n- [Features](#features)\n- [Package Name Convention](#package-name-convention)\n- [Installation](#installation)\n  - [From PyPI](#from-pypi)\n  - [From Source](#from-source)\n  - [Command Line Usage](#command-line-usage)\n  - [Demo Shell Session](#demo-shell-session)\n  - [Python API Usage](#python-api-usage)\n- [Configuration Options](#configuration-options)\n  - [FileVersioningConfig Parameters](#fileversioningconfig-parameters)\n  - [Command Line Options](#command-line-options)\n- [Examples](#examples)\n  - [Maintaining Multiple Versions](#maintaining-multiple-versions)\n  - [Using Different Compression Types](#using-different-compression-types)\n  - [Version File Naming](#version-file-naming)\n- [Development](#development)\n  - [Setting Up Development Environment](#setting-up-development-environment)\n  - [Running Tests](#running-tests)\n  - [Code Quality Checks](#code-quality-checks)\n- [License](#license)\n\n## Features\n\n* Create versioned backups of files with automatic sequence numbering\n* Multiple compression options: gzip, bzip2, xz, or uncompressed\n* Configurable timestamp formats (UTC or local time)\n* Limit the number of versions kept per file\n* Command-line interface for easy integration\n* Support for Unicode filenames\n* Cross-platform compatibility\n\n## Package Name Convention\n\nWhile the package is installed as `py-file-versioning` (using hyphens), you should use `py_file_versioning` (using underscores) in your Python imports following Python naming conventions.\n\n## Installation\n\n### From PyPI\n\n```bash\npip install py-file-versioning\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/jftuga/py-file-versioning.git\ncd py-file-versioning\npip install .\n```\n\nFor development installation:\n\n```bash\nuv venv\nsource .venv/bin/activate\nuv pip install -e '.[dev]'\nuv pip list\n```\n\n### Command Line Usage\n\nThe package installs a command-line tool called `pyfileversioning`. Here are some common operations:\n\nCreate a version:\n```bash\npyfileversioning create myfile.txt\n```\n\nCreate a compressed version:\n```bash\npyfileversioning create myfile.txt -c gz  # or --compression gz\n```\n\nList all versions:\n```bash\npyfileversioning list myfile.txt\n```\n\nRestore a specific version to a new file path:\n```bash\npyfileversioning restore versions/myfile--20240120.123456_001.txt.gz --target /path/to/restored_file.txt\n```\n\nRemove a version:\n```bash\npyfileversioning remove versions/myfile--20240120.123456_001.txt.gz\n```\n\n### Demo Shell Session\n\nHere's a practical demonstration of using the command-line interface:\n\n```bash\n# Create a sample config file\n$ echo \"database_host=localhost\" \u003e config.ini\n$ cat config.ini\ndatabase_host=localhost\n\n# Create first version (uncompressed)\n$ pyfileversioning create config.ini -d backups\nCreated version: backups/config--20250207.044841_001--loc_mod.ini\n\n# Update the file content\n$ echo \"database_port=5432\" \u003e\u003e config.ini\n\n# Create compressed version\n$ pyfileversioning create config.ini -d backups -c gz\nCreated version: backups/config--20250207.044924_001--loc_mod.ini.gz\n\n# List all versions\n$ pyfileversioning list config.ini -d backups\nPath                                        | Sequence | Size | Timestamp           | TimeZone | TimestampSrc\n====                                        | ======== | ==== | =========           | ======== | ============\nconfig--20250207.044924_001--loc_mod.ini.gz |        1 |   95 | 2025-02-07T04:49:24 |    local |  modify time\nconfig--20250207.044841_001--loc_mod.ini    |        1 |   24 | 2025-02-07T04:48:41 |    local |  modify time\n\n# Add more content and create another version with UTC time\n$ echo \"database_name=myapp\" \u003e\u003e config.ini\n$ pyfileversioning create config.ini -d backups -c gz -u\nCreated version: backups/config--20250207.095009_001--utc_mod.ini.gz\n\n# View all versions with size and timestamp (note: mixed timezone versions not recommended)\n$ pyfileversioning list config.ini -d backups\nPath                                        | Sequence | Size | Timestamp           | TimeZone | TimestampSrc\n====                                        | ======== | ==== | =========           | ======== | ============\nconfig--20250207.095009_001--utc_mod.ini.gz |        1 |  107 | 2025-02-07T09:50:09 |      utc |  modify time\nconfig--20250207.044924_001--loc_mod.ini.gz |        1 |   95 | 2025-02-07T04:49:24 |    local |  modify time\nconfig--20250207.044841_001--loc_mod.ini    |        1 |   24 | 2025-02-07T04:48:41 |    local |  modify time\n```\n\n### Python API Usage\n\nThe library provides a flexible API for file versioning. Here's how to use it:\n\n```python\nfrom py_file_versioning import FileVersioning, FileVersioningConfig\n\n# Create a test file\ndef create_example_file(filename: str) -\u003e None:\n    content = \"\"\"\n    # Database configuration settings\n    db_host = db.example.com\n    db_port = 5432\n    db_name = production_db\n    \"\"\".strip()\n    with open(filename, 'w') as f:\n        f.write(content)\n\n# Basic usage\nfilename = \"example.ini\"\ncreate_example_file(filename)\n\nversioning = FileVersioning()\nversion_path, removed, error = versioning.create_version(filename)\nif error:\n    print(f\"Warning: {error}\")\nprint(version_path)\n\n# Advanced configuration\nconfig = FileVersioningConfig(\n    versions_path=\"backups\",     # Store versions in 'backups' directory\n    compression=\"gz\",            # Use gzip compression\n    max_versions=5,             # Keep only last 5 versions\n    use_utc=True,              # Use UTC timestamps\n    use_modified_time=True,    # Use file's modified time\n    delimiter=\"__\"             # Custom delimiter for version files\n)\nversioning = FileVersioning(config)\nversion_path, removed, error = versioning.create_version(filename)\nif error:\n    print(f\"Warning: {error}\")\nprint(version_path)\n```\n\n## Configuration Options\n\n### FileVersioningConfig Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| delimiter | str | \"--\" | Separator between filename and version information |\n| use_utc | bool | False | Use UTC timestamps instead of local time |\n| versions_path | str | \"versions\" | Directory to store versions |\n| compression | str | \"none\" | Compression type: \"none\", \"gz\", \"bz2\", \"xz\" |\n| max_versions | Optional[int] | None | Maximum number of versions to keep |\n| use_modified_time | bool | True | Use file's modified time instead of current time |\n\n### Command Line Options\n\n```\nusage: pyfileversioning [-h] [-V] [-t TARGET] [-d VERSIONS_PATH]\n                        [-c {none,gz,bz2,xz}] [-m MAX_VERSIONS] [-s {mod,sto}]\n                        [-u] [-D DELIMITER]\n                        [{create,restore,list,remove}] files [files ...]\n```\n\nOptions:\n* `-V, --version`: Show version information\n* `-t, --target`: Target file path for restore operation (must be full path to the restored file)\n* `-d, --versions-path`: Directory to store versions (default: versions)\n* `-c, --compression`: Compression type to use (none, gz, bz2, xz)\n* `-m, --max-versions`: Maximum number of versions to keep\n* `-s, --src`: Source for timestamps (mod: file modified time, sto: current time)\n* `-u, --utc`: Use UTC timezone for timestamps (default: local time)\n* `--delimiter DELIMITER`: The delimiter to use (default: --)\n\nEnvironment Variables:\n* `PFV_VERSIONS_PATH`: Override default versions directory\n* `PFV_COMPRESSION`: Override default compression type\n* `PFV_DELIMITER`: Override default delimiter\n\nNotes:\n* The tool supports file patterns (e.g., `*.txt`, `config*.ini`)\n* Multiple files can be specified for batch operations\n\n## Examples\n\n### Maintaining Multiple Versions\n\n```python\nfrom py_file_versioning import FileVersioning, FileVersioningConfig\n\n# Create versions with different timezone and timestamp combinations\nconfigs = [\n    # Local timezone versions\n    {\"use_utc\": False, \"use_modified_time\": True, \"desc\": \"local timezone, modified time\"},\n    {\"use_utc\": False, \"use_modified_time\": False, \"desc\": \"local timezone, current time\"},\n\n    # UTC timezone versions\n    {\"use_utc\": True, \"use_modified_time\": True, \"desc\": \"UTC timezone, modified time\"},\n    {\"use_utc\": True, \"use_modified_time\": False, \"desc\": \"UTC timezone, current time\"}\n]\n\nfor cfg in configs:\n    config = FileVersioningConfig(\n        use_utc=cfg[\"use_utc\"],\n        use_modified_time=cfg[\"use_modified_time\"]\n    )\n    versioning = FileVersioning(config)\n    version_path, removed, error = versioning.create_version(\"example.ini\")\n    print(version_path)\n```\n\n### Using Different Compression Types\n\n```python\nfrom py_file_versioning import FileVersioning, FileVersioningConfig\n\n# Create versions using each compression type\ncompression_types = [\"gz\", \"bz2\", \"xz\"]\n\nfor compression in compression_types:\n    config = FileVersioningConfig(\n        compression=compression,\n        use_utc=True,          # Use UTC time\n        use_modified_time=True # Use file's modified time\n    )\n    versioning = FileVersioning(config)\n    version_path, removed, error = versioning.create_version(\"example.ini\")\n    print(version_path)\n```\n\n### Version File Naming\n\nVersion files follow this naming pattern:\n```\n{original_name}{delimiter}{timestamp}_{sequence}{delimiter}{version_spec}{extension}[.compression_ext]\n```\n\nExample:\n```\nmyfile--20240120.123456_001--utc_mod.txt.gz\n```\n\nWhere:\n- `myfile` is the original filename\n- `--` is the delimiter (configurable)\n- `20240120.123456` is the timestamp (YYYYMMDD.HHMMSS)\n- `001` is the sequence number\n- `utc_mod` is the version specification:\n  - First part (`utc` or `loc`) indicates timezone (UTC or local)\n  - Second part (`mod` or `sto`) indicates timestamp source (modified time or stored/current time)\n- `.txt` is the original extension\n- `.gz` is the compression extension (if compression is used)\n\nNote: All versions of a file must use consistent timezone and timestamp source settings.\n\n## Development\n\n### Setting Up Development Environment\n\n```bash\n# Clone the repository\ngit clone https://github.com/jftuga/py-file-versioning.git\ncd py-file-versioning\n\n# Create and activate virtual environment\npython -m venv .venv\nsource .venv/bin/activate  # On Windows: .venv\\Scripts\\activate\n\n# Install development dependencies\npip install -e '.[dev]'\n```\n\n### Running Tests\n\n```bash\npytest\n```\n\nFor coverage report:\n```bash\npytest --cov=file_versioning --cov-report=html\n```\n\n### Code Quality Checks\n\n```bash\n# Format code\nblack .\n\n# Sort imports\nisort .\n\n# Style checking\nflake8\n\n# Linting\nruff check\n```\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjftuga%2Fpy-file-versioning","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjftuga%2Fpy-file-versioning","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjftuga%2Fpy-file-versioning/lists"}