Skip to content

Commit d0e788d

Browse files
committed
feat: initial release of irail-cli
CLI for Belgian railway (NMBS/SNCB) real-time schedules via iRail API. Features: - liveboard: departures/arrivals for any station - connections: route planning between stations - vehicle: train information and stops - composition: train seating and amenities - disturbances: service disruptions - stations: search Belgian railway stations - TUI station picker for ambiguous names - JSON output mode - Shell completions (bash/zsh/fish) - Colored output with delay/platform change indicators
0 parents  commit d0e788d

39 files changed

Lines changed: 4036 additions & 0 deletions

.github/workflows/ci.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Go
16+
uses: actions/setup-go@v5
17+
with:
18+
go-version: '1.23'
19+
20+
- name: Build
21+
run: go build -v ./...
22+
23+
- name: Test
24+
run: go test -race -v ./...
25+
26+
lint:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/checkout@v4
30+
31+
- name: Set up Go
32+
uses: actions/setup-go@v5
33+
with:
34+
go-version: '1.23'
35+
36+
- name: golangci-lint
37+
uses: golangci/golangci-lint-action@v6
38+
with:
39+
version: latest

.github/workflows/release.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Set up Go
20+
uses: actions/setup-go@v5
21+
with:
22+
go-version: '1.23'
23+
24+
- name: Run GoReleaser
25+
uses: goreleaser/goreleaser-action@v6
26+
with:
27+
version: latest
28+
args: release --clean
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}

.gitignore

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Binaries
2+
/bin/
3+
*.exe
4+
*.exe~
5+
*.dll
6+
*.so
7+
*.dylib
8+
9+
# Test binary
10+
*.test
11+
12+
# Output of go coverage
13+
*.out
14+
15+
# Go workspace
16+
go.work
17+
go.work.sum
18+
19+
# IDE
20+
.idea/
21+
.vscode/
22+
*.swp
23+
*.swo
24+
25+
# Build
26+
/dist/
27+
/tmp/
28+
29+
# OS
30+
.DS_Store
31+
Thumbs.db

.golangci.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
version: "2"
2+
3+
run:
4+
timeout: 5m
5+
6+
linters:
7+
default: standard
8+
enable:
9+
- copyloopvar
10+
- errname
11+
- errorlint
12+
- gochecknoinits
13+
- goconst
14+
- gocritic
15+
- gosec
16+
- misspell
17+
- nilerr
18+
- noctx
19+
- unconvert
20+
- unparam
21+
- whitespace
22+
disable:
23+
- errcheck # Too noisy for CLI output
24+
25+
formatters:
26+
enable:
27+
- gofmt
28+
- goimports
29+
settings:
30+
goimports:
31+
local-prefixes: github.com/dedene/irail-cli
32+
33+
linters-settings:
34+
goconst:
35+
min-len: 3
36+
min-occurrences: 3
37+
gocritic:
38+
enabled-tags:
39+
- diagnostic
40+
- performance
41+
disabled-checks:
42+
- assignOp
43+
44+
issues:
45+
exclude-dirs:
46+
- vendor
47+
max-issues-per-linter: 0
48+
max-same-issues: 0

.goreleaser.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
version: 2
2+
3+
before:
4+
hooks:
5+
- go mod tidy
6+
7+
builds:
8+
- main: ./cmd/irail
9+
binary: irail
10+
env:
11+
- CGO_ENABLED=0
12+
goos:
13+
- linux
14+
- darwin
15+
- windows
16+
goarch:
17+
- amd64
18+
- arm64
19+
ldflags:
20+
- -s -w
21+
- -X github.com/dedene/irail-cli/internal/cmd.version={{.Version}}
22+
- -X github.com/dedene/irail-cli/internal/cmd.commit={{.Commit}}
23+
- -X github.com/dedene/irail-cli/internal/cmd.date={{.Date}}
24+
25+
archives:
26+
- format: tar.gz
27+
name_template: >-
28+
{{ .ProjectName }}_
29+
{{- title .Os }}_
30+
{{- if eq .Arch "amd64" }}x86_64
31+
{{- else if eq .Arch "386" }}i386
32+
{{- else }}{{ .Arch }}{{ end }}
33+
format_overrides:
34+
- goos: windows
35+
format: zip
36+
37+
checksum:
38+
name_template: 'checksums.txt'
39+
40+
snapshot:
41+
version_template: "{{ incpatch .Version }}-next"
42+
43+
changelog:
44+
sort: asc
45+
filters:
46+
exclude:
47+
- '^docs:'
48+
- '^test:'
49+
- '^chore:'
50+
51+
brews:
52+
- name: irail
53+
repository:
54+
owner: dedene
55+
name: homebrew-tap
56+
folder: Formula
57+
homepage: https://github.com/dedene/irail-cli
58+
description: CLI for Belgian railway (NMBS/SNCB) schedules
59+
license: MIT
60+
install: |
61+
bin.install "irail"
62+
test: |
63+
system "#{bin}/irail", "version"

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Peter Dedene
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.PHONY: build test lint fmt ci install clean
2+
3+
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
4+
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
5+
DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
6+
LDFLAGS := -ldflags "-s -w -X github.com/dedene/irail-cli/internal/cmd.version=$(VERSION) -X github.com/dedene/irail-cli/internal/cmd.commit=$(COMMIT) -X github.com/dedene/irail-cli/internal/cmd.date=$(DATE)"
7+
8+
build:
9+
@mkdir -p bin
10+
go build $(LDFLAGS) -o bin/irail ./cmd/irail
11+
12+
test:
13+
go test -race -v ./...
14+
15+
lint:
16+
golangci-lint run
17+
18+
fmt:
19+
go fmt ./...
20+
goimports -w .
21+
22+
ci: fmt lint test build
23+
24+
install:
25+
go install $(LDFLAGS) ./cmd/irail
26+
27+
clean:
28+
rm -rf bin/
29+
rm -rf dist/

