remind-cli 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- remind_cli-1.0.0/.gitignore +71 -0
- remind_cli-1.0.0/PKG-INFO +86 -0
- remind_cli-1.0.0/README.md +50 -0
- remind_cli-1.0.0/build_tools/build.py +86 -0
- remind_cli-1.0.0/build_tools/build_deb.sh +124 -0
- remind_cli-1.0.0/build_tools/generate_homebrew_formula.py +153 -0
- remind_cli-1.0.0/build_tools/homebrew_formula.rb +45 -0
- remind_cli-1.0.0/build_tools/install.sh +332 -0
- remind_cli-1.0.0/build_tools/macos_launchd.plist +23 -0
- remind_cli-1.0.0/build_tools/systemd_service.service +14 -0
- remind_cli-1.0.0/pyproject.toml +79 -0
- remind_cli-1.0.0/src/remind_cli/__init__.py +4 -0
- remind_cli-1.0.0/src/remind_cli/__main__.py +6 -0
- remind_cli-1.0.0/src/remind_cli/ai.py +78 -0
- remind_cli-1.0.0/src/remind_cli/cli.py +99 -0
- remind_cli-1.0.0/src/remind_cli/cli_utils.py +121 -0
- remind_cli-1.0.0/src/remind_cli/commands/__init__.py +0 -0
- remind_cli-1.0.0/src/remind_cli/commands/add.py +88 -0
- remind_cli-1.0.0/src/remind_cli/commands/doctor.py +129 -0
- remind_cli-1.0.0/src/remind_cli/commands/done.py +35 -0
- remind_cli-1.0.0/src/remind_cli/commands/list.py +69 -0
- remind_cli-1.0.0/src/remind_cli/commands/login.py +78 -0
- remind_cli-1.0.0/src/remind_cli/commands/search.py +57 -0
- remind_cli-1.0.0/src/remind_cli/commands/settings.py +118 -0
- remind_cli-1.0.0/src/remind_cli/commands/uninstall.py +50 -0
- remind_cli-1.0.0/src/remind_cli/commands/update.py +114 -0
- remind_cli-1.0.0/src/remind_cli/commands/upgrade.py +57 -0
- remind_cli-1.0.0/src/remind_cli/commands/usage.py +80 -0
- remind_cli-1.0.0/src/remind_cli/config.py +123 -0
- remind_cli-1.0.0/src/remind_cli/db.py +167 -0
- remind_cli-1.0.0/src/remind_cli/models.py +66 -0
- remind_cli-1.0.0/src/remind_cli/notifications.py +308 -0
- remind_cli-1.0.0/src/remind_cli/output.py +222 -0
- remind_cli-1.0.0/src/remind_cli/platform_capabilities.py +215 -0
- remind_cli-1.0.0/src/remind_cli/platform_utils.py +199 -0
- remind_cli-1.0.0/src/remind_cli/plugins.py +57 -0
- remind_cli-1.0.0/src/remind_cli/premium.py +108 -0
- remind_cli-1.0.0/src/remind_cli/scheduler.py +291 -0
- remind_cli-1.0.0/src/remind_cli/services/__init__.py +6 -0
- remind_cli-1.0.0/src/remind_cli/services/ai_service.py +119 -0
- remind_cli-1.0.0/src/remind_cli/services/config_service.py +63 -0
- remind_cli-1.0.0/src/remind_cli/services/daemon_service.py +252 -0
- remind_cli-1.0.0/src/remind_cli/services/reminder_service.py +113 -0
- remind_cli-1.0.0/src/remind_cli/services/scheduler_service.py +134 -0
- remind_cli-1.0.0/src/remind_cli/ui/__init__.py +1 -0
- remind_cli-1.0.0/src/remind_cli/utils.py +141 -0
- remind_cli-1.0.0/src/remind_cli/version_check.py +72 -0
- remind_cli-1.0.0/tests/__init__.py +1 -0
- remind_cli-1.0.0/tests/conftest.py +25 -0
- remind_cli-1.0.0/tests/integration/__init__.py +1 -0
- remind_cli-1.0.0/tests/integration/test_commands.py +412 -0
- remind_cli-1.0.0/tests/test_reminder_service.py +197 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Environment
|
|
2
|
+
.env
|
|
3
|
+
.env.*
|
|
4
|
+
!.env.example
|
|
5
|
+
|
|
6
|
+
# Databases
|
|
7
|
+
*.db
|
|
8
|
+
*.db-wal
|
|
9
|
+
*.db-shm
|
|
10
|
+
*.sqlite
|
|
11
|
+
*.sqlite3
|
|
12
|
+
*.pgsql
|
|
13
|
+
|
|
14
|
+
# Python
|
|
15
|
+
__pycache__/
|
|
16
|
+
*.py[cod]
|
|
17
|
+
*$py.class
|
|
18
|
+
*.so
|
|
19
|
+
.Python
|
|
20
|
+
build/
|
|
21
|
+
develop-eggs/
|
|
22
|
+
dist/
|
|
23
|
+
downloads/
|
|
24
|
+
eggs/
|
|
25
|
+
.eggs/
|
|
26
|
+
lib/
|
|
27
|
+
lib64/
|
|
28
|
+
parts/
|
|
29
|
+
sdist/
|
|
30
|
+
var/
|
|
31
|
+
wheels/
|
|
32
|
+
*.egg-info/
|
|
33
|
+
.installed.cfg
|
|
34
|
+
*.egg
|
|
35
|
+
|
|
36
|
+
# Virtual environments
|
|
37
|
+
venv/
|
|
38
|
+
env/
|
|
39
|
+
ENV/
|
|
40
|
+
.venv
|
|
41
|
+
|
|
42
|
+
# IDE
|
|
43
|
+
.vscode/
|
|
44
|
+
.idea/
|
|
45
|
+
*.swp
|
|
46
|
+
*.swo
|
|
47
|
+
*~
|
|
48
|
+
|
|
49
|
+
# Testing
|
|
50
|
+
.pytest_cache/
|
|
51
|
+
.coverage
|
|
52
|
+
htmlcov/
|
|
53
|
+
.tox/
|
|
54
|
+
|
|
55
|
+
# OS
|
|
56
|
+
.DS_Store
|
|
57
|
+
Thumbs.db
|
|
58
|
+
|
|
59
|
+
# Build artifacts
|
|
60
|
+
dist/
|
|
61
|
+
build/
|
|
62
|
+
*.egg-info/
|
|
63
|
+
|
|
64
|
+
# Logs
|
|
65
|
+
*.log
|
|
66
|
+
logs/
|
|
67
|
+
|
|
68
|
+
# Node (future web app)
|
|
69
|
+
node_modules/
|
|
70
|
+
.next/
|
|
71
|
+
out/
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: remind-cli
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A cross-platform CLI reminder and notification engine with AI-powered suggestions and smart nudges
|
|
5
|
+
Project-URL: Homepage, https://github.com/hamzaplojovic/remind
|
|
6
|
+
Project-URL: Repository, https://github.com/hamzaplojovic/remind.git
|
|
7
|
+
Project-URL: Documentation, https://github.com/hamzaplojovic/remind/blob/main/README.md
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/hamzaplojovic/remind/issues
|
|
9
|
+
Author: Remind Contributors
|
|
10
|
+
License: MIT
|
|
11
|
+
Keywords: ai,cli,notifications,reminders,scheduler
|
|
12
|
+
Requires-Python: >=3.12
|
|
13
|
+
Requires-Dist: dateparser
|
|
14
|
+
Requires-Dist: httpx
|
|
15
|
+
Requires-Dist: notify-py
|
|
16
|
+
Requires-Dist: pydantic
|
|
17
|
+
Requires-Dist: pydantic-settings
|
|
18
|
+
Requires-Dist: remind-database
|
|
19
|
+
Requires-Dist: remind-shared
|
|
20
|
+
Requires-Dist: sqlalchemy
|
|
21
|
+
Requires-Dist: tabulate
|
|
22
|
+
Requires-Dist: typer[all]
|
|
23
|
+
Provides-Extra: build
|
|
24
|
+
Requires-Dist: pyinstaller>=6.0.0; extra == 'build'
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: mypy>=1.5.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-mock>=3.11.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
32
|
+
Provides-Extra: linux
|
|
33
|
+
Requires-Dist: dbus-python; extra == 'linux'
|
|
34
|
+
Provides-Extra: macos
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# Remind CLI
|
|
38
|
+
|
|
39
|
+
AI-powered command-line reminder and notification engine.
|
|
40
|
+
|
|
41
|
+
## Quick Start
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
remind add "Buy groceries" --due "tomorrow 5pm"
|
|
45
|
+
remind list
|
|
46
|
+
remind done 1
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- AI-powered reminder suggestions
|
|
52
|
+
- Smart scheduling and notifications
|
|
53
|
+
- Full-text search
|
|
54
|
+
- Cross-platform support (macOS, Linux, Windows)
|
|
55
|
+
- License-based plan tiers (Free, Pro, Enterprise)
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install remind-cli
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Or build from source:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
uv sync
|
|
67
|
+
uv run remind --help
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Commands
|
|
71
|
+
|
|
72
|
+
- `add` - Create a new reminder
|
|
73
|
+
- `list` - List all reminders
|
|
74
|
+
- `done` - Mark reminder as complete
|
|
75
|
+
- `search` - Search reminders by text
|
|
76
|
+
- `login` - Authenticate with license token
|
|
77
|
+
- `settings` - Manage configuration
|
|
78
|
+
- `report` - View usage statistics
|
|
79
|
+
- `scheduler` - Manage background scheduler
|
|
80
|
+
- `doctor` - Diagnose issues
|
|
81
|
+
- `upgrade` - View pricing plans
|
|
82
|
+
- `uninstall` - Remove Remind
|
|
83
|
+
|
|
84
|
+
## Documentation
|
|
85
|
+
|
|
86
|
+
See [../../REFACTORING_COMPLETE.md](../../REFACTORING_COMPLETE.md) for architecture and implementation details.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Remind CLI
|
|
2
|
+
|
|
3
|
+
AI-powered command-line reminder and notification engine.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
remind add "Buy groceries" --due "tomorrow 5pm"
|
|
9
|
+
remind list
|
|
10
|
+
remind done 1
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- AI-powered reminder suggestions
|
|
16
|
+
- Smart scheduling and notifications
|
|
17
|
+
- Full-text search
|
|
18
|
+
- Cross-platform support (macOS, Linux, Windows)
|
|
19
|
+
- License-based plan tiers (Free, Pro, Enterprise)
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install remind-cli
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or build from source:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv sync
|
|
31
|
+
uv run remind --help
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
- `add` - Create a new reminder
|
|
37
|
+
- `list` - List all reminders
|
|
38
|
+
- `done` - Mark reminder as complete
|
|
39
|
+
- `search` - Search reminders by text
|
|
40
|
+
- `login` - Authenticate with license token
|
|
41
|
+
- `settings` - Manage configuration
|
|
42
|
+
- `report` - View usage statistics
|
|
43
|
+
- `scheduler` - Manage background scheduler
|
|
44
|
+
- `doctor` - Diagnose issues
|
|
45
|
+
- `upgrade` - View pricing plans
|
|
46
|
+
- `uninstall` - Remove Remind
|
|
47
|
+
|
|
48
|
+
## Documentation
|
|
49
|
+
|
|
50
|
+
See [../../REFACTORING_COMPLETE.md](../../REFACTORING_COMPLETE.md) for architecture and implementation details.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Build script for creating standalone binaries."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import platform
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def build_binary(output_dir: Path | None = None) -> None:
|
|
11
|
+
"""Build a standalone binary using PyInstaller."""
|
|
12
|
+
if output_dir is None:
|
|
13
|
+
output_dir = Path("dist")
|
|
14
|
+
|
|
15
|
+
output_dir.mkdir(exist_ok=True)
|
|
16
|
+
|
|
17
|
+
system = platform.system()
|
|
18
|
+
arch = platform.machine()
|
|
19
|
+
|
|
20
|
+
print(f"Building for {system} ({arch})")
|
|
21
|
+
|
|
22
|
+
# Find notify-py Notificator.app for macOS notifications
|
|
23
|
+
notificator_path = None
|
|
24
|
+
if system == "Darwin":
|
|
25
|
+
try:
|
|
26
|
+
import notifypy.os_notifiers
|
|
27
|
+
|
|
28
|
+
os_notifiers_dir = os.path.dirname(notifypy.os_notifiers.__file__)
|
|
29
|
+
notificator_path = os.path.join(os_notifiers_dir, "binaries", "Notificator.app")
|
|
30
|
+
if not os.path.exists(notificator_path):
|
|
31
|
+
notificator_path = None
|
|
32
|
+
print("⚠ Warning: Could not find Notificator.app for notifications")
|
|
33
|
+
except (ImportError, AttributeError):
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
# PyInstaller command
|
|
37
|
+
cmd = [
|
|
38
|
+
sys.executable,
|
|
39
|
+
"-m",
|
|
40
|
+
"PyInstaller",
|
|
41
|
+
"--onefile",
|
|
42
|
+
"--console",
|
|
43
|
+
"--name",
|
|
44
|
+
"remind",
|
|
45
|
+
"--distpath",
|
|
46
|
+
str(output_dir),
|
|
47
|
+
"--workpath",
|
|
48
|
+
"build",
|
|
49
|
+
"--specpath",
|
|
50
|
+
"build",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
# Add notify-py bundle on macOS
|
|
54
|
+
if notificator_path:
|
|
55
|
+
binaries_dir = os.path.dirname(notificator_path)
|
|
56
|
+
cmd.extend(["--add-data", f"{binaries_dir}:notifypy/os_notifiers"])
|
|
57
|
+
|
|
58
|
+
cmd.append("remind/__main__.py")
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
subprocess.run(cmd, check=True, cwd=Path(__file__).parent.parent)
|
|
62
|
+
binary_name = "remind.exe" if system == "Windows" else "remind"
|
|
63
|
+
binary_path = output_dir / binary_name
|
|
64
|
+
print(f"✓ Binary built: {binary_path}")
|
|
65
|
+
print(f" Size: {binary_path.stat().st_size / (1024 * 1024):.2f} MB")
|
|
66
|
+
except subprocess.CalledProcessError as e:
|
|
67
|
+
print(f"✗ Build failed: {e}")
|
|
68
|
+
sys.exit(1)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def build_deb_package() -> None:
|
|
72
|
+
"""Build a Debian package."""
|
|
73
|
+
print("Building Debian package...")
|
|
74
|
+
# Placeholder for deb building
|
|
75
|
+
print("Not yet implemented")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def build_rpm_package() -> None:
|
|
79
|
+
"""Build an RPM package."""
|
|
80
|
+
print("Building RPM package...")
|
|
81
|
+
# Placeholder for rpm building
|
|
82
|
+
print("Not yet implemented")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if __name__ == "__main__":
|
|
86
|
+
build_binary()
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Build Debian/Ubuntu package for Remind
|
|
3
|
+
# Usage: ./build_deb.sh [VERSION]
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
VERSION="${1:-0.1.0}"
|
|
8
|
+
REPO_NAME="remind"
|
|
9
|
+
ARCH="amd64"
|
|
10
|
+
OUTPUT_DIR="dist"
|
|
11
|
+
|
|
12
|
+
# Create build directory structure
|
|
13
|
+
BUILD_DIR=$(mktemp -d)
|
|
14
|
+
trap "rm -rf $BUILD_DIR" EXIT
|
|
15
|
+
|
|
16
|
+
echo "Building Debian package for Remind ${VERSION}..."
|
|
17
|
+
|
|
18
|
+
# Create directory structure for deb package
|
|
19
|
+
mkdir -p "${BUILD_DIR}/DEBIAN"
|
|
20
|
+
mkdir -p "${BUILD_DIR}/usr/local/bin"
|
|
21
|
+
mkdir -p "${BUILD_DIR}/usr/share/doc/remind"
|
|
22
|
+
|
|
23
|
+
# Copy binary
|
|
24
|
+
if [ ! -f "dist/remind" ]; then
|
|
25
|
+
echo "Error: dist/remind not found. Run 'python build_tools/build.py' first."
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
cp "dist/remind" "${BUILD_DIR}/usr/local/bin/remind"
|
|
30
|
+
chmod 755 "${BUILD_DIR}/usr/local/bin/remind"
|
|
31
|
+
|
|
32
|
+
# Create DEBIAN/control file
|
|
33
|
+
cat > "${BUILD_DIR}/DEBIAN/control" << EOF
|
|
34
|
+
Package: ${REPO_NAME}
|
|
35
|
+
Version: ${VERSION}
|
|
36
|
+
Architecture: ${ARCH}
|
|
37
|
+
Maintainer: Remind Contributors <support@remind.dev>
|
|
38
|
+
Description: AI-powered CLI reminder and notification engine
|
|
39
|
+
Remind is a cross-platform CLI tool for managing reminders with desktop
|
|
40
|
+
notifications and AI-powered suggestions (premium feature).
|
|
41
|
+
.
|
|
42
|
+
Features:
|
|
43
|
+
* Instant reminder capture with natural language dates
|
|
44
|
+
* Desktop notifications when reminders are due
|
|
45
|
+
* Local SQLite database storage
|
|
46
|
+
* Premium AI rephrasing and smart nudges
|
|
47
|
+
* Analytics and reporting
|
|
48
|
+
Section: utilities
|
|
49
|
+
Priority: optional
|
|
50
|
+
Depends: libnotify-bin
|
|
51
|
+
Homepage: https://github.com/hamzaplojovic/remember
|
|
52
|
+
EOF
|
|
53
|
+
|
|
54
|
+
# Create DEBIAN/postinst script
|
|
55
|
+
cat > "${BUILD_DIR}/DEBIAN/postinst" << 'EOF'
|
|
56
|
+
#!/bin/bash
|
|
57
|
+
set -e
|
|
58
|
+
|
|
59
|
+
case "$1" in
|
|
60
|
+
configure)
|
|
61
|
+
# Create symlink in /usr/bin if it doesn't exist
|
|
62
|
+
if [ ! -L /usr/bin/remind ] && [ ! -f /usr/bin/remind ]; then
|
|
63
|
+
ln -s /usr/local/bin/remind /usr/bin/remind 2>/dev/null || true
|
|
64
|
+
fi
|
|
65
|
+
echo "Remind installed successfully!"
|
|
66
|
+
echo "Run 'remind --help' to get started"
|
|
67
|
+
;;
|
|
68
|
+
abort-upgrade|abort-remove|abort-deconfigure)
|
|
69
|
+
;;
|
|
70
|
+
*)
|
|
71
|
+
echo "postinst called with unknown argument \`$1'" >&2
|
|
72
|
+
exit 1
|
|
73
|
+
;;
|
|
74
|
+
esac
|
|
75
|
+
|
|
76
|
+
exit 0
|
|
77
|
+
EOF
|
|
78
|
+
|
|
79
|
+
chmod 755 "${BUILD_DIR}/DEBIAN/postinst"
|
|
80
|
+
|
|
81
|
+
# Create DEBIAN/prerm script
|
|
82
|
+
cat > "${BUILD_DIR}/DEBIAN/prerm" << 'EOF'
|
|
83
|
+
#!/bin/bash
|
|
84
|
+
set -e
|
|
85
|
+
|
|
86
|
+
case "$1" in
|
|
87
|
+
remove|deconfigure)
|
|
88
|
+
# Remove symlink if it exists
|
|
89
|
+
[ -L /usr/bin/remind ] && rm -f /usr/bin/remind 2>/dev/null || true
|
|
90
|
+
;;
|
|
91
|
+
upgrade|failed-upgrade)
|
|
92
|
+
;;
|
|
93
|
+
*)
|
|
94
|
+
echo "prerm called with unknown argument \`$1'" >&2
|
|
95
|
+
exit 1
|
|
96
|
+
;;
|
|
97
|
+
esac
|
|
98
|
+
|
|
99
|
+
exit 0
|
|
100
|
+
EOF
|
|
101
|
+
|
|
102
|
+
chmod 755 "${BUILD_DIR}/DEBIAN/prerm"
|
|
103
|
+
|
|
104
|
+
# Create changelog
|
|
105
|
+
cat > "${BUILD_DIR}/usr/share/doc/remind/changelog.gz" << 'EOF'
|
|
106
|
+
remind (0.1.0) unstable; urgency=medium
|
|
107
|
+
* Initial release
|
|
108
|
+
* MVP: CLI reminders with desktop notifications
|
|
109
|
+
* Premium: AI-powered suggestions and smart nudges
|
|
110
|
+
EOF
|
|
111
|
+
|
|
112
|
+
# Build the deb package
|
|
113
|
+
mkdir -p "${OUTPUT_DIR}"
|
|
114
|
+
DEB_FILE="${OUTPUT_DIR}/remind_${VERSION}_${ARCH}.deb"
|
|
115
|
+
|
|
116
|
+
dpkg-deb --build "${BUILD_DIR}" "${DEB_FILE}"
|
|
117
|
+
|
|
118
|
+
if [ -f "${DEB_FILE}" ]; then
|
|
119
|
+
echo "✓ Package created: ${DEB_FILE}"
|
|
120
|
+
ls -lh "${DEB_FILE}"
|
|
121
|
+
else
|
|
122
|
+
echo "✗ Failed to create package"
|
|
123
|
+
exit 1
|
|
124
|
+
fi
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate Homebrew formula with correct checksums from GitHub release."""
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_release_info(repo: str, version: str) -> dict:
|
|
11
|
+
"""Fetch release information from GitHub API."""
|
|
12
|
+
api_url = f"https://api.github.com/repos/{repo}/releases/tags/{version}"
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
result = subprocess.run(
|
|
16
|
+
["curl", "-s", api_url],
|
|
17
|
+
capture_output=True,
|
|
18
|
+
text=True,
|
|
19
|
+
check=True,
|
|
20
|
+
)
|
|
21
|
+
return json.loads(result.stdout)
|
|
22
|
+
except subprocess.CalledProcessError as e:
|
|
23
|
+
print(f"Error fetching release info: {e}")
|
|
24
|
+
sys.exit(1)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_file_sha256(repo: str, version: str, filename: str) -> str:
|
|
28
|
+
"""Get SHA256 checksum from GitHub release."""
|
|
29
|
+
api_url = f"https://api.github.com/repos/{repo}/releases/tags/{version}"
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
result = subprocess.run(
|
|
33
|
+
["curl", "-s", api_url],
|
|
34
|
+
capture_output=True,
|
|
35
|
+
text=True,
|
|
36
|
+
check=True,
|
|
37
|
+
)
|
|
38
|
+
data = json.loads(result.stdout)
|
|
39
|
+
|
|
40
|
+
# Look for SHA256SUMS file in release
|
|
41
|
+
for asset in data.get("assets", []):
|
|
42
|
+
if asset["name"] == "SHA256SUMS":
|
|
43
|
+
sha_url = asset["browser_download_url"]
|
|
44
|
+
sha_result = subprocess.run(
|
|
45
|
+
["curl", "-s", sha_url],
|
|
46
|
+
capture_output=True,
|
|
47
|
+
text=True,
|
|
48
|
+
check=True,
|
|
49
|
+
)
|
|
50
|
+
# Parse SHA256SUMS file
|
|
51
|
+
for line in sha_result.stdout.split("\n"):
|
|
52
|
+
parts = line.strip().split()
|
|
53
|
+
if len(parts) >= 2 and filename in parts[1]:
|
|
54
|
+
return parts[0]
|
|
55
|
+
|
|
56
|
+
print(f"Could not find SHA256 for {filename}")
|
|
57
|
+
sys.exit(1)
|
|
58
|
+
except subprocess.CalledProcessError as e:
|
|
59
|
+
print(f"Error fetching checksums: {e}")
|
|
60
|
+
sys.exit(1)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def generate_formula(
|
|
64
|
+
repo: str, version: str, x86_sha: str, arm_sha: str, linux_sha: str | None = None
|
|
65
|
+
) -> str:
|
|
66
|
+
"""Generate Homebrew formula with proper URLs and checksums."""
|
|
67
|
+
# Clean version (remove 'v' prefix if present)
|
|
68
|
+
clean_version = version.lstrip("v")
|
|
69
|
+
|
|
70
|
+
# Use Linux SHA if provided, otherwise fallback to x86_sha for x86_64 builds
|
|
71
|
+
linux_sha = linux_sha or x86_sha
|
|
72
|
+
|
|
73
|
+
formula = f'''# Homebrew formula for Remind
|
|
74
|
+
# Auto-generated during release. Do not edit manually.
|
|
75
|
+
# Source: build_tools/generate_homebrew_formula.py
|
|
76
|
+
|
|
77
|
+
class RemindCli < Formula
|
|
78
|
+
desc "AI-powered CLI reminder and notification engine"
|
|
79
|
+
homepage "https://github.com/{repo}"
|
|
80
|
+
license "MIT"
|
|
81
|
+
version "{clean_version}"
|
|
82
|
+
|
|
83
|
+
on_macos do
|
|
84
|
+
on_intel do
|
|
85
|
+
url "https://github.com/{repo}/releases/download/{version}/remind-macos-x86_64"
|
|
86
|
+
sha256 "{x86_sha}"
|
|
87
|
+
end
|
|
88
|
+
on_arm do
|
|
89
|
+
url "https://github.com/{repo}/releases/download/{version}/remind-macos-arm64"
|
|
90
|
+
sha256 "{arm_sha}"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
on_linux do
|
|
95
|
+
url "https://github.com/{repo}/releases/download/{version}/remind-linux-x86_64"
|
|
96
|
+
sha256 "{linux_sha}"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def install
|
|
100
|
+
if OS.mac? && Hardware::CPU.intel?
|
|
101
|
+
bin.install "remind-macos-x86_64" => "remind"
|
|
102
|
+
elsif OS.mac? && Hardware::CPU.arm?
|
|
103
|
+
bin.install "remind-macos-arm64" => "remind"
|
|
104
|
+
elsif OS.linux?
|
|
105
|
+
bin.install "remind-linux-x86_64" => "remind"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def post_install
|
|
110
|
+
puts "Remind installed successfully!"
|
|
111
|
+
puts "Run 'remind --help' to get started."
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
test do
|
|
115
|
+
assert_match(/Usage|Commands/, shell_output("{{bin}}/remind --help"))
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
'''
|
|
119
|
+
return formula
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def main():
|
|
123
|
+
"""Main entry point."""
|
|
124
|
+
if len(sys.argv) < 3:
|
|
125
|
+
print("Usage: generate_homebrew_formula.py <repo> <version>")
|
|
126
|
+
print("Example: generate_homebrew_formula.py hamzaplojovic/remind v0.1.0")
|
|
127
|
+
sys.exit(1)
|
|
128
|
+
|
|
129
|
+
repo = sys.argv[1]
|
|
130
|
+
version = sys.argv[2]
|
|
131
|
+
|
|
132
|
+
print(f"Generating Homebrew formula for {repo} {version}...")
|
|
133
|
+
|
|
134
|
+
# Get checksums from GitHub release
|
|
135
|
+
x86_sha = get_file_sha256(repo, version, "remind-macos-x86_64")
|
|
136
|
+
arm_sha = get_file_sha256(repo, version, "remind-macos-arm64")
|
|
137
|
+
linux_sha = get_file_sha256(repo, version, "remind-linux-x86_64")
|
|
138
|
+
|
|
139
|
+
print(f"macOS x86_64 SHA256: {x86_sha}")
|
|
140
|
+
print(f"macOS arm64 SHA256: {arm_sha}")
|
|
141
|
+
print(f"Linux x86_64 SHA256: {linux_sha}")
|
|
142
|
+
|
|
143
|
+
# Generate formula
|
|
144
|
+
formula = generate_formula(repo, version, x86_sha, arm_sha, linux_sha)
|
|
145
|
+
|
|
146
|
+
# Write to file
|
|
147
|
+
output_path = Path("build_tools/homebrew_formula.rb")
|
|
148
|
+
output_path.write_text(formula)
|
|
149
|
+
print(f"✓ Formula written to {output_path}")
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
if __name__ == "__main__":
|
|
153
|
+
main()
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Homebrew formula for Remind
|
|
2
|
+
# Auto-generated during release. Do not edit manually.
|
|
3
|
+
# Source: build_tools/generate_homebrew_formula.py
|
|
4
|
+
|
|
5
|
+
class RemindCli < Formula
|
|
6
|
+
desc "AI-powered CLI reminder and notification engine"
|
|
7
|
+
homepage "https://github.com/hamzaplojovic/remind"
|
|
8
|
+
license "MIT"
|
|
9
|
+
version "0.1.0"
|
|
10
|
+
|
|
11
|
+
on_macos do
|
|
12
|
+
on_intel do
|
|
13
|
+
url "https://github.com/hamzaplojovic/remind/releases/download/v0.1.0/remind-macos-x86_64"
|
|
14
|
+
sha256 "HOMEBREW_BINARY_SHA256_X86_64"
|
|
15
|
+
end
|
|
16
|
+
on_arm do
|
|
17
|
+
url "https://github.com/hamzaplojovic/remind/releases/download/v0.1.0/remind-macos-arm64"
|
|
18
|
+
sha256 "HOMEBREW_BINARY_SHA256_ARM64"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
on_linux do
|
|
23
|
+
url "https://github.com/hamzaplojovic/remind/releases/download/v0.1.0/remind-linux-x86_64"
|
|
24
|
+
sha256 "HOMEBREW_BINARY_SHA256_LINUX_X86_64"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def install
|
|
28
|
+
if OS.mac? && Hardware::CPU.intel?
|
|
29
|
+
bin.install "remind-macos-x86_64" => "remind"
|
|
30
|
+
elsif OS.mac? && Hardware::CPU.arm?
|
|
31
|
+
bin.install "remind-macos-arm64" => "remind"
|
|
32
|
+
elsif OS.linux?
|
|
33
|
+
bin.install "remind-linux-x86_64" => "remind"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def post_install
|
|
38
|
+
puts "Remind installed successfully!"
|
|
39
|
+
puts "Run 'remind --help' to get started."
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
test do
|
|
43
|
+
assert_match(/Usage|Commands/, shell_output("#{bin}/remind --help"))
|
|
44
|
+
end
|
|
45
|
+
end
|