Skip to main content

Modular, pluggable GitHub updater library for Python-glued projects (release / source / python-source channels with 3-way merge and dependency auto-detection).

Project description

updater-gitplucker

A modular, pluggable GitHub updater library for Python-glued projects. Drop it into any of your apps to keep them up to date from GitHub — with a safety allowlist, a 3-way merge that preserves your local edits, and automatic Python dependency detection/installation.

  • Import name: gitplucker · Package: updater-gitplucker
  • Zero required dependencies — the core runs on the Python standard library.
  • Passive by design — it hands you an inspectable plan; you decide when to apply. Trigger it manually, at startup, or from a background thread.
from gitplucker import Updater, UpdaterConfig, RepoSubscription, Channel
from pathlib import Path

config = UpdaterConfig(
    install_root=Path("/path/to/your/app"),         # where the app lives on disk
    allowed_repos=["your-org/your-app"],            # nothing outside this is ever fetched
    subscriptions=[
        RepoSubscription("your-org/your-app", branches=["main"],
                         channel=Channel.PYTHON_SOURCE),
    ],
    token="ghp_...",                                # optional (private repos / rate limits)
)

updater = Updater(config)
for plan in updater.check():                        # dry run — nothing written yet
    print(plan.summary())
    if plan.has_update and not plan.conflicts:
        updater.apply(plan)                         # backup → write → install deps
    else:
        updater.discard(plan)

Install

pip install updater-gitplucker

Or the latest from source:

pip install "git+https://github.com/uukjtisa/updater-gitplucker.git"

Concepts

Allowlist (security boundary)

allowed_repos is enforced at the network layer: any repo not listed is rejected before any request. Every subscription's repo must be allowlisted.

Channels — how a repo is updated

Channel Source Best for
Channel.RELEASE Latest GitHub Release + assets (.zip, .whl, …) Versioned/shipped builds
Channel.SOURCE Raw source at a branch tip (zipball) Repos without formal releases
Channel.PYTHON_SOURCE SOURCE + 3-way merge + dependency auto-detect Python apps held together by scripts (the main use case)

Apply strategies — what an update replaces (config.apply_strategy)

Strategy Effect
ApplyStrategy.WHOLE_APP (default) Add/modify/merge/delete the tracked tree, with backup + rollback
ApplyStrategy.SELECTIVE Only paths matching selective_globs; never deletes
ApplyStrategy.PACKAGE pip install the downloaded wheel/sdist (RELEASE channel)

Triggers — when it runs

  • Manual — just call updater.check() / updater.apply() (or ManualTrigger).
  • StartupStartupTrigger(updater).run(on_update=prompt_fn).
  • BackgroundBackgroundTrigger(updater, interval_seconds=3600).start(...).

All three are optional wrappers; the library never acts on its own.

3-way merge (PYTHON_SOURCE)

After each apply, gitplucker snapshots the exact files it pulled (the base). On the next update it merges base → your local edits with base → upstream. Non-overlapping changes merge cleanly; only edits to the same lines produce a conflict. config.conflict_policy decides what happens then: mark (git-style markers, default), local, remote, or abort.

Dependency auto-detection (PYTHON_SOURCE)

Every incoming .py is scanned for imports; standard-library and the app's own packages are filtered out; anything left that isn't installed is surfaced in plan.dependency_changes and (if auto_install_deps=True) pip install-ed on apply. Version pins in your requirements.txt are honored. Newly-added modules are flagged is_new.

Inspecting a plan

plan.summary()            # one-line human summary
plan.has_update           # bool
plan.file_changes         # list[FileChange]  (added/modified/merged/conflict/deleted)
plan.conflicts            # list[FileChange]  (subset needing attention)
plan.dependency_changes   # list[DependencyChange]
plan.new_dependencies     # subset that are newly referenced
plan.warnings             # e.g. "local changes overwritten (no merge available)"
plan.release_notes        # release body / source stamp

Events

updater.events.on(lambda name, payload: print(name, payload))

Emitted: check.start/done, download.progress, dep.detected/install, apply.file, backup, rollback, apply.done. A throwing listener can never break an update.

State & rollback

Everything lives in install_root/.gitplucker/ (override via state_dir): manifest.json (installed version + known modules per repo/branch), base/ (merge snapshots), backups/ (timestamped pre-apply copies for manual rollback). A failed apply auto-rolls-back the current batch.

See docs/INTEGRATION.md for a step-by-step wiring guide and examples/basic.py for a runnable script.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

updater_gitplucker-0.1.0.tar.gz (31.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

updater_gitplucker-0.1.0-py3-none-any.whl (36.8 kB view details)

Uploaded Python 3

File details

Details for the file updater_gitplucker-0.1.0.tar.gz.

File metadata

  • Download URL: updater_gitplucker-0.1.0.tar.gz
  • Upload date:
  • Size: 31.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for updater_gitplucker-0.1.0.tar.gz
Algorithm Hash digest
SHA256 61032343d71c54de4006ae7cdb6348d59ccfed8e8fd99500d001f469a7414fb1
MD5 9499a8978708969861721377ef7be81e
BLAKE2b-256 7495792ac688979ac60b3528ba6f33a372754cc05633d497d8ab1b5da5f3f39d

See more details on using hashes here.

File details

Details for the file updater_gitplucker-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for updater_gitplucker-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5a5fba156d4d1d3f0305f946d758b211700dc93c37236c62822074c2145e2e2e
MD5 9703fc006227979fcb0f376cbb815313
BLAKE2b-256 33a2cde6a23f6133d99436c566ef22801a3e59a7d80a925dd4cf880ea1126659

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page