README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# irail-cli
2+
3+
CLI for Belgian railway (NMBS/SNCB) real-time schedules via [iRail API](https://api.irail.be/).
4+
5+
## Installation
6+
7+
### Homebrew (macOS/Linux)
8+
9+
```bash
10+
brew install dedene/tap/irail
11+
```
12+
13+
### Go Install
14+
15+
```bash
16+
go install github.com/dedene/irail-cli/cmd/irail@latest
17+
```
18+
19+
### Binary
20+
21+
Download from [Releases](https://github.com/dedene/irail-cli/releases).
22+
23+
## Usage
24+
25+
### Liveboard
26+
27+
Show departures from a station:
28+
29+
```bash
30+
irail liveboard Brugge
31+
irail liveboard "Brussel-Centraal"
32+
irail liveboard Brugge --arrivals
33+
irail liveboard Brugge --time 09:00 --date 2025-02-15
34+
```
35+
36+
### Connections
37+
38+
Find routes between stations:
39+
40+
```bash
41+
irail connections Brugge Leuven
42+
irail connections Brugge Leuven --time 09:00
43+
irail connections Brugge Leuven --arrive-by # time is arrival time
44+
irail connections Brugge Leuven --results 10
45+
```
46+
47+
### Stations
48+
49+
List or search stations:
50+
51+
```bash
52+
irail stations
53+
irail stations --search bruss
54+
```
55+
56+
### Vehicle
57+
58+
Show train information:
59+
60+
```bash
61+
irail vehicle IC1832
62+
irail vehicle IC1832 --stops # show all stops
63+
```
64+
65+
### Composition
66+
67+
Show train composition (seats, amenities):
68+
69+
```bash
70+
irail composition S51507
71+
```
72+
73+
### Disturbances
74+
75+
Show service disruptions:
76+
77+
```bash
78+
irail disturbances
79+
irail disturbances --type planned # only planned works
80+
irail disturbances --type disturbance # only disruptions
81+
```
82+
83+
## Options
84+
85+
| Flag | Description |
86+
|------|-------------|
87+
| `--json` | Output JSON |
88+
| `--lang` | Language: nl, fr, en, de |
89+
| `--no-color` | Disable colors |
90+
91+
### Environment Variables
92+
93+
- `IRAIL_LANG` - Default language
94+
- `IRAIL_JSON` - Default to JSON output
95+
- `NO_COLOR` - Disable colors
96+
97+
## Features
98+
99+
- Real-time departures and arrivals
100+
- Connection planning with transfers
101+
- Delay highlighting (red for delays)
102+
- Platform change warnings (yellow ⚠️)
103+
- Occupancy indicators
104+
- Clickable train links (in supported terminals)
105+
- Shell completions (bash, zsh, fish)
106+
107+
## Shell Completions
108+
109+
```bash
110+
# Bash
111+
irail completion bash > /etc/bash_completion.d/irail
112+
113+
# Zsh
114+
irail completion zsh > "${fpath[1]}/_irail"
115+
116+
# Fish
117+
irail completion fish > ~/.config/fish/completions/irail.fish
118+
```
119+
120+
## License
121+
122+
MIT

0 commit comments

Comments
 (0)