diff --git a/.agents/skills/xpack-development/SKILL.md b/.agents/skills/xpack-development/SKILL.md new file mode 100644 index 0000000..8a7da4c --- /dev/null +++ b/.agents/skills/xpack-development/SKILL.md @@ -0,0 +1,126 @@ +--- +name: xpack-development +description: Development rules for xpack Linux package builder +version: 1.0.0 +tags: [golang, packaging, deb, rpm, linux] +author: xpack Team +--- + +# xpack Development Skill + +## Project Identity + +**xpack** - Universal Linux Package Builder +- Go ≥1.18 +- CLI tool for converting binaries to .deb, .rpm, .tar.gz +- Reproducible, standards-compliant packages + +## Mandatory Workflows + +### After EVERY Code Change +```bash +go build -o xpack src/Core/main.go +go test ./... +go fmt ./... +go vet ./... +``` + +### For ANY Package Format Change +1. Validate with lintian (deb) or rpmlint (rpm) +2. Test installation on target system +3. Verify reproducible builds +4. Update documentation + +## Definition of "Done" + +- ✅ `go build` passes +- ✅ `go test ./...` passes +- ✅ Packages validate (lintian/rpmlint) +- ✅ Reproducible builds verified +- ✅ Documentation updated +- ✅ Package standards followed + +## Architecture + +``` +src/ +├── Core/main.go # CLI entry +├── base/ # Utilities +└── packager/ # Package builders + +Scripts/ +├── BinBuilder.sh # Multi-platform +└── installer.sh # One-line install + +dist/ # Output packages +``` + +## Go Standards + +### Error Handling +```go +// ✅ REQUIRED +if err != nil { + return fmt.Errorf("failed to create deb for '%s': %w", name, err) +} +``` + +### Type Safety +```go +// ✅ Use structs +type PackageMetadata struct { + Name string + Version string + Architecture string + Maintainer string + Description string +} +``` + +## Key Patterns + +### Reproducible Builds +```go +// ✅ Sort for determinism +sort.Strings(files) +for _, file := range files { + addToPackage(file) +} +``` + +### Package Validation +```go +// ✅ Validate metadata +if !regexp.MustCompile(`^[a-z0-9][a-z0-9+.-]+$`).MatchString(name) { + return fmt.Errorf("invalid package name") +} +``` + +## Package Standards + +- **Debian**: Control file, maintainer scripts, /usr/bin layout +- **RPM**: Spec file, scriptlets, /usr/bin layout +- **Tarball**: Unix layout, install script, checksums + +## Testing + +- Unit: Metadata validation, file operations +- Integration: Full package creation +- Validation: lintian (deb), rpmlint (rpm) +- Installation: Test on Debian, RPM-based systems + +## Anti-Patterns (FORBIDDEN) + +❌ Non-deterministic builds +❌ Invalid metadata +❌ Missing validation +❌ Breaking standards +❌ Generic errors + +## Success Criteria + +- ✅ Builds successfully +- ✅ Tests pass +- ✅ Packages validate +- ✅ Reproducible +- ✅ Standards compliant diff --git a/.codex/config.toml b/.codex/config.toml new file mode 100644 index 0000000..b3b48be --- /dev/null +++ b/.codex/config.toml @@ -0,0 +1,31 @@ +# OpenAI Codex CLI Configuration for xpack + +[project] +name = "xpack" +description = "Universal Linux Package Builder" +language = "Go" + +[model] +default = "gpt-4-turbo" +temperature = 0.2 + +[build] +command = "go build -o xpack src/Core/main.go" +required = true + +[test] +command = "go test ./..." +required = true + +[rules] +reproducible_builds = true +package_standards = true +validate_packages = true + +[completion] +required = [ + "go build passes", + "go test passes", + "Packages validate", + "Reproducible builds" +] diff --git a/.cursor/rules/xpack-core.mdc b/.cursor/rules/xpack-core.mdc new file mode 100644 index 0000000..b5ec1da --- /dev/null +++ b/.cursor/rules/xpack-core.mdc @@ -0,0 +1,82 @@ +# xpack Core Rules for Cursor IDE + +## Project Context + +**xpack** - Universal Linux Package Builder (Go CLI tool) + +## Mandatory Workflows + +```bash +go build -o xpack src/Core/main.go +go test ./... +go fmt ./... +go vet ./... +``` + +## Definition of "Done" + +- ✅ `go build` passes +- ✅ Tests pass +- ✅ Packages validate (lintian/rpmlint) +- ✅ Reproducible builds +- ✅ Docs updated + +## Architecture + +``` +src/ (Core, base, packager) → Build → Validate → dist/ +``` + +## Go Standards + +### Errors +```go +// ✅ Descriptive +if err != nil { + return fmt.Errorf("failed to create package '%s': %w", name, err) +} +``` + +### Types +```go +// ✅ Use structs +type PackageMetadata struct { + Name string + Version string +} +``` + +## Key Patterns + +### Reproducible +```go +// ✅ Sort files +sort.Strings(files) +``` + +### Validate +```go +// ✅ Check names +if !regexp.MustCompile(`^[a-z0-9][a-z0-9+.-]+$`).MatchString(name) { + return fmt.Errorf("invalid name") +} +``` + +## Package Standards + +- Debian: Control file, /usr/bin +- RPM: Spec file, /usr/bin +- Tarball: Unix layout + +## Anti-Patterns + +❌ Non-deterministic builds +❌ Invalid metadata +❌ Missing validation + +## Success + +- ✅ Builds +- ✅ Tests pass +- ✅ Validates +- ✅ Reproducible diff --git a/.gemini/settings.json b/.gemini/settings.json new file mode 100644 index 0000000..0197dfd --- /dev/null +++ b/.gemini/settings.json @@ -0,0 +1,15 @@ +{ + "version": "1.0", + "project": { + "name": "xpack", + "type": "CLI Tool", + "language": "Go" + }, + "model": { + "name": "gemini-3-pro", + "temperature": 0.2 + }, + "context": { + "fileName": ["GEMINI.md"] + } +} diff --git a/.github/copilot/instructions.md b/.github/copilot/instructions.md new file mode 100644 index 0000000..24a56f2 --- /dev/null +++ b/.github/copilot/instructions.md @@ -0,0 +1,78 @@ +# GitHub Copilot Instructions for xpack + +## Project Overview + +**xpack** - Universal Linux Package Builder +- **Language**: Go ≥1.18 +- **Type**: CLI for binary-to-package conversion +- **Formats**: .deb, .rpm, .tar.gz + +## Core Rules + +### 1. Reproducible Builds +Same input must produce identical output + +### 2. Package Standards +- Debian: Follow Debian Policy +- RPM: Follow RPM Guidelines + +### 3. Validation +- Use `lintian` for .deb +- Use `rpmlint` for .rpm + +## Commands + +```bash +go build -o xpack src/Core/main.go +go test ./... +./bin/xpack -i ./bin -arch amd64 -v 1.1.1 +``` + +## Go Standards + +### Error Handling +```go +// ✅ GOOD +if err != nil { + return fmt.Errorf("failed to create deb '%s': %w", name, err) +} +``` + +### Type Safety +```go +// ✅ Use structs +type PackageMetadata struct { + Name string + Version string +} +``` + +## Key Patterns + +### Deterministic Builds +```go +// ✅ Sort files +sort.Strings(files) +``` + +### Validation +```go +// ✅ Validate names +if !regexp.MustCompile(`^[a-z0-9][a-z0-9+.-]+$`).MatchString(name) { + return fmt.Errorf("invalid name") +} +``` + +## Testing + +- Unit: Metadata, file ops +- Integration: Package creation +- Validation: lintian, rpmlint + +## Success Criteria + +- ✅ `go build` passes +- ✅ Tests pass +- ✅ Packages validate +- ✅ Reproducible +- ✅ Docs updated diff --git a/.github/copilot/settings.json b/.github/copilot/settings.json new file mode 100644 index 0000000..9e9d54f --- /dev/null +++ b/.github/copilot/settings.json @@ -0,0 +1,29 @@ +{ + "version": "1.0", + "project": { + "name": "xpack", + "type": "CLI Tool", + "language": "Go" + }, + "build": { + "command": "go build -o xpack src/Core/main.go", + "required": true + }, + "test": { + "command": "go test ./...", + "required": true + }, + "instructions": [ + "Reproducible builds: same input = same output", + "Follow package standards (Debian Policy, RPM Guidelines)", + "Validate with lintian (deb) and rpmlint (rpm)", + "Sort files for deterministic builds", + "Validate package metadata", + "Clear error messages with context" + ], + "antiPatterns": [ + "Non-deterministic builds", + "Invalid metadata", + "Missing validation" + ] +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..1d096e4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,167 @@ +# AGENTS.md + +OpenAI Codex CLI Instructions for xpack + +## Project Overview + +**xpack** - Universal Linux Package Builder + +- **Language**: Go ≥1.18 +- **Type**: CLI for binary-to-package conversion +- **Formats**: .deb, .rpm, .tar.gz +- **Purpose**: Automate Linux package creation + +## Build Commands + +```bash +# Development +go build -o xpack src/Core/main.go +./bin/xpack -i ./bin -arch amd64 -v 1.1.1 + +# Test +go test ./... +go fmt ./... +go vet ./... + +# Distribution +./Scripts/BinBuilder.sh # Multi-platform build +``` + +## Core Principles + +### 1. Reproducible Builds +- Same input must produce identical output +- No timestamps (use SOURCE_DATE_EPOCH) +- Deterministic file ordering +- Consistent compression + +### 2. Package Standards +- **Debian**: Follow Debian Policy Manual +- **RPM**: Follow RPM Packaging Guidelines +- **Tarball**: Standard Unix layout + +### 3. Validation +- Use `lintian` for .deb packages +- Use `rpmlint` for .rpm packages +- Test installation on target systems + +## Architecture + +### Structure +``` +src/ +├── Core/main.go # CLI entry point +├── base/ # Utilities +└── packager/ # Package builders + +Scripts/ +├── BinBuilder.sh # Multi-platform builder +└── installer.sh # One-line installer + +dist/ # Output packages +``` + +### Flow +``` +Binary → CLI Args → Metadata → Package Structure → Build → Validate → Output +``` + +## Go Standards + +### Error Handling +```go +// ✅ GOOD +if err != nil { + return fmt.Errorf("failed to create package '%s': %w", name, err) +} + +// ❌ BAD +if err != nil { + return err +} +``` + +### Structs for Options +```go +// ✅ GOOD +type PackageMetadata struct { + Name string + Version string + Architecture string + Maintainer string + Description string +} + +func BuildDeb(meta PackageMetadata, binPath string) error + +// ❌ BAD +func BuildDeb(name, version, arch, maintainer, desc, binPath string) error +``` + +## Key Patterns + +### Deterministic Sorting +```go +// ✅ Sort for reproducibility +sort.Strings(files) +for _, file := range files { + addToPackage(file) +} +``` + +### Metadata Validation +```go +// ✅ Validate package names +if !regexp.MustCompile(`^[a-z0-9][a-z0-9+.-]+$`).MatchString(name) { + return fmt.Errorf("invalid package name: %s", name) +} +``` + +## Documentation + +Update when features change: +- README.md - Usage, features +- INSTALLATION.md - Install methods +- LEARN.md - Advanced usage, guides +- CHANGELOG.md - Version changes + +## Testing + +- Unit tests: Metadata, file operations +- Integration tests: Full package creation +- Validation: lintian, rpmlint +- Installation: Test on Debian, RHEL/Fedora + +## Package Formats + +### Debian (.deb) +- Control file with metadata +- Maintainer scripts (preinst, postinst, prerm, postrm) +- File layout: /usr/bin, /usr/share/doc + +### RPM (.rpm) +- Spec file with metadata +- Scriptlets (%pre, %post, %preun, %postun) +- File layout: /usr/bin, /usr/share/doc + +### Tarball (.tar.gz) +- Standard Unix layout +- Install script +- Checksum file + +## Anti-Patterns + +❌ Non-deterministic builds +❌ Invalid package metadata +❌ Missing validation +❌ Breaking package standards +❌ Generic error messages + +## Success Criteria + +- ✅ `go build` passes +- ✅ `go test ./...` passes +- ✅ Packages validate (lintian, rpmlint) +- ✅ Reproducible builds +- ✅ Documentation updated +- ✅ Standards compliant diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2137e05 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,289 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +**xpack** - Universal Linux Package Builder + +- **Language**: Go ≥1.18 +- **Type**: CLI tool for converting binaries to Linux packages (.deb, .rpm, tar.gz) +- **Platform**: Linux (target), cross-platform build +- **Purpose**: Automate creation of native Linux packages from standalone binaries + +## Commands + +```bash +# Build +go build -o xpack src/Core/main.go +./Scripts/BinBuilder.sh # Multi-platform build + +# Run +./bin/xpack -i ./bin -arch amd64 -v 1.1.1 +./bin/xpack build --input ./myapp.bin --name myapp --version 1.0.0 --formats deb,rpm + +# Test +go test ./... +go fmt ./... +go vet ./... +``` + +## Core Rules (NON-NEGOTIABLE) + +1. **ALWAYS test**: Test package creation on Debian and RPM-based systems +2. **ALWAYS build**: Run `go build` after code changes +3. **Reproducible builds**: Same input must produce identical packages +4. **Package standards**: Follow Debian Policy and RPM standards +5. **Error handling**: Clear, actionable error messages +6. **Update docs**: README.md, INSTALLATION.md, LEARN.md when features change + +## Critical Constraints + +### Package Format Compliance +- **Debian packages (.deb)**: Follow Debian Policy Manual +- **RPM packages (.rpm)**: Follow RPM Packaging Guidelines +- **Tarball (.tar.gz)**: Standard Unix layout +- **Metadata**: Maintainer, description, dependencies, conflicts + +### Deterministic Builds +- **Same input = same output** (reproducible builds) +- **No timestamps** in package metadata (or use SOURCE_DATE_EPOCH) +- **Consistent file ordering** +- **Deterministic compression** + +## Architecture Overview + +See `LEARN.md` for complete details. + +### Structure +``` +src/ +├── Core/ # main.go - CLI entry point +├── base/ # Utilities (banner, helpers) +└── packager/ # Package generation logic + ├── deb builder + ├── rpm builder + └── tar.gz builder + +Scripts/ +├── BinBuilder.sh # Multi-platform binary builder +└── installer.sh # One-line installer script + +dist/ # Output directory for generated packages +``` + +### Package Creation Flow +``` +Input Binary (.bin) + ↓ +Parse CLI Arguments (name, version, arch, formats) + ↓ +Generate Package Metadata (control files, spec files) + ↓ +Create Package Structure (directories, permissions) + ↓ +Add Scripts (pre/post install/remove) + ↓ +Build Package (.deb, .rpm, .tar.gz) + ↓ +Output to dist/ +``` + +## Go Standards + +### Error Handling +```go +// ✅ GOOD - Descriptive with context +if err != nil { + return fmt.Errorf("failed to create deb package for '%s': %w", pkgName, err) +} + +// ❌ BAD - Generic +if err != nil { + return err +} +``` + +### Package Structure +```go +// ✅ GOOD - Clear struct for package metadata +type PackageMetadata struct { + Name string + Version string + Architecture string + Maintainer string + Description string + Depends []string + Conflicts []string +} + +func BuildDeb(meta PackageMetadata, binPath string) error { } + +// ❌ BAD - Too many parameters +func BuildDeb(name, version, arch, maintainer, desc string, binPath string) error { } +``` + +### File Operations +```go +// ✅ GOOD - Use filepath for cross-platform paths +import "path/filepath" + +debPath := filepath.Join(outputDir, fmt.Sprintf("%s_%s_%s.deb", name, version, arch)) + +// ❌ BAD - Hardcoded separators +debPath := outputDir + "/" + name + "_" + version + ".deb" +``` + +## Key Patterns + +### Deterministic File Ordering +```go +// ✅ GOOD - Sort files for reproducibility +sort.Strings(files) +for _, file := range files { + addToArchive(file) +} + +// ❌ BAD - Non-deterministic order +for file := range fileMap { + addToArchive(file) +} +``` + +### Metadata Validation +```go +// ✅ Validate package metadata +func ValidateMetadata(meta PackageMetadata) error { + if meta.Name == "" { + return fmt.Errorf("package name is required") + } + if !regexp.MustCompile(`^[a-z0-9][a-z0-9+.-]+$`).MatchString(meta.Name) { + return fmt.Errorf("invalid package name: %s", meta.Name) + } + if meta.Version == "" { + return fmt.Errorf("package version is required") + } + return nil +} +``` + +### Package Building +```go +// ✅ GOOD - Build multiple formats +func BuildPackages(meta PackageMetadata, binPath string, formats []string) error { + for _, format := range formats { + switch format { + case "deb": + if err := BuildDeb(meta, binPath); err != nil { + return fmt.Errorf("deb build failed: %w", err) + } + case "rpm": + if err := BuildRPM(meta, binPath); err != nil { + return fmt.Errorf("rpm build failed: %w", err) + } + case "tar": + if err := BuildTarball(meta, binPath); err != nil { + return fmt.Errorf("tarball build failed: %w", err) + } + default: + return fmt.Errorf("unsupported format: %s", format) + } + } + return nil +} +``` + +## Documentation Requirements + +**Update when features change**: +1. **README.md** - Usage examples, quick start +2. **INSTALLATION.md** - Installation methods, requirements +3. **LEARN.md** - Package creation guide, advanced usage +4. **CONTRIBUTING.md** - Development guidelines +5. **Code comments** - All exported functions, complex logic + +## Security + +1. **Input Validation**: Validate all CLI arguments (names, versions, paths) +2. **Path Traversal**: Sanitize file paths to prevent directory traversal +3. **Script Injection**: Validate maintainer scripts (pre/post install) +4. **File Permissions**: Set proper permissions (755 for binaries, 644 for docs) +5. **Signature Support**: Support GPG signing for packages + +## Testing + +- **Unit tests**: Metadata validation, file operations +- **Integration tests**: Full package creation (.deb, .rpm, .tar.gz) +- **Package validation**: Use `lintian` (Debian), `rpmlint` (RPM) +- **Installation tests**: Install packages on target systems +- **Reproducibility**: Verify identical builds from same input + +## Package Standards + +### Debian (.deb) +- Control file format +- Maintainer scripts (preinst, postinst, prerm, postrm) +- File layout (/usr/bin, /usr/share/doc, /etc) +- Dependencies, conflicts, provides +- Architecture (amd64, arm64, all) + +### RPM (.rpm) +- Spec file format +- Scriptlets (%pre, %post, %preun, %postun) +- File layout (/usr/bin, /usr/share/doc, /etc) +- Requires, conflicts, provides +- Architecture (x86_64, aarch64, noarch) + +### Tarball (.tar.gz) +- Standard Unix layout +- Install script +- Manifest file +- Checksum file (SHA256) + +## Anti-Patterns (FORBIDDEN) + +❌ Non-deterministic builds (timestamps, random order) +❌ Invalid package metadata (missing required fields) +❌ Hardcoded paths without cross-platform support +❌ Missing input validation +❌ Breaking package standards (Debian Policy, RPM guidelines) +❌ Skipping package validation tools +❌ Missing error handling +❌ Generic error messages + +## Workflow Guidelines + +### When Adding Package Format Support +1. Read official packaging guidelines (Debian Policy, RPM docs) +2. Create builder in `src/packager/` +3. Implement metadata generation +4. Add file layout logic +5. Support maintainer scripts +6. Add tests with validation tools +7. Update documentation (README, LEARN) + +### When Fixing Bugs +1. Write failing test that reproduces bug +2. Fix the bug +3. Verify test passes +4. Test on target systems (Debian, RPM-based) +5. Validate with lintian/rpmlint +6. Document in CHANGELOG.md + +### When Refactoring +1. Ensure backward compatibility +2. Run all tests before and after +3. Validate packages on target systems +4. Update documentation if behavior changes + +## Success Criteria + +Every task must meet ALL: +- ✅ Builds successfully (`go build`) +- ✅ Tests pass (`go test ./...`) +- ✅ Lints pass (`go vet ./...`, `go fmt ./...`) +- ✅ Packages validate (`lintian`, `rpmlint`) +- ✅ Reproducible builds (same input = same output) +- ✅ Documentation updated +- ✅ Package standards followed +- ✅ Clear error messages diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..a5e1498 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,124 @@ +# GEMINI.md + +This file provides guidance to Gemini Code Assist when working with code in this repository. + +## Project Overview + +**xpack** - Universal Linux Package Builder + +- **Language**: Go ≥1.18 +- **Type**: CLI for converting binaries to .deb, .rpm, .tar.gz packages +- **Platform**: Linux (target) +- **Purpose**: Automate Linux package creation + +## Commands + +```bash +# Build & Run +go build -o xpack src/Core/main.go +./bin/xpack -i ./bin -arch amd64 -v 1.1.1 +./Scripts/BinBuilder.sh + +# Test +go test ./... +go fmt ./... +go vet ./... +``` + +## Core Rules (NON-NEGOTIABLE) + +1. **Reproducible builds**: Same input = same output +2. **Package standards**: Follow Debian Policy, RPM guidelines +3. **ALWAYS test**: Validate with lintian (deb), rpmlint (rpm) +4. **ALWAYS build**: Run `go build` after changes +5. **Update docs**: README, INSTALLATION, LEARN + +## Architecture + +### Structure +``` +src/ +├── Core/main.go # CLI entry +├── base/ # Utilities +└── packager/ # Package builders (deb, rpm, tar.gz) +``` + +### Flow +``` +Binary Input → Parse Args → Generate Metadata → Build Package → Output to dist/ +``` + +## Go Standards + +### Error Handling +```go +// ✅ GOOD +if err != nil { + return fmt.Errorf("failed to create deb for '%s': %w", name, err) +} + +// ❌ BAD +if err != nil { + return err +} +``` + +### Type Safety +```go +// ✅ Use structs +type PackageMetadata struct { + Name string + Version string + Arch string +} + +// ❌ Too many params +func BuildDeb(name, version, arch string) error +``` + +## Key Patterns + +### Deterministic Builds +```go +// ✅ Sort for reproducibility +sort.Strings(files) + +// ❌ Non-deterministic +for file := range fileMap { } +``` + +### Validation +```go +// ✅ Validate metadata +if !regexp.MustCompile(`^[a-z0-9][a-z0-9+.-]+$`).MatchString(name) { + return fmt.Errorf("invalid package name") +} +``` + +## Documentation + +Update when features change: +- README.md - Usage, quick start +- INSTALLATION.md - Install methods +- LEARN.md - Package creation guide + +## Testing + +- Unit tests for metadata, file ops +- Integration tests for package creation +- Validate with lintian, rpmlint +- Test on Debian, RPM-based systems + +## Package Standards + +- **Debian**: Control file, maintainer scripts, /usr/bin layout +- **RPM**: Spec file, scriptlets, /usr/bin layout +- **Tarball**: Standard Unix layout, install script + +## Definition of "Done" + +- ✅ `go build` passes +- ✅ `go test ./...` passes +- ✅ Packages validate (lintian, rpmlint) +- ✅ Reproducible builds +- ✅ Documentation updated diff --git a/Scripts/installer.sh b/Scripts/installer.sh index f7ec960..d5793b2 100755 --- a/Scripts/installer.sh +++ b/Scripts/installer.sh @@ -7,7 +7,7 @@ ARCH=$(dpkg --print-architecture) echo "Detected architecture: $ARCH" -VERSION="2.2.8-stable" +VERSION="2.2.9-stable" if [[ "$ARCH" == "amd64" ]]; then PKG="xpack_${VERSION}_amd64.deb" diff --git a/VERSION b/VERSION index 24409f5..e01087e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.8-stable +2.2.9-stable diff --git a/src/Core/main.go b/src/Core/main.go index 0ddbc03..efe77b9 100644 --- a/src/Core/main.go +++ b/src/Core/main.go @@ -15,7 +15,7 @@ import ( ) // var VERSION is updated by Scripts/versionController.sh -var VERSION = "2.2.8-stable" +var VERSION = "2.2.9-stable" // readLineRaw reads interactive input from terminal in raw mode, supporting Tab completion func readLineRaw(promptText, defaultVal string) (string, error) { diff --git a/src/base/banner.go b/src/base/banner.go index 43f83f0..5c8bdb8 100644 --- a/src/base/banner.go +++ b/src/base/banner.go @@ -5,7 +5,7 @@ import ( ) // const Version is kept so external scripts can update it via sed -const Version = "2.2.8-stable" +const Version = "2.2.9-stable" // PrintBanner prints a simple welcome banner. Version may be empty. func PrintBanner(version string) {