diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..c728b48 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,24 @@ +stages: + - test + - release + +lint: + stage: test + image: registry.gitlab.com/etke.cc/base + script: + - make lint + +unit: + stage: test + image: registry.gitlab.com/etke.cc/base + script: + - make test + +release: + stage: release + only: ['tags'] + image: + name: goreleaser/goreleaser + entrypoint: [''] + script: + - goreleaser release --rm-dist diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..6048e7b --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,94 @@ +run: + concurrency: 4 + timeout: 5m + issues-exit-code: 1 + tests: true + build-tags: [] + skip-dirs: [] + skip-dirs-use-default: true + skip-files: [] + modules-download-mode: readonly + allow-parallel-runners: false + +output: + format: colored-line-number + print-issued-lines: true + print-linter-name: true + uniq-by-line: true + path-prefix: "" + sort-results: true + +linters-settings: + errcheck: + check-blank: true + gci: + local-prefixes: gitlab.com/etke.cc/emm + gocognit: + min-complexity: 10 + nestif: + min-complexity: 4 + gocritic: + enabled-tags: + - performance + gofumpt: + lang-version: "1.17" + goimports: + local-prefixes: gitlab.com/etke.cc/emm + gosimple: + go: "1.17" + checks: [ "all" ] + govet: + check-shadowing: true + enable: + - atomicalign + - shadow + misspell: + locale: US + staticcheck: + go: "1.17" + checks: [ "all" ] + stylecheck: + go: "1.17" + unparam: + check-exported: true + unused: + go: "1.17" +linters: + disable-all: false + enable: + - megacheck + - govet + - errcheck + - gci + - gocognit + - nestif + - gocritic + - gofumpt + - goimports + - gosimple + - govet + - misspell + - staticcheck + - stylecheck + - unparam + - unused + fast: false + + +issues: + exclude-rules: + - path: _test\.go + linters: + - gocyclo + - errcheck + - dupl + - gosec + - linters: + - staticcheck + text: "SA9003:" + - linters: + - lll + source: "^//go:generate " + max-issues-per-linter: 0 + max-same-issues: 0 + new: false diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..043e9e8 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,36 @@ +project_name: emm +before: + hooks: + - go mod tidy + +builds: + - main: ./cmd + binary: emm + goos: + - freebsd + - linux + - darwin + goarch: + - arm + - arm64 + - amd64 + +nfpms: + - vendor: https://etke.cc + package_name: export-matrix-messages + maintainer: etke.cc + description: emm stands for export-matrix-messages, cli tool that can export messages sent into specific matrix room to one or more files + homepage: https://gitlab.com/etke.cc/emm + license: MIT + formats: + - deb + - rpm + - apk + file_name_template: "{{ .PackageName }}-{{ .Version }}_{{ .Os }}-{{ .Arch }}" + +changelog: + sort: asc +checksum: + disable: true +archives: + - format: binary diff --git a/Makefile b/Makefile index 676bbac..c41aa87 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,8 @@ -BUILDFLAGS = -buildmode=pie -### CI vars -CI_LOGIN_COMMAND = @echo "Not a CI, skip login" -CI_REGISTRY_IMAGE ?= registry.gitlab.com/etke.cc/honoroit -CI_COMMIT_TAG ?= latest -# for main branch it must be set explicitly -ifeq ($(CI_COMMIT_TAG), main) -CI_COMMIT_TAG = latest -endif -# login command -ifdef CI_JOB_TOKEN -CI_LOGIN_COMMAND = @docker login -u gitlab-ci-token -p $(CI_JOB_TOKEN) $(CI_REGISTRY) -endif +export CGO_CPPFLAGS=${CPPFLAGS} +export CGO_CFLAGS=${CFLAGS} +export CGO_CXXFLAGS=${CXXFLAGS} +export CGO_LDFLAGS=${LDFLAGS} +GOFLAGS ?= -buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw # update go dependencies update: @@ -19,7 +11,6 @@ update: go mod vendor mock: - -@rm -rf mocks @mockery --all # run linter @@ -32,24 +23,19 @@ lintfix: # run unit tests test: - @go test ${BUILDFLAGS} -coverprofile=cover.out ./... + @go test -coverprofile=cover.out ./... @go tool cover -func=cover.out -@rm -f cover.out -# run honoroit, note: make doesn't understand exit code 130 and sets it == 1 +# run emm, note: make doesn't understand exit code 130 and sets it == 1 run: - @go run ${BUILDFLAGS} ./cmd || exit 0 + @go run ./cmd || exit 0 -# build honoroit +install: build + @mv ./emm ${HOME}/go/bin/ + @echo "emm has been installed." + +# build emm build: - go build ${BUILDFLAGS} -v -o honoroit -ldflags "-X main.version=${CI_COMMIT_TAG}" ./cmd + go build -v -o emm ./cmd -# CI: docker login -login: - @echo "trying to login to docker registry..." - $(CI_LOGIN_COMMAND) - -# docker build -docker: - docker buildx create --use - docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --push -t ${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG} . diff --git a/README.md b/README.md index c1bf40b..b4e1ff7 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,48 @@ -# emm: Export Matrix Messages +# emm: Export Matrix Messages [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/etkecc) [![coverage report](https://gitlab.com/etke.cc/emm/badges/main/coverage.svg)](https://gitlab.com/etke.cc/emm/-/commits/main) [![Go Report Card](https://goreportcard.com/badge/gitlab.com/etke.cc/emm)](https://goreportcard.com/report/gitlab.com/etke.cc/emm) [![Go Reference](https://pkg.go.dev/badge/gitlab.com/etke.cc/emm.svg)](https://pkg.go.dev/gitlab.com/etke.cc/emm) A CLI tool that joins the room and exports last N messages to the file you specified. -## TODO +## Features -* setup the repo properly -* add docs +* Get messages from any matrix room +* Export messages to one file for all messages +* Export each message in separate file +* Custom templates supported (`contrib` contains an example of hugo post template, [etke.cc/webite](https://gitlab.com/etke.cc/website) can be used as reference) +* Delegation and aliases supported +* `Anyone`/`world_readable` access supported without invite ## Usage +### Full example + +That's how [etke.cc/website](https://gitlab.com/etke.cc/website) news generated + ```bash emm -hs hs.url -u user -p pass -r "#room:hs.url" -t contrib/hugo-post-template.md -o /tmp/%s.md ``` + +### Documentation + +```bash +Usage of emm: + -hs string + Homeserver URL (supports delegation) + -l int + Messages limit + -o string + Output filename. If it contains %s, it will be replaced with event ID (one message per file) + -p string + Password of the matrix user + -r string + Room ID or alias + -t string + Template file. Default is JSON message struct + -u string + Username/Login of the matrix user +``` + +## How to get + +* [Releases](https://gitlab.com/etke.cc/emm/-/releases) for freebsd, linux and MacOS +* or `go install gitlab.com/etke.cc/emm@latest` / `make install` +* or from source code diff --git a/cmd/cmd.go b/cmd/cmd.go index 5aabb2b..42f0452 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -1,10 +1,11 @@ package main import ( + "maunium.net/go/mautrix/id" + "gitlab.com/etke.cc/emm/export" "gitlab.com/etke.cc/emm/flags" "gitlab.com/etke.cc/emm/matrix" - "maunium.net/go/mautrix/id" ) var cfg *flags.Config diff --git a/export/export_test.go b/export/export_test.go new file mode 100644 index 0000000..0fd21d2 --- /dev/null +++ b/export/export_test.go @@ -0,0 +1 @@ +package export diff --git a/export/output.go b/export/output.go index a0dc89f..7c3f064 100644 --- a/export/output.go +++ b/export/output.go @@ -26,12 +26,12 @@ func isMulti(output string) bool { func getOutputSingle(output string) (*os.File, error) { var err error if outputFileSingle == nil { - outputFileSingle, err = os.OpenFile(output, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644) + outputFileSingle, err = os.OpenFile(output, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o644) } return outputFileSingle, err } func getOutputMulti(output string) (*os.File, error) { - return os.OpenFile(output, os.O_WRONLY|os.O_CREATE, 0644) + return os.OpenFile(output, os.O_WRONLY|os.O_CREATE, 0o644) } diff --git a/flags/flags.go b/flags/flags.go index 99373dd..22de963 100644 --- a/flags/flags.go +++ b/flags/flags.go @@ -30,6 +30,7 @@ type Config struct { Output *string } +// nolint // as-is for now func (cfg *Config) validate() error { if cfg.HS == nil || *cfg.HS == "" { return errors.New("-hs is not set. You must specify homeserver URL") diff --git a/flags/flags_test.go b/flags/flags_test.go new file mode 100644 index 0000000..0cfcbd5 --- /dev/null +++ b/flags/flags_test.go @@ -0,0 +1 @@ +package flags diff --git a/matrix/client.go b/matrix/client.go index 2186ea8..8d5fb3d 100644 --- a/matrix/client.go +++ b/matrix/client.go @@ -5,8 +5,10 @@ import ( "maunium.net/go/mautrix/id" ) -var client *mautrix.Client -var room id.RoomID +var ( + client *mautrix.Client + room id.RoomID +) // Init matrix client func Init(hs string, login string, password string, roomID id.RoomID, alias id.RoomAlias) error { diff --git a/matrix/matrix_test.go b/matrix/matrix_test.go new file mode 100644 index 0000000..2903ff7 --- /dev/null +++ b/matrix/matrix_test.go @@ -0,0 +1 @@ +package matrix