Stabilize packaging and scheduler storage
This commit is contained in:
@@ -1,37 +1,173 @@
|
||||
# PySentry
|
||||
|
||||
PySentry is a cross-platform desktop scheduler inspired by cron.
|
||||
PySentry is a cross-platform desktop scheduler inspired by cron. It provides a native GUI for creating, grouping, pausing, running, and monitoring scheduled shell commands.
|
||||
|
||||
The project is starting with the GUI shell first, then the scheduling core.
|
||||
## Features
|
||||
|
||||
- Native desktop GUI built with Fyne.
|
||||
- Job storage in one clean YAML file.
|
||||
- App settings in a separate YAML file.
|
||||
- `@every` schedules and standard 5-field cron expressions.
|
||||
- Manual and scheduled command runs.
|
||||
- Per-run `.log` files with stdout/stderr.
|
||||
- Log cleanup by maximum file count and maximum age.
|
||||
- Global pause/resume for all job execution.
|
||||
- Windows tray support.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Go 1.22 or newer
|
||||
- A C compiler for Fyne builds on Windows, for example MSYS2/MinGW-w64
|
||||
Common:
|
||||
|
||||
## Run
|
||||
- Go 1.22 or newer.
|
||||
|
||||
```powershell
|
||||
go mod tidy
|
||||
go run ./cmd/pysentry
|
||||
Windows:
|
||||
|
||||
- MSYS2 with UCRT64 GCC in `C:\msys64\ucrt64\bin`.
|
||||
|
||||
Linux:
|
||||
|
||||
- A C compiler.
|
||||
- Fyne native build dependencies, including OpenGL/X11 development packages.
|
||||
|
||||
On Debian/Ubuntu, the Linux dependencies are typically:
|
||||
|
||||
```bash
|
||||
sudo apt install golang gcc libgl1-mesa-dev xorg-dev
|
||||
```
|
||||
|
||||
If Go is installed but not available in `PATH`, use the full path:
|
||||
## Build
|
||||
|
||||
Windows:
|
||||
|
||||
```powershell
|
||||
.\scripts\build-windows.ps1
|
||||
```
|
||||
|
||||
The binary is written to:
|
||||
|
||||
```text
|
||||
dist\windows\pysentry.exe
|
||||
```
|
||||
|
||||
Linux:
|
||||
|
||||
```bash
|
||||
chmod +x ./scripts/build-linux.sh
|
||||
./scripts/build-linux.sh
|
||||
```
|
||||
|
||||
The binary is written to:
|
||||
|
||||
```text
|
||||
dist/linux/pysentry
|
||||
```
|
||||
|
||||
Linux using Docker:
|
||||
|
||||
```powershell
|
||||
.\scripts\build-linux-docker.ps1
|
||||
```
|
||||
|
||||
The binary is copied to:
|
||||
|
||||
```text
|
||||
dist\linux\pysentry
|
||||
```
|
||||
|
||||
## Run From Source
|
||||
|
||||
Windows:
|
||||
|
||||
```powershell
|
||||
$env:Path = 'C:\msys64\ucrt64\bin;' + $env:Path
|
||||
$env:CGO_ENABLED = '1'
|
||||
& 'C:\Program Files\Go\bin\go.exe' run ./cmd/pysentry
|
||||
```
|
||||
|
||||
## Current shape
|
||||
Linux:
|
||||
|
||||
```bash
|
||||
CGO_ENABLED=1 go run ./cmd/pysentry
|
||||
```
|
||||
|
||||
## Storage
|
||||
|
||||
PySentry creates its runtime files next to the executable by default.
|
||||
|
||||
`pysentry.yaml` stores application settings:
|
||||
|
||||
```yaml
|
||||
jobs_dir: .
|
||||
logs_dir: logs
|
||||
max_log_files: 100
|
||||
max_log_age_days: 30
|
||||
keep_running_in_tray: true
|
||||
notify_on_failure: true
|
||||
```
|
||||
|
||||
`jobs.yaml` stores only job definitions:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
- id: 1
|
||||
name: Hello scheduler
|
||||
folder: Examples
|
||||
schedule: '@every 10s'
|
||||
command: echo PySentry test job: scheduler is alive
|
||||
enabled: true
|
||||
```
|
||||
|
||||
Command output is written to separate files under `logs_dir`. File names include the run timestamp and job name, for example:
|
||||
|
||||
```text
|
||||
20260614-224306_Hello_scheduler.log
|
||||
```
|
||||
|
||||
## Schedules
|
||||
|
||||
Fast interval schedules:
|
||||
|
||||
```text
|
||||
@every 10s
|
||||
@every 5m
|
||||
@every 1h30m
|
||||
```
|
||||
|
||||
Standard 5-field cron schedules:
|
||||
|
||||
```text
|
||||
*/5 * * * * every five minutes
|
||||
0 2 * * * every day at 02:00
|
||||
30 9 * * 1-5 weekdays at 09:30
|
||||
```
|
||||
|
||||
## Using The App
|
||||
|
||||
1. Start PySentry.
|
||||
2. Use `New job` to create a command.
|
||||
3. Set `Schedule`, `Command`, optional `Folder`, and `Enabled`.
|
||||
4. Use `Run now` for a manual test run.
|
||||
5. Use `Pause` to disable one job.
|
||||
6. Use `Pause all` as a global stop switch.
|
||||
7. Open `History` to see whether a run was `Manual`, `Schedule`, or `UI`.
|
||||
8. Open `Settings` to change `jobs_dir`, `logs_dir`, and log cleanup limits. Use `Browse` to choose directories.
|
||||
|
||||
Changing `jobs_dir` saves the current job list to the new directory.
|
||||
|
||||
## Project Layout
|
||||
|
||||
- `cmd/pysentry` starts the desktop app.
|
||||
- `internal/app` contains the first Fyne-based interface prototype.
|
||||
- `internal/core` contains YAML storage, command execution, and the first scheduler loop.
|
||||
- Jobs can be created, edited, paused/resumed, run manually, and persisted to YAML.
|
||||
- Settings are stored in `pysentry.yaml` next to the executable.
|
||||
- Jobs are stored in one `jobs.yaml` file. The job directory is configured by `jobs_dir` and defaults to the executable directory.
|
||||
- Command output is also written to per-run `.log` files in `logs_dir`. Log filenames include the run timestamp and job name.
|
||||
- Log cleanup is controlled by `max_log_files` and `max_log_age_days`.
|
||||
- The current scheduler supports `@every` schedules such as `@every 10s` and `@every 1m`.
|
||||
- Run history records include a `trigger` value such as `Manual`, `Schedule`, or `UI`.
|
||||
- Cron expression parsing is planned for the next phase.
|
||||
- `internal/app` contains the GUI.
|
||||
- `internal/core` contains YAML storage, command execution, scheduling, and log cleanup.
|
||||
- `assets` contains app icons.
|
||||
- `scripts` contains build helpers.
|
||||
|
||||
## Dependencies
|
||||
|
||||
PySentry keeps the direct dependency list intentionally small:
|
||||
|
||||
- `fyne.io/fyne/v2` for the native GUI.
|
||||
- `github.com/robfig/cron/v3` for cron schedule parsing.
|
||||
- `gopkg.in/yaml.v3` for YAML settings and jobs.
|
||||
|
||||
The remaining entries in `go.mod` are indirect dependencies pulled by Fyne and the Go module resolver.
|
||||
|
||||
Reference in New Issue
Block a user