Local Development Installation¶
For development or running from source, you can build and run Night Routine Scheduler locally.
Prerequisites¶
- Go 1.25 or later - Download Go
- Git - Download Git
- Google Calendar API Credentials - Get credentials
Installation Steps¶
1. Clone the Repository¶
2. Create Configuration¶
Copy the example configuration:
# Create a configuration directory if it doesn't exist
mkdir -p configs
# Copy or create the configuration file
cat > configs/my-routine.toml << 'EOF'
[app]
port = 8080
app_url = "http://localhost:8080"
public_url = "http://localhost:8080"
[parents]
parent_a = "Parent1"
parent_b = "Parent2"
[availability]
parent_a_unavailable = ["Wednesday"]
parent_b_unavailable = ["Monday"]
[schedule]
update_frequency = "weekly"
look_ahead_days = 30
past_event_threshold_days = 5
[service]
state_file = "data/state.db"
log_level = "info"
EOF
3. Set Environment Variables¶
Create a .env file or export the variables directly:
export GOOGLE_OAUTH_CLIENT_ID=your-client-id
export GOOGLE_OAUTH_CLIENT_SECRET=your-client-secret
export CONFIG_FILE=configs/my-routine.toml
export ENV=development
Or create a .env file:
cat > .env << 'EOF'
GOOGLE_OAUTH_CLIENT_ID=your-client-id
GOOGLE_OAUTH_CLIENT_SECRET=your-client-secret
CONFIG_FILE=configs/my-routine.toml
ENV=development
EOF
Then source it:
4. Download Dependencies¶
5. Build the Application¶
6. Run the Application¶
The application will start and be available at http://localhost:8080 (or your configured port).
Development Workflow¶
Using Air for Live Reload¶
For a better development experience, use Air for automatic reloading:
-
Install Air:
-
Create
.air.tomlconfiguration:root = "." testdata_dir = "testdata" tmp_dir = "tmp" [build] args_bin = [] bin = "./tmp/main" cmd = "go build -o ./tmp/main ./cmd/night-routine" delay = 1000 exclude_dir = ["assets", "tmp", "vendor", "testdata", "data", "docs", "docs-site"] exclude_file = [] exclude_regex = ["_test.go"] exclude_unchanged = false follow_symlink = false full_bin = "" include_dir = [] include_ext = ["go", "tpl", "tmpl", "html"] include_file = [] kill_delay = "0s" log = "build-errors.log" poll = false poll_interval = 0 rerun = false rerun_delay = 500 send_interrupt = false stop_on_error = false [color] app = "" build = "yellow" main = "magenta" runner = "green" watcher = "cyan" [log] main_only = false time = false [misc] clean_on_exit = false [screen] clear_on_rebuild = false keep_scroll = true -
Run with Air:
Now your application will automatically rebuild and restart when you make changes to the code.
Running Tests¶
Run all tests:
Run tests with coverage:
Generate coverage report:
Run specific package tests:
Linting¶
The project uses golangci-lint for code linting:
-
Install golangci-lint:
-
Run the linter:
Code Formatting¶
Format your code before committing:
Directory Structure¶
After setup, your project structure will look like:
night-routine/
├── cmd/
│ └── night-routine/ # Main application entry point
├── internal/ # Internal packages
│ ├── calendar/ # Google Calendar integration
│ ├── config/ # Configuration management
│ ├── database/ # Database operations
│ ├── fairness/ # Fairness algorithm
│ ├── scheduler/ # Scheduling logic
│ └── web/ # Web interface
├── configs/ # Configuration files
│ └── my-routine.toml
├── data/ # Runtime data (created automatically)
│ └── state.db
├── docs/ # Additional documentation
├── .env # Environment variables (gitignored)
├── go.mod # Go module definition
├── go.sum # Go module checksums
└── README.md
Debugging¶
Using Delve Debugger¶
Install and use Delve for debugging:
# Install Delve
go install github.com/go-delve/delve/cmd/dlv@latest
# Run with debugger
dlv debug ./cmd/night-routine
# Or attach to running process
dlv attach <pid>
Enabling Debug Logging¶
Update your configuration to enable debug logging:
Common Issues¶
Port Already in Use¶
If port 8080 is already in use:
-
Change the port in your
routine.toml: -
Or set the
PORTenvironment variable:
OAuth Callback Issues¶
Make sure your Google OAuth2 redirect URI matches your local URL:
- In development:
http://localhost:8080/oauth/callback - Update in Google Cloud Console
Database Locked Errors¶
If you encounter database locked errors:
- Ensure only one instance is running
- Check file permissions on the
datadirectory - The database uses WAL mode which should prevent most locking issues
Building for Production¶
Build a production-ready binary:
# Build with optimizations and version information
VERSION=$(git describe --tags --always)
COMMIT=$(git rev-parse --short HEAD)
DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
CGO_ENABLED=0 go build \
-ldflags="-s -w -X 'main.version=${VERSION}' -X 'main.commit=${COMMIT}' -X 'main.date=${DATE}'" \
-o night-routine \
./cmd/night-routine
The resulting binary will be statically linked and can be deployed anywhere.