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.6.0.tar.gz (39.8 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.6.0-py3-none-any.whl (42.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: updater_gitplucker-0.6.0.tar.gz
  • Upload date:
  • Size: 39.8 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.6.0.tar.gz
Algorithm Hash digest
SHA256 3ced49fa08a1defccd833ba319d68d45c0cb22f21cd50826edf0d220e2b00d0b
MD5 da9fc22668b272a3511506253034c4ce
BLAKE2b-256 06718d24746c2b9822353261593b9156e15bb6f3423d16c6b30c9e03581aa2fb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for updater_gitplucker-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 039e4b411395e2937d591cf31921beef35d2838061b5d5d926bce5fa58b0dd2b
MD5 2672ff54faad7da060fd149e57dea4f5
BLAKE2b-256 9ee471fd780c246eb60b354dc9491544f079823477871818fee3496ad5603333

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