diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..afc916b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/llm +/llmd diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..5f0d58c --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,35 @@ +run: + # timeout for analysis + deadline: 4m + + # Linting uses a lot of memory. Keep it under control by only running a single + # worker. + concurrency: 1 + +linters-settings: + govet: + # Don't report about shadowed variables + check-shadowing: false + gofmt: + # simplify code: gofmt with `-s` option, true by default + simplify: true + +linters: + enable-all: true + disable: + # Init functions are used by loggers throughout the codebase. + - gochecknoinits + + # Global variables are used by loggers. + - gochecknoglobals + + # Some lines are over 80 characters on purpose and we don't want to make + # them even longer by marking them as 'nolint'. + - lll + + # We don't care (enough) about misaligned structs to lint that. + - maligned + + # We have long functions, especially in tests. Moving or renaming those + # would trigger funlen problems that we may not want to solve at that time. + - funlen diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cfcf1c1 --- /dev/null +++ b/Makefile @@ -0,0 +1,141 @@ +PKG := github.com/lightninglabs/llm +ESCPKG := github.com\/lightninglabs\/llm + +LINT_PKG := github.com/golangci/golangci-lint/cmd/golangci-lint +GOVERALLS_PKG := github.com/mattn/goveralls +GOACC_PKG := github.com/ory/go-acc + +GO_BIN := ${GOPATH}/bin +GOVERALLS_BIN := $(GO_BIN)/goveralls +LINT_BIN := $(GO_BIN)/golangci-lint +GOACC_BIN := $(GO_BIN)/go-acc + +LINT_COMMIT := v1.18.0 +GOACC_COMMIT := ddc355013f90fea78d83d3a6c71f1d37ac07ecd5 + +DEPGET := cd /tmp && go get -v +GOBUILD := go build -v +GOINSTALL := go install -v +GOTEST := go test -v + +GOFILES_NOVENDOR = $(shell find . -type f -name '*.go' -not -path "./vendor/*") +GOLIST := go list -deps $(PKG)/... | grep '$(PKG)'| grep -v '/vendor/' +GOLISTCOVER := $(shell go list -deps -f '{{.ImportPath}}' ./... | grep '$(PKG)' | sed -e 's/^$(ESCPKG)/./') + +RM := rm -f +CP := cp +MAKE := make +XARGS := xargs -L 1 + +include make/testing_flags.mk + +LINT = $(LINT_BIN) run -v + +GREEN := "\\033[0;32m" +NC := "\\033[0m" +define print + echo $(GREEN)$1$(NC) +endef + +default: scratch + +all: scratch check install + +# ============ +# DEPENDENCIES +# ============ + +$(GOVERALLS_BIN): + @$(call print, "Fetching goveralls.") + go get -u $(GOVERALLS_PKG) + +$(LINT_BIN): + @$(call print, "Fetching linter") + $(DEPGET) $(LINT_PKG)@$(LINT_COMMIT) + +$(GOACC_BIN): + @$(call print, "Fetching go-acc") + $(DEPGET) $(GOACC_PKG)@$(GOACC_COMMIT) + +# ============ +# INSTALLATION +# ============ + +build: + @$(call print, "Building LLM.") + $(GOBUILD) $(PKG)/cmd/llm + $(GOBUILD) $(PKG)/cmd/llmd + +install: + @$(call print, "Installing LLM.") + $(GOINSTALL) $(PKG)/cmd/llm + $(GOINSTALL) $(PKG)/cmd/llmd + +scratch: build + +# ======= +# TESTING +# ======= + +check: unit + +unit: + @$(call print, "Running unit tests.") + $(UNIT) + +unit-cover: $(GOACC_BIN) + @$(call print, "Running unit coverage tests.") + $(GOACC_BIN) $(COVER_PKG) + +unit-race: + @$(call print, "Running unit race tests.") + env CGO_ENABLED=1 GORACE="history_size=7 halt_on_errors=1" $(UNIT_RACE) + +goveralls: $(GOVERALLS_BIN) + @$(call print, "Sending coverage report.") + $(GOVERALLS_BIN) -coverprofile=coverage.txt -service=travis-ci + +travis-race: lint unit-race + +travis-cover: lint unit-cover goveralls + +travis-itest: lint + +# ============= +# FLAKE HUNTING +# ============= +flake-unit: + @$(call print, "Flake hunting unit tests.") + while [ $$? -eq 0 ]; do GOTRACEBACK=all $(UNIT) -count=1; done + +flake-race: + @$(call print, "Flake hunting race tests.") + while [ $$? -eq 0 ]; do GOTRACEBACK=all CGO_ENABLED=1 GORACE="history_size=7 halt_on_errors=1" $(UNIT_RACE) -count=1; done + +# ========= +# UTILITIES +# ========= +fmt: + @$(call print, "Formatting source.") + gofmt -l -w -s $(GOFILES_NOVENDOR) + +lint: $(LINT_BIN) + @$(call print, "Linting source.") + $(LINT) + +list: + @$(call print, "Listing commands.") + @$(MAKE) -qp | \ + awk -F':' '/^[a-zA-Z0-9][^$$#\/\t=]*:([^=]|$$)/ {split($$1,A,/ /);for(i in A)print A[i]}' | \ + grep -v Makefile | \ + sort + +rpc: + @$(call print, "Compiling protos.") + cd ./clmrpc; ./gen_protos.sh + +clean: + @$(call print, "Cleaning source.$(NC)") + $(RM) ./llm + $(RM) ./llmd + $(RM) coverage.txt diff --git a/make/testing_flags.mk b/make/testing_flags.mk new file mode 100644 index 0000000..ff8dfbe --- /dev/null +++ b/make/testing_flags.mk @@ -0,0 +1,40 @@ +TEST_FLAGS = +COVER_PKG = $$(go list -deps ./... | grep '$(PKG)') + +# If specific package is being unit tested, construct the full name of the +# subpackage. +ifneq ($(pkg),) +UNITPKG := $(PKG)/$(pkg) +UNIT_TARGETED = yes +COVER_PKG = $(PKG)/$(pkg) +endif + +# If a specific unit test case is being target, construct test.run filter. +ifneq ($(case),) +TEST_FLAGS += -test.run=$(case) +UNIT_TARGETED = yes +endif + +# If a timeout was requested, construct initialize the proper flag for the go +# test command. If not, we set 20m (up from the default 10m). +ifneq ($(timeout),) +TEST_FLAGS += -test.timeout=$(timeout) +else +TEST_FLAGS += -test.timeout=20m +endif + +# UNIT_TARGTED is undefined iff a specific package and/or unit test case is +# not being targeted. +UNIT_TARGETED ?= no + +# If a specific package/test case was requested, run the unit test for the +# targeted case. Otherwise, default to running all tests. +ifeq ($(UNIT_TARGETED), yes) +UNIT := $(GOTEST) $(TEST_FLAGS) $(UNITPKG) +UNIT_RACE := $(GOTEST) $(TEST_FLAGS) -race $(UNITPKG) +endif + +ifeq ($(UNIT_TARGETED), no) +UNIT := $(GOLIST) | $(XARGS) env $(GOTEST) $(TEST_FLAGS) +UNIT_RACE := $(UNIT) -race +endif