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.2.0.tar.gz (33.1 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.2.0-py3-none-any.whl (37.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: updater_gitplucker-0.2.0.tar.gz
  • Upload date:
  • Size: 33.1 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.2.0.tar.gz
Algorithm Hash digest
SHA256 19ab0886eee71a5aab929f013141f4a9e7833d228705894ba28d1992575a5a2a
MD5 3b195aaf531c782c6a0fb79154d56e03
BLAKE2b-256 319ea3e6d7b5c796bd3ee60dcad6a085f38f6533ade9d571ebd315b783718856

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for updater_gitplucker-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 95ca2a59d7147f35c4888b8f782b5d983433d7cc409c55cb0b91470fd19a8675
MD5 3f714c51a7204f968bacbde636365892
BLAKE2b-256 3da49925196eaeaa6161bac29e12019eddb6252db479fbc3e6624e8ad77f9c52

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