diff --git a/.circleci/config.yml b/.circleci/config.yml index 35eb942..1dadb53 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,6 +12,7 @@ workflows: - go_1-18 - go_1-19 - go_1-20 + - go_1-25 - build_docs commands: @@ -19,7 +20,7 @@ commands: description: Run linter checks on TeleIRC. steps: - checkout - - run: + - run: name: Download and install golintci-lint. command: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sudo sh -s -- -b $(go env GOPATH)/bin v1.43.0 - run: @@ -64,6 +65,30 @@ jobs: command: | sed -i 's/github.com\/ritlug\/teleirc\///g' c.out /tmp/cc-test-reporter after-build + go_1-25: + docker: + - image: cimg/go:1.25 + steps: + - checkout + - run: + name: Download and install golintci-lint. + command: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sudo sh -s -- -b $(go env GOPATH)/bin v2.6.1 + - run: + name: Run Go linter checks. + command: golangci-lint run + - teleirc-test + - run: + name: Display test coverage summary. + command: | + go tool cover -func=c.out + echo "Total coverage:" + go tool cover -func=c.out | grep total | awk '{print $3}' + - run: + name: Generate HTML coverage report. + command: go tool cover -html=c.out -o coverage.html + - store_artifacts: + path: coverage.html + destination: coverage-report build_docs: docker: - image: cimg/python:3.10 diff --git a/cmd/teleirc.go b/cmd/teleirc.go index fa8921c..c24e5a7 100644 --- a/cmd/teleirc.go +++ b/cmd/teleirc.go @@ -6,6 +6,7 @@ import ( "os" "os/signal" "syscall" + "strconv" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" "github.com/ritlug/teleirc/internal" @@ -14,8 +15,8 @@ import ( ) var ( - flagPath = flag.String("conf", ".env", "config file") - flagDebug = flag.Bool("debug", false, "enable debugging output") + flagPath = flag.String("conf", "", "config file") + flagDebug = flag.Bool("debug", func() bool { env, _ := strconv.ParseBool(os.Getenv("DEBUG")); return env }(), "enable debugging output") flagVersion = flag.Bool("version", false, "displays current version of TeleIRC") version string ) diff --git a/deployments/container/Dockerfile b/deployments/container/Dockerfile index 633cd8a..d813999 100644 --- a/deployments/container/Dockerfile +++ b/deployments/container/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.22-alpine AS builder +FROM golang:1.25-alpine AS builder WORKDIR /app @@ -16,8 +16,6 @@ RUN adduser -D teleirc-user USER teleirc-user COPY --from=builder /app/teleirc /opt/teleirc/teleirc -COPY --from=builder /app/.env /opt/teleirc/conf WORKDIR /opt/teleirc ENTRYPOINT [ "./teleirc" ] -CMD [ "-conf", "/opt/teleirc/conf", "-debug", "true" ] diff --git a/deployments/container/docker-compose.yml.example b/deployments/container/docker-compose.yml.example index 59ce7db..63797c1 100644 --- a/deployments/container/docker-compose.yml.example +++ b/deployments/container/docker-compose.yml.example @@ -6,7 +6,6 @@ version: '3' services: teleirc: build: - context: ../../ - dockerfile: ./deployments/container/Dockerfile - env_file: ../../.env + context: https://github.com/RITlug/teleirc.git + dockerfile: deployments/container/Dockerfile user: teleirc diff --git a/docs/user/config-file-glossary.rst b/docs/user/config-file-glossary.rst index 21beffc..0491833 100644 --- a/docs/user/config-file-glossary.rst +++ b/docs/user/config-file-glossary.rst @@ -3,8 +3,21 @@ Config file glossary #################### This page is a glossary of different settings in the ``env.example`` configuration file. -All values shown are the default settings. -This glossary is intended for advanced users. + +.. note:: + All values shown are the default settings. + This glossary is intended for advanced users. + + +************ +General settings +************ + +Configuration settings +======================== + +``DEBUG=false`` + (Optional) Verbose logging, enabled when set to `true` ************ diff --git a/docs/user/quick-start.md b/docs/user/quick-start.md index 53e2fe9..9c19560 100644 --- a/docs/user/quick-start.md +++ b/docs/user/quick-start.md @@ -132,15 +132,35 @@ There are two ways to deploy TeleIRC persistently: Containers are the easiest way to deploy TeleIRC. Dockerfiles and other deployment resources are available in ``deployments/``. -#### Build TeleIRC +Ensure you have [docker](https://www.docker.com/) installed. + +#### Build TeleIRC docker image -1. Ensure you have [docker](https://www.docker.com/) installed 1. Enter container deployment directory (`cd deployments/container`) 1. Build image (`./build_image.sh`) 1. Run container (`docker run teleirc:latest`) -**NOTE**: -**This deployment method assumes you have a complete .env file** +> [!NOTE] +> This deployment can optionally copy a standalone .env file + + +#### Run TeleIRC using Docker compose + +1. Enter container deployment directory (`cd deployments/container`) +1. Run service using `docker compose`: + +```bash +IRC_SERVER=chat.freenode.net \ +IRC_CHANNEL='#channelname' \ +IRC_BOT_NAME='teleirc' \ +TELEIRC_TOKEN='000000000:AAAAAAaAAa2AaAAaoAAAA-a_aaAAaAaaaAA' \ +TELEGRAM_CHAT_ID='-0000000000000' \ +docker compose up -d teleirc +``` + +> [!TIP] +> Instead you can also add `environment:` entries via `docker-compose.yml`, or pass a standalone `.env` file using the CLI: +> `docker compose --env-file ../../.env up --build -d teleirc` ### Run binary diff --git a/env.example b/env.example index c9282e7..ed5650c 100644 --- a/env.example +++ b/env.example @@ -2,6 +2,17 @@ # See the Config File Glossary for instructions. # https://docs.teleirc.com/en/latest/user/config-file-glossary/ +############################################################################### +# # +# General settings # +# # +############################################################################### + +#####----- Configuration settings -----##### +DEBUG=false + + + ############################################################################### # # # IRC configuration settings # @@ -77,6 +88,7 @@ LEAVE_MESSAGE_ALLOW_LIST="" SHOW_DISCONNECT_MESSAGE=true + ################################################################################ # # # Imgur configuration settings # diff --git a/internal/config.go b/internal/config.go index 4d22cc9..0381263 100644 --- a/internal/config.go +++ b/internal/config.go @@ -3,6 +3,7 @@ package internal import ( "fmt" "os" + "path/filepath" "strings" "github.com/caarlos0/env/v6" @@ -135,13 +136,33 @@ func LoadConfig(path string) (*Settings, error) { if err := validate.RegisterValidation("notempty", validateEmptyString); err != nil { return nil, err } - // Attempt to load environment variables from path if path was provided - if path != ".env" && path != "" { - if err := godotenv.Load(path); err != nil { - return nil, err + // If a path was provided, try to load it. + if path != "" { + if info, err := os.Stat(path); err == nil { + // If the path is a directory, look for /.env. + if info.IsDir() { + envFile := filepath.Join(path, defaultPath) + if _, err := os.Stat(envFile); err == nil { + if err := godotenv.Load(envFile); err != nil { + return nil, err + } + } + } else { + // path exists and is a file — attempt to load it + if err := godotenv.Load(path); err != nil { + return nil, err + } + } + } else { + // If the provided path does not exist, continue and rely on passed process ENV variables + if os.IsNotExist(err) { + warning.Printf("config path %q not provided or does not exist; continuing and using process environment variables", path) + } else { + return nil, err + } } } else if _, err := os.Stat(defaultPath); !os.IsNotExist(err) { - // Attempt to load from defaultPath if defaultPath exists + // Attempt to load from defaultPath if it exists if err := godotenv.Load(defaultPath); err != nil { return nil, err }