From 76ca3dab733395a5d0464a6882c3702374d00faf Mon Sep 17 00:00:00 2001 From: Alexander Saal Date: Sun, 3 May 2026 09:16:25 +0200 Subject: [PATCH] chore: bootstrap Go module, package skeleton, and CI Closes #1. - go.mod (module github.com/chmmou/kasapi-cli, Go 1.23) - cmd/kasapi-cli with build-stamped --version - internal/ skeleton mirroring docs/go/ARCHITECTURE.md (per-resource domain packages + soap/transport/auth/api/config/cli/version adapters) - .golangci.yml (gofmt, goimports, govet w/ shadow, errcheck, ineffassign, staticcheck, unused, revive) - .github/workflows/ci.yml: gofmt, vet, golangci-lint v2.1, go test, go test -race, go build - CHANGELOG.md with [Unreleased] entry --- .github/workflows/ci.yml | 47 +++++++++++++++++++++++++++++ .golangci.yml | 38 +++++++++++++++++++++++ CHANGELOG.md | 23 ++++++++++++++ cmd/kasapi-cli/main.go | 27 +++++++++++++++++ go.mod | 3 ++ internal/account/doc.go | 5 +++ internal/api/doc.go | 4 +++ internal/auth/doc.go | 3 ++ internal/chown/doc.go | 3 ++ internal/cli/doc.go | 3 ++ internal/config/doc.go | 3 ++ internal/cronjob/doc.go | 4 +++ internal/database/doc.go | 4 +++ internal/ddns/doc.go | 4 +++ internal/directoryprotection/doc.go | 6 ++++ internal/dns/doc.go | 4 +++ internal/domain/doc.go | 4 +++ internal/ftpuser/doc.go | 7 +++++ internal/mailaccount/doc.go | 4 +++ internal/mailfilter/doc.go | 4 +++ internal/mailforward/doc.go | 4 +++ internal/mailinglist/doc.go | 4 +++ internal/sambauser/doc.go | 4 +++ internal/server/doc.go | 3 ++ internal/session/doc.go | 4 +++ internal/soap/doc.go | 3 ++ internal/softwareinstall/doc.go | 5 +++ internal/ssl/doc.go | 3 ++ internal/subdomain/doc.go | 4 +++ internal/symlink/doc.go | 3 ++ internal/transport/doc.go | 3 ++ internal/usage/doc.go | 4 +++ internal/version/version.go | 25 +++++++++++++++ internal/version/version_test.go | 15 +++++++++ 34 files changed, 284 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .golangci.yml create mode 100644 CHANGELOG.md create mode 100644 cmd/kasapi-cli/main.go create mode 100644 go.mod create mode 100644 internal/account/doc.go create mode 100644 internal/api/doc.go create mode 100644 internal/auth/doc.go create mode 100644 internal/chown/doc.go create mode 100644 internal/cli/doc.go create mode 100644 internal/config/doc.go create mode 100644 internal/cronjob/doc.go create mode 100644 internal/database/doc.go create mode 100644 internal/ddns/doc.go create mode 100644 internal/directoryprotection/doc.go create mode 100644 internal/dns/doc.go create mode 100644 internal/domain/doc.go create mode 100644 internal/ftpuser/doc.go create mode 100644 internal/mailaccount/doc.go create mode 100644 internal/mailfilter/doc.go create mode 100644 internal/mailforward/doc.go create mode 100644 internal/mailinglist/doc.go create mode 100644 internal/sambauser/doc.go create mode 100644 internal/server/doc.go create mode 100644 internal/session/doc.go create mode 100644 internal/soap/doc.go create mode 100644 internal/softwareinstall/doc.go create mode 100644 internal/ssl/doc.go create mode 100644 internal/subdomain/doc.go create mode 100644 internal/symlink/doc.go create mode 100644 internal/transport/doc.go create mode 100644 internal/usage/doc.go create mode 100644 internal/version/version.go create mode 100644 internal/version/version_test.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7f5d2f2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +permissions: + contents: read + +jobs: + test: + name: lint & test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.23" + cache: true + + - name: gofmt + run: | + out=$(gofmt -l .) + if [ -n "$out" ]; then + echo "gofmt diff in:" + echo "$out" + exit 1 + fi + + - name: go vet + run: go vet ./... + + - name: golangci-lint + uses: golangci/golangci-lint-action@v7 + with: + version: v2.1 + + - name: go test + run: go test ./... + + - name: go test -race + run: go test -race ./... + + - name: build + run: go build ./cmd/kasapi-cli diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..8bb8525 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,38 @@ +version: "2" + +run: + timeout: 5m + tests: true + +linters: + default: none + enable: + - errcheck + - govet + - ineffassign + - staticcheck + - unused + - revive + settings: + revive: + rules: + - name: package-comments + - name: exported + arguments: + - disableStutteringCheck + govet: + enable: + - shadow + +formatters: + enable: + - gofmt + - goimports + settings: + goimports: + local-prefixes: + - github.com/chmmou/kasapi-cli + +issues: + max-issues-per-linter: 0 + max-same-issues: 0 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..6fef61d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,23 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- Bootstrap Go module `github.com/chmmou/kasapi-cli` (Go 1.23). +- `cmd/kasapi-cli` entry point with build-stamped `--version`. +- `internal/` package skeleton mirroring the clean-architecture layering in + `docs/go/ARCHITECTURE.md`: per-resource domain packages + (`account`, `server`, `domain`, `subdomain`, `dns`, `mailaccount`, + `mailforward`, `mailfilter`, `mailinglist`, `database`, `ftpuser`, + `sambauser`, `cronjob`, `ddns`, `directoryprotection`, `softwareinstall`, + `ssl`, `usage`, `chown`, `symlink`, `session`) plus inner-/adapter-layer + packages (`soap`, `transport`, `auth`, `api`, `config`, `cli`, `version`). +- `.golangci.yml` matching the gate set in `docs/go/LINTING.md`. +- GitHub Actions CI workflow running `gofmt`, `go vet`, `golangci-lint`, + `go test`, `go test -race`, and `go build ./cmd/kasapi-cli`. diff --git a/cmd/kasapi-cli/main.go b/cmd/kasapi-cli/main.go new file mode 100644 index 0000000..290fe8d --- /dev/null +++ b/cmd/kasapi-cli/main.go @@ -0,0 +1,27 @@ +// Command kasapi-cli is the All-Inkl KAS API command-line client. +// +// This is the wiring layer per docs/go/ARCHITECTURE.md: it composes the +// inner layers (domain/use cases) with the outer adapters (SOAP transport, +// HTTP client, CLI) and exposes them through subcommands. +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/chmmou/kasapi-cli/internal/version" +) + +func main() { + showVersion := flag.Bool("version", false, "print version and exit") + flag.Parse() + + if *showVersion { + fmt.Println(version.String()) + return + } + + fmt.Fprintln(os.Stderr, "kasapi-cli: no subcommand wired up yet (see issues #2-#13)") + os.Exit(1) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5bd9711 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/chmmou/kasapi-cli + +go 1.23 diff --git a/internal/account/doc.go b/internal/account/doc.go new file mode 100644 index 0000000..0c94bae --- /dev/null +++ b/internal/account/doc.go @@ -0,0 +1,5 @@ +// Package account holds the domain types and use cases for the KAS account +// endpoints (get_accounts, get_accountsettings, get_accountresources, +// add_account, update_account, delete_account, update_accountsettings, +// update_superusersettings). See issue #7. +package account diff --git a/internal/api/doc.go b/internal/api/doc.go new file mode 100644 index 0000000..decd1e6 --- /dev/null +++ b/internal/api/doc.go @@ -0,0 +1,4 @@ +// Package api is the generic KasApi.php call surface that all per-resource +// modules build on. It owns error mapping from KAS error strings to typed +// Go errors. See issue #6. +package api diff --git a/internal/auth/doc.go b/internal/auth/doc.go new file mode 100644 index 0000000..f183e6e --- /dev/null +++ b/internal/auth/doc.go @@ -0,0 +1,3 @@ +// Package auth implements the KasAuth.php credential-token flow +// (plain / session / 2FA). See issue #5. +package auth diff --git a/internal/chown/doc.go b/internal/chown/doc.go new file mode 100644 index 0000000..a6047f2 --- /dev/null +++ b/internal/chown/doc.go @@ -0,0 +1,3 @@ +// Package chown holds the domain types and use cases for the KAS chown +// endpoint (update_chown). See issue #13. +package chown diff --git a/internal/cli/doc.go b/internal/cli/doc.go new file mode 100644 index 0000000..c7b9a15 --- /dev/null +++ b/internal/cli/doc.go @@ -0,0 +1,3 @@ +// Package cli holds the root command, global flags, and shared output +// renderers (json / yaml / table). See issue #12. +package cli diff --git a/internal/config/doc.go b/internal/config/doc.go new file mode 100644 index 0000000..5d69ef4 --- /dev/null +++ b/internal/config/doc.go @@ -0,0 +1,3 @@ +// Package config loads KAS credentials and CLI defaults from a TOML file +// (XDG path), env vars, and command-line flags. See issue #2. +package config diff --git a/internal/cronjob/doc.go b/internal/cronjob/doc.go new file mode 100644 index 0000000..bf02e97 --- /dev/null +++ b/internal/cronjob/doc.go @@ -0,0 +1,4 @@ +// Package cronjob holds the domain types and use cases for the KAS cronjob +// endpoints (get_cronjobs, get_cronjob, add_cronjob, update_cronjob, +// delete_cronjob). See issues #11 and #13. +package cronjob diff --git a/internal/database/doc.go b/internal/database/doc.go new file mode 100644 index 0000000..5477d19 --- /dev/null +++ b/internal/database/doc.go @@ -0,0 +1,4 @@ +// Package database holds the domain types and use cases for the KAS +// database endpoints (get_databases, get_database, add_database, +// update_database, delete_database). See issues #11 and #13. +package database diff --git a/internal/ddns/doc.go b/internal/ddns/doc.go new file mode 100644 index 0000000..85db613 --- /dev/null +++ b/internal/ddns/doc.go @@ -0,0 +1,4 @@ +// Package ddns holds the domain types and use cases for the KAS DynDNS +// endpoints (get_ddnsusers, add_ddnsuser, update_ddnsuser, +// delete_ddnsuser). See issues #11 and #13. +package ddns diff --git a/internal/directoryprotection/doc.go b/internal/directoryprotection/doc.go new file mode 100644 index 0000000..ab8c403 --- /dev/null +++ b/internal/directoryprotection/doc.go @@ -0,0 +1,6 @@ +// Package directoryprotection holds the domain types and use cases for the +// KAS directory-protection endpoints (get_directoryprotections, +// get_directoryprotection, add_directoryprotection, +// update_directoryprotection, delete_directoryprotection). See issues #11 +// and #13. +package directoryprotection diff --git a/internal/dns/doc.go b/internal/dns/doc.go new file mode 100644 index 0000000..16542c4 --- /dev/null +++ b/internal/dns/doc.go @@ -0,0 +1,4 @@ +// Package dns holds the domain types and use cases for the KAS DNS +// endpoints (get_dns_settings, add_dns_settings, update_dns_settings, +// delete_dns_settings, reset_dns_settings). See issues #8 and #13. +package dns diff --git a/internal/domain/doc.go b/internal/domain/doc.go new file mode 100644 index 0000000..cb0674f --- /dev/null +++ b/internal/domain/doc.go @@ -0,0 +1,4 @@ +// Package domain holds the domain types and use cases for the KAS domain +// endpoints (get_domains, get_domain, get_topleveldomains, add_domain, +// update_domain, delete_domain, move_domain). See issues #8 and #13. +package domain diff --git a/internal/ftpuser/doc.go b/internal/ftpuser/doc.go new file mode 100644 index 0000000..3897b42 --- /dev/null +++ b/internal/ftpuser/doc.go @@ -0,0 +1,7 @@ +// Package ftpuser holds the domain types and use cases for the KAS FTP-user +// endpoints (get_ftpusers, get_ftpuser, add_ftpuser, update_ftpuser, +// delete_ftpuser). See issues #11 and #13. +// +// Note: KAS docs spell the create action add_ftpusers (plural) while the +// fixture folder uses the singular form — verify against the live API. +package ftpuser diff --git a/internal/mailaccount/doc.go b/internal/mailaccount/doc.go new file mode 100644 index 0000000..edf53cf --- /dev/null +++ b/internal/mailaccount/doc.go @@ -0,0 +1,4 @@ +// Package mailaccount holds the domain types and use cases for the KAS +// mail-account endpoints (get_mailaccounts, get_mailaccount, add_mailaccount, +// update_mailaccount, delete_mailaccount). See issues #9 and #13. +package mailaccount diff --git a/internal/mailfilter/doc.go b/internal/mailfilter/doc.go new file mode 100644 index 0000000..c7c782e --- /dev/null +++ b/internal/mailfilter/doc.go @@ -0,0 +1,4 @@ +// Package mailfilter holds the domain types and use cases for the KAS +// mail-standard-filter endpoints (get_mailstandardfilter, +// add_mailstandardfilter, delete_mailstandardfilter). See issues #9 and #13. +package mailfilter diff --git a/internal/mailforward/doc.go b/internal/mailforward/doc.go new file mode 100644 index 0000000..810c17f --- /dev/null +++ b/internal/mailforward/doc.go @@ -0,0 +1,4 @@ +// Package mailforward holds the domain types and use cases for the KAS +// mail-forward endpoints (get_mailforwards, get_mailforward, add_mailforward, +// update_mailforward, delete_mailforward). See issues #9 and #13. +package mailforward diff --git a/internal/mailinglist/doc.go b/internal/mailinglist/doc.go new file mode 100644 index 0000000..46ef781 --- /dev/null +++ b/internal/mailinglist/doc.go @@ -0,0 +1,4 @@ +// Package mailinglist holds the domain types and use cases for the KAS +// mailinglist endpoints (get_mailinglists, add_mailinglist, +// update_mailinglist, delete_mailinglist). See issues #9 and #13. +package mailinglist diff --git a/internal/sambauser/doc.go b/internal/sambauser/doc.go new file mode 100644 index 0000000..50e3937 --- /dev/null +++ b/internal/sambauser/doc.go @@ -0,0 +1,4 @@ +// Package sambauser holds the domain types and use cases for the KAS +// samba-user endpoints (get_sambausers, add_sambauser, update_sambauser, +// delete_sambauser). See issues #11 and #13. +package sambauser diff --git a/internal/server/doc.go b/internal/server/doc.go new file mode 100644 index 0000000..2bdebdb --- /dev/null +++ b/internal/server/doc.go @@ -0,0 +1,3 @@ +// Package server holds the domain types and use cases for the KAS server +// information endpoint (get_server_information). See issue #7. +package server diff --git a/internal/session/doc.go b/internal/session/doc.go new file mode 100644 index 0000000..25788dd --- /dev/null +++ b/internal/session/doc.go @@ -0,0 +1,4 @@ +// Package session holds the domain types and use cases for the KAS session +// endpoints (add_session, delete_session) used by the session-mode auth +// flow. See issues #5 and #11. +package session diff --git a/internal/soap/doc.go b/internal/soap/doc.go new file mode 100644 index 0000000..989d549 --- /dev/null +++ b/internal/soap/doc.go @@ -0,0 +1,3 @@ +// Package soap implements the Apache xml-soap ns2:Map codec used by every +// KAS-API response. See issue #3. +package soap diff --git a/internal/softwareinstall/doc.go b/internal/softwareinstall/doc.go new file mode 100644 index 0000000..fa09160 --- /dev/null +++ b/internal/softwareinstall/doc.go @@ -0,0 +1,5 @@ +// Package softwareinstall holds the domain types and use cases for the KAS +// software-install endpoints (get_softwareinstalls, get_softwareinstall, +// add_softwareinstall). The KAS API has no update or delete for this +// resource. See issues #11 and #13. +package softwareinstall diff --git a/internal/ssl/doc.go b/internal/ssl/doc.go new file mode 100644 index 0000000..4218e17 --- /dev/null +++ b/internal/ssl/doc.go @@ -0,0 +1,3 @@ +// Package ssl holds the domain types and use cases for the KAS SSL endpoint +// (update_ssl). See issue #13. +package ssl diff --git a/internal/subdomain/doc.go b/internal/subdomain/doc.go new file mode 100644 index 0000000..6d02182 --- /dev/null +++ b/internal/subdomain/doc.go @@ -0,0 +1,4 @@ +// Package subdomain holds the domain types and use cases for the KAS +// subdomain endpoints (get_subdomains, add_subdomain, update_subdomain, +// delete_subdomain, move_subdomain). See issues #8 and #13. +package subdomain diff --git a/internal/symlink/doc.go b/internal/symlink/doc.go new file mode 100644 index 0000000..8544e27 --- /dev/null +++ b/internal/symlink/doc.go @@ -0,0 +1,3 @@ +// Package symlink holds the domain types and use cases for the KAS symlink +// endpoint (add_symlink). See issue #13. +package symlink diff --git a/internal/transport/doc.go b/internal/transport/doc.go new file mode 100644 index 0000000..e01bc15 --- /dev/null +++ b/internal/transport/doc.go @@ -0,0 +1,3 @@ +// Package transport provides the HTTP client that wraps the SOAP codec and +// enforces KasFloodDelay between successive calls. See issue #4. +package transport diff --git a/internal/usage/doc.go b/internal/usage/doc.go new file mode 100644 index 0000000..a9d8cd9 --- /dev/null +++ b/internal/usage/doc.go @@ -0,0 +1,4 @@ +// Package usage holds the domain types and use cases for the KAS +// space/traffic endpoints (get_space, get_space_usage, get_traffic). +// Fixtures live under testdata/statistic/. See issue #10. +package usage diff --git a/internal/version/version.go b/internal/version/version.go new file mode 100644 index 0000000..1927329 --- /dev/null +++ b/internal/version/version.go @@ -0,0 +1,25 @@ +// Package version exposes build-time version information for kasapi-cli. +// +// Version, Commit and Date are populated via -ldflags at build time: +// +// go build -ldflags "-X github.com/chmmou/kasapi-cli/internal/version.Version=v0.1.0 \ +// -X github.com/chmmou/kasapi-cli/internal/version.Commit=$(git rev-parse --short HEAD) \ +// -X github.com/chmmou/kasapi-cli/internal/version.Date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ +// ./cmd/kasapi-cli +package version + +import "fmt" + +// Version is the semver tag the binary was built from. +var Version = "dev" + +// Commit is the short git revision the binary was built from. +var Commit = "none" + +// Date is the build timestamp in RFC3339 form. +var Date = "unknown" + +// String returns a human-readable single-line version banner. +func String() string { + return fmt.Sprintf("kasapi-cli %s (commit %s, built %s)", Version, Commit, Date) +} diff --git a/internal/version/version_test.go b/internal/version/version_test.go new file mode 100644 index 0000000..853f33e --- /dev/null +++ b/internal/version/version_test.go @@ -0,0 +1,15 @@ +package version + +import ( + "strings" + "testing" +) + +func TestStringContainsFields(t *testing.T) { + got := String() + for _, want := range []string{"kasapi-cli", Version, Commit, Date} { + if !strings.Contains(got, want) { + t.Errorf("String() = %q, want it to contain %q", got, want) + } + } +}