From 85f958dd11341d99e285c146fa2df75a485967e1 Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Mon, 27 Mar 2023 20:25:20 +0800 Subject: [PATCH 01/12] Design pre-version storage Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- Make | 192 +++++++++++++++++++++++++ Makefile | 102 ++++++++++--- {utils => pkg}/version/version.go | 0 {utils => pkg}/version/version_test.go | 0 {hack => scripts}/LICENSE_TEMPLATE | 0 {hack => scripts}/boilerplate.go.txt | 0 {hack => scripts}/build.sh | 0 scripts/make-rules/ca.mk | 0 scripts/make-rules/common.mk | 81 +++++++++++ scripts/make-rules/copyright.mk | 0 scripts/make-rules/dependencies.mk | 0 scripts/make-rules/deploy.mk | 0 scripts/make-rules/gen.mk | 0 scripts/make-rules/golang.mk | 0 scripts/make-rules/image.mk | 0 scripts/make-rules/release.mk | 0 scripts/make-rules/swagger.mk | 0 scripts/make-rules/tools.mk | 0 18 files changed, 358 insertions(+), 17 deletions(-) create mode 100644 Make rename {utils => pkg}/version/version.go (100%) rename {utils => pkg}/version/version_test.go (100%) rename {hack => scripts}/LICENSE_TEMPLATE (100%) rename {hack => scripts}/boilerplate.go.txt (100%) rename {hack => scripts}/build.sh (100%) create mode 100644 scripts/make-rules/ca.mk create mode 100644 scripts/make-rules/common.mk create mode 100644 scripts/make-rules/copyright.mk create mode 100644 scripts/make-rules/dependencies.mk create mode 100644 scripts/make-rules/deploy.mk create mode 100644 scripts/make-rules/gen.mk create mode 100644 scripts/make-rules/golang.mk create mode 100644 scripts/make-rules/image.mk create mode 100644 scripts/make-rules/release.mk create mode 100644 scripts/make-rules/swagger.mk create mode 100644 scripts/make-rules/tools.mk diff --git a/Make b/Make new file mode 100644 index 00000000000..7ee04ba118b --- /dev/null +++ b/Make @@ -0,0 +1,192 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Help by default, even if it's not first +.DEFAULT_GOAL := help + +.PHONY: all +all: tidy gen add-copyright format lint cover build + +# ============================================================================== +# Build options + +ROOT_PACKAGE=github.com/sealerio/sealer +VERSION_PACKAGE=github.com/sealerio/sealer/pkg/version + +# ============================================================================== +# Includes + +include scripts/make-rules/common.mk # make sure include common.mk at the first include line +include scripts/make-rules/golang.mk +include scripts/make-rules/image.mk +include scripts/make-rules/deploy.mk +include scripts/make-rules/copyright.mk +include scripts/make-rules/gen.mk +include scripts/make-rules/ca.mk +include scripts/make-rules/release.mk +include scripts/make-rules/swagger.mk +include scripts/make-rules/dependencies.mk +include scripts/make-rules/tools.mk + +# ============================================================================== +# Usage + +define USAGE_OPTIONS + +Options: + DEBUG Whether to generate debug symbols. Default is 0. + BINS The binaries to build. Default is all of cmd. + This option is available when using: make build/build.multiarch + Example: make build BINS="iam-apiserver iam-authz-server" + IMAGES Backend images to make. Default is all of cmd starting with iam-. + This option is available when using: make image/image.multiarch/push/push.multiarch + Example: make image.multiarch IMAGES="iam-apiserver iam-authz-server" + REGISTRY_PREFIX Docker registry prefix. Default is marmotedu. + Example: make push REGISTRY_PREFIX=ccr.ccs.tencentyun.com/marmotedu VERSION=v1.6.2 + PLATFORMS The multiple platforms to build. Default is linux_amd64 and linux_arm64. + This option is available when using: make build.multiarch/image.multiarch/push.multiarch + Example: make image.multiarch IMAGES="iam-apiserver iam-pump" PLATFORMS="linux_amd64 linux_arm64" + VERSION The version information compiled into binaries. + The default is obtained from gsemver or git. + V Set to 1 enable verbose build. Default is 0. +endef +export USAGE_OPTIONS + +# ============================================================================== +# Targets + +Dirs=$(shell ls) + +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifneq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif + + +fmt: ## Run go fmt against code. + go fmt ./... + +## vet: Run go vet against code. +vet: + go vet ./... + +## lint: Run go lint against code. +lint: + golangci-lint run -v ./... + +## style: code style: fmt,vet,lint +style: fmt vet lint + +## build: Build binaries by default +build: clean + @echo "build sealer and seautil bin" + scripts/build.sh + +## linux: Build binaries for linux +linux: clean + @echo "build sealer and seautil bin for linux" + GOOS=linux GOARCH=amd64 hack/build.sh $(GitTag) + +## linux-arm64: build binaries for linux +linux-arm64: clean + @echo "build sealer and seautil bin for linux" + GOOS=linux GOARCH=arm64 hack/build.sh $(GitTag) + +# sealer should be compiled in linux platform, otherwise there will be GraphDriver problem. +build-in-docker: + docker run --rm -v ${PWD}:/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux + +test-sealer: + @echo "run e2e test for sealer bin" + hack/test-sealer.sh + +clean: ## clean + @rm -rf _output + +install-addlicense: ## check license if not exist install addlicense tools +ifeq (, $(shell which addlicense)) + @{ \ + set -e ;\ + LICENSE_TMP_DIR=$$(mktemp -d) ;\ + cd $$LICENSE_TMP_DIR ;\ + go mod init tmp ;\ + go get -v github.com/google/addlicense ;\ + rm -rf $$LICENSE_TMP_DIR ;\ + } +ADDLICENSE_BIN=$(GOBIN)/addlicense +else +ADDLICENSE_BIN=$(shell which addlicense) +endif + +filelicense: SHELL:=/bin/bash +filelicense: ## add license + for file in ${Dirs} ; do \ + if [[ $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' ]]; then \ + $(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "Alibaba Group Holding Ltd." -f hack/LICENSE_TEMPLATE ./$$file ; \ + fi \ + done + + +install-gosec: ## check license if not exist install addlicense tools +ifeq (, $(shell which gosec)) + @{ \ + set -e ;\ + curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(GOBIN) v2.2.0 ;\ + } +GOSEC_BIN=$(GOBIN)/gosec +else +GOSEC_BIN=$(shell which gosec) +endif + +gosec: install-gosec + $(GOSEC_BIN) ./... + + +install-deepcopy-gen: +ifeq (, $(shell which deepcopy-gen)) + @{ \ + set -e ;\ + LICENSE_TMP_DIR=$$(mktemp -d) ;\ + cd $$LICENSE_TMP_DIR ;\ + go mod init tmp ;\ + go get -v k8s.io/code-generator/cmd/deepcopy-gen ;\ + rm -rf $$LICENSE_TMP_DIR ;\ + } +DEEPCOPY_BIN=$(GOBIN)/deepcopy-gen +else +DEEPCOPY_BIN=$(shell which deepcopy-gen) +endif + +HEAD_FILE := scripts/boilerplate.go.txt +INPUT_DIR := github.com/sealerio/sealer/types/api +deepcopy:install-deepcopy-gen + $(DEEPCOPY_BIN) \ + --input-dirs="$(INPUT_DIR)/v1" \ + -O zz_generated.deepcopy \ + --go-header-file "$(HEAD_FILE)" \ + --output-base "${GOPATH}/src" + $(DEEPCOPY_BIN) \ + --input-dirs="$(INPUT_DIR)/v2" \ + -O zz_generated.deepcopy \ + --go-header-file "$(HEAD_FILE)" \ + --output-base "${GOPATH}/src" + +## help: Show this help info. +.PHONY: help +help: Makefile + @printf "\nUsage: make ...\n\nTargets:\n" + @sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /' + @echo "$$USAGE_OPTIONS" \ No newline at end of file diff --git a/Makefile b/Makefile index 399df64f453..509dc5e5be2 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,77 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Help by default, even if it's not first .DEFAULT_GOAL := help +.PHONY: all +all: tidy gen add-copyright format lint cover build + +# ============================================================================== +# Build options + +ROOT_PACKAGE=github.com/sealerio/sealer +VERSION_PACKAGE=github.com/sealerio/sealer/pkg/version + Dirs=$(shell ls) + +# ============================================================================== +# Includes + +include scripts/make-rules/common.mk # make sure include common.mk at the first include line +include scripts/make-rules/golang.mk +include scripts/make-rules/image.mk +include scripts/make-rules/copyright.mk +include scripts/make-rules/gen.mk +include scripts/make-rules/ca.mk +include scripts/make-rules/release.mk +include scripts/make-rules/swagger.mk +include scripts/make-rules/dependencies.mk +include scripts/make-rules/tools.mk + +# ============================================================================== +# Usage + +define USAGE_OPTIONS + +Options: + DEBUG Whether to generate debug symbols. Default is 0. + + BINS The binaries to build. Default is all of cmd. + This option is available when using: make build/build.multiarch + Example: make build BINS="iam-apiserver iam-authz-server" + + IMAGES Backend images to make. Default is all of cmd starting with iam-. + This option is available when using: make image/image.multiarch/push/push.multiarch + Example: make image.multiarch IMAGES="iam-apiserver iam-authz-server" + + REGISTRY_PREFIX Docker registry prefix. Default is marmotedu. + Example: make push REGISTRY_PREFIX=ccr.ccs.tencentyun.com/marmotedu VERSION=v1.6.2 + + PLATFORMS The multiple platforms to build. Default is linux_amd64 and linux_arm64. + This option is available when using: make build.multiarch/image.multiarch/push.multiarch + Example: make image.multiarch IMAGES="iam-apiserver iam-pump" PLATFORMS="linux_amd64 linux_arm64" + + VERSION The version information compiled into binaries. + The default is obtained from gsemver or git. + + V Set to 1 enable verbose build. Default is 0. +endef +export USAGE_OPTIONS + +# ============================================================================== +# Targets GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) GOOS ?= $(shell go env GOOS) GOARCH ?= $(shell go env GOARCH) @@ -15,29 +86,28 @@ GOBIN=$(shell go env GOBIN) endif ## fmt: Run go fmt against code. +.PHONY: fmt fmt: go fmt ./... ## vet: Run go vet against code. +.PHONY: vet vet: go vet ./... ## lint: Run go lint against code. +.PHONY: lint lint: golangci-lint run -v ./... -## style: code style: fmt,vet,lint +## style: code style -> fmt,vet,lint +.PHONY: style style: fmt vet lint ## build: Build binaries by default build: clean - @echo "build sealer and seautil bin" - $(TOOLS_DIR) - -## linux: Build binaries for Linux -linux: clean - @echo "Building sealer and seautil binaries for Linux (amd64)" - GOOS=$(GOOS) GOARCH=$(GOARCH) $(TOOLS_DIR) $(GIT_TAG) + @echo "===========> build sealer and seautil bin" + @scripts/build.sh ## linux-amd64: Build binaries for Linux (amd64) linux-amd64: clean @@ -80,7 +150,7 @@ filelicense: SHELL:=/bin/bash filelicense: for file in ${Dirs} ; do \ if [[ $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' ]]; then \ - $(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "Alibaba Group Holding Ltd." -f hack/LICENSE_TEMPLATE ./$$file ; \ + $(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "Alibaba Group Holding Ltd." -f scripts/LICENSE_TEMPLATE ./$$file ; \ fi \ done @@ -116,7 +186,7 @@ else DEEPCOPY_BIN=$(shell which deepcopy-gen) endif -HEAD_FILE := hack/boilerplate.go.txt +HEAD_FILE := scripts/boilerplate.go.txt INPUT_DIR := github.com/sealerio/sealer/types/api deepcopy:install-deepcopy-gen $(DEEPCOPY_BIN) \ @@ -130,11 +200,9 @@ deepcopy:install-deepcopy-gen --go-header-file "$(HEAD_FILE)" \ --output-base "${GOPATH}/src" -## help: Display help information +## help: Show this help info. +.PHONY: help help: Makefile - @echo "" - @echo "Usage:" "\n" - @echo " make [target]" "\n" - @echo "Targets:" "\n" "" - @awk -F ':|##' '/^[^\.%\t][^\t]*:.*##/{printf " \033[36m%-20s\033[0m %s\n", $$1, $$NF}' $(MAKEFILE_LIST) | sort - @sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /' + @printf "\nUsage: make ...\n\nTargets:\n" + @sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /' + @echo "$$USAGE_OPTIONS" \ No newline at end of file diff --git a/utils/version/version.go b/pkg/version/version.go similarity index 100% rename from utils/version/version.go rename to pkg/version/version.go diff --git a/utils/version/version_test.go b/pkg/version/version_test.go similarity index 100% rename from utils/version/version_test.go rename to pkg/version/version_test.go diff --git a/hack/LICENSE_TEMPLATE b/scripts/LICENSE_TEMPLATE similarity index 100% rename from hack/LICENSE_TEMPLATE rename to scripts/LICENSE_TEMPLATE diff --git a/hack/boilerplate.go.txt b/scripts/boilerplate.go.txt similarity index 100% rename from hack/boilerplate.go.txt rename to scripts/boilerplate.go.txt diff --git a/hack/build.sh b/scripts/build.sh similarity index 100% rename from hack/build.sh rename to scripts/build.sh diff --git a/scripts/make-rules/ca.mk b/scripts/make-rules/ca.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk new file mode 100644 index 00000000000..d6022fddbc5 --- /dev/null +++ b/scripts/make-rules/common.mk @@ -0,0 +1,81 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +SHELL := /bin/bash +DIRS=$(shell ls) + +# include the common makefile +COMMON_SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) + +# ROOT_DIR: root directory of the code base +ifeq ($(origin ROOT_DIR),undefined) +ROOT_DIR := $(abspath $(shell cd $(COMMON_SELF_DIR)/../.. && pwd -P)) +endif + +# OUTPUT_DIR: The directory where the build output is stored. +ifeq ($(origin OUTPUT_DIR),undefined) +OUTPUT_DIR := $(ROOT_DIR)/_output +$(shell mkdir -p $(OUTPUT_DIR)) +endif + +# BIN_DIR: Directory where executable files are stored. +ifeq ($(origin BIN_DIR),undefined) +BIN_DIR := $(ROOT_DIR)/bin +$(shell mkdir -p $(BIN_DIR)) +endif + +# TOOLS_DIR: The directory where tools are stored for build and testing. +ifeq ($(origin TOOLS_DIR),undefined) +TOOLS_DIR := $(ROOT_DIR)/tools +$(shell mkdir -p $(TOOLS_DIR)) +endif + +# TMP_DIR: directory where temporary files are stored. +ifeq ($(origin TMP_DIR),undefined) +TMP_DIR := $(ROOT_DIR)/tmp +$(shell mkdir -p $(TMP_DIR)) +endif + +ifeq ($(origin VERSION), undefined) +VERSION := $(shell git describe --abbrev=0 --dirty --always --tags | sed 's/-/./g') +endif + +# platforms: The OS must be linux when building docker images +PLATFORMS ?= linux_amd64 linux_arm64 +# TODO(sealer?): The OS can be linux/windows/darwin when building binaries? if only support linux +# PLATFORMS ?= darwin_amd64 windows_amd64 linux_amd64 linux_arm64 +GOOS=linux + +# set a specific PLATFORM, defaults to the host platform +ifeq ($(origin PLATFORM), undefined) + ifeq ($(origin GOARCH), undefined) + GOARCH := $(shell go env GOARCH) + endif + ifeq ($(origin GOARCH), undefined) + GOARCH := $(shell go env GOARCH) + endif + PLATFORM := $(GOOS)_$(GOARCH) + # Use linux as the default OS when building images + IMAGE_PLAT := linux_$(GOARCH) +else + # such as: PLATFORM = linux_amd64 + GOOS := $(word 1, $(subst _, ,$(PLATFORM))) + GOARCH := $(word 2, $(subst _, ,$(PLATFORM))) + IMAGE_PLAT := $(PLATFORM) +endif + + +# Linux command settings +CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/test $(ROOT_DIR)/staging +FIND := find $(CODE_DIRS) diff --git a/scripts/make-rules/copyright.mk b/scripts/make-rules/copyright.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/make-rules/dependencies.mk b/scripts/make-rules/dependencies.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/make-rules/deploy.mk b/scripts/make-rules/deploy.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/make-rules/gen.mk b/scripts/make-rules/gen.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/make-rules/image.mk b/scripts/make-rules/image.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/make-rules/release.mk b/scripts/make-rules/release.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/make-rules/swagger.mk b/scripts/make-rules/swagger.mk new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/make-rules/tools.mk b/scripts/make-rules/tools.mk new file mode 100644 index 00000000000..e69de29bb2d From 5f1da7523c37612d2b9e29525eab69317f50ca76 Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Tue, 28 Mar 2023 13:49:38 +0800 Subject: [PATCH 02/12] save makefile --- scripts/make-rules/common.mk | 26 ++++++++++++++++++++++++-- scripts/make-rules/gen.mk | 23 +++++++++++++++++++++++ {pkg => utils}/version/version.go | 0 {pkg => utils}/version/version_test.go | 0 4 files changed, 47 insertions(+), 2 deletions(-) rename {pkg => utils}/version/version.go (100%) rename {pkg => utils}/version/version_test.go (100%) diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk index d6022fddbc5..ca6570d3422 100644 --- a/scripts/make-rules/common.mk +++ b/scripts/make-rules/common.mk @@ -14,6 +14,10 @@ SHELL := /bin/bash DIRS=$(shell ls) +DEBUG ?= 0 +GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) +GIT_COMMIT ?= $(shell git rev-parse --short HEAD || echo "0.0.0") +BUILD_DATE=$(shell date +%FT%T%z) # include the common makefile COMMON_SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) @@ -25,13 +29,13 @@ endif # OUTPUT_DIR: The directory where the build output is stored. ifeq ($(origin OUTPUT_DIR),undefined) -OUTPUT_DIR := $(ROOT_DIR)/_output +OUTPUT_DIR := $(ROOT_DIR)/dist $(shell mkdir -p $(OUTPUT_DIR)) endif # BIN_DIR: Directory where executable files are stored. ifeq ($(origin BIN_DIR),undefined) -BIN_DIR := $(ROOT_DIR)/bin +BIN_DIR := $(ROOT_DIR)/out_put $(shell mkdir -p $(BIN_DIR)) endif @@ -75,7 +79,25 @@ else IMAGE_PLAT := $(PLATFORM) endif +# Linux command settings +# TODO: Whether you need to join utils? +FIND := find . ! -path './utils/*' ! -path './vendor/*' +XARGS := xargs -r +# CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/test $(ROOT_DIR)/build +# FIND := find $(CODE_DIRS) # Linux command settings CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/test $(ROOT_DIR)/staging FIND := find $(CODE_DIRS) + +# Makefile settings: Select different behaviors by determining whether V option is set +ifeq ($(origin V), undefined) # ifndef V +MAKEFLAGS += --no-print-directory +endif + +# COMMA: Concatenate multiple strings to form a list of strings +COMMA := , +# SPACE: Used to separate strings +SPACE := +# SPACE: Replace multiple consecutive Spaces with a single space +SPACE += \ No newline at end of file diff --git a/scripts/make-rules/gen.mk b/scripts/make-rules/gen.mk index e69de29bb2d..f0c1821bfab 100644 --- a/scripts/make-rules/gen.mk +++ b/scripts/make-rules/gen.mk @@ -0,0 +1,23 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================== +# Makefile helper functions for generate necessary files +# + +.PHONY: gen.run +#gen.run: gen.errcode gen.docgo +gen.run: gen.clean gen.deepcopy gen.docs + +INPUT_DIR := $(ROOT_DIR)/types/api \ No newline at end of file diff --git a/pkg/version/version.go b/utils/version/version.go similarity index 100% rename from pkg/version/version.go rename to utils/version/version.go diff --git a/pkg/version/version_test.go b/utils/version/version_test.go similarity index 100% rename from pkg/version/version_test.go rename to utils/version/version_test.go From b0b7efa98fff11e996b051599c5e5d3800fc5631 Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Tue, 28 Mar 2023 14:35:59 +0800 Subject: [PATCH 03/12] save makefile makefile:What is needed to preserve it save makefile add makefile go.build as dirty Add the images and copyright portions of the makefile Clear the output directory to tools.clean add help info for samll makefile Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> The help information is built End help, Color and case Complete the makefile tools section Finish implementing the code generator Initialize Initialize the contributor file Remove some irrelevant directories Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- .gitignore | 6 + Make | 192 ---------------------------- Makefile | 150 +++++++++------------- build/buildimage/differ.go | 10 +- build/kubefile/command/command.go | 4 +- cmd/sealer/cmd/image/build.go | 2 +- cmd/sealer/cmd/root.go | 2 +- cmd/sealer/cmd/version.go | 2 +- cmd/seautil/cmd/version.go | 2 +- pkg/checker/node_checker.go | 2 +- {version => pkg/version}/base.go | 0 {version => pkg/version}/types.go | 0 {version => pkg/version}/version.go | 0 scripts/build.sh | 3 +- scripts/coverage.awk | 13 ++ scripts/make-rules/ca.mk | 0 scripts/make-rules/common.mk | 85 ++++++++++-- scripts/make-rules/copyright.mk | 93 ++++++++++++++ scripts/make-rules/dependencies.mk | 36 ++++++ scripts/make-rules/deploy.mk | 0 scripts/make-rules/gen.mk | 88 ++++++++++++- scripts/make-rules/golang.mk | 185 +++++++++++++++++++++++++++ scripts/make-rules/image.mk | 155 ++++++++++++++++++++++ scripts/make-rules/release.mk | 0 scripts/make-rules/swagger.mk | 0 scripts/make-rules/tools.mk | 189 +++++++++++++++++++++++++++ 26 files changed, 910 insertions(+), 309 deletions(-) delete mode 100644 Make rename {version => pkg/version}/base.go (100%) rename {version => pkg/version}/types.go (100%) rename {version => pkg/version}/version.go (100%) create mode 100644 scripts/coverage.awk delete mode 100644 scripts/make-rules/ca.mk delete mode 100644 scripts/make-rules/deploy.mk delete mode 100644 scripts/make-rules/release.mk delete mode 100644 scripts/make-rules/swagger.mk diff --git a/.gitignore b/.gitignore index 407bccc2143..2d59c24af00 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,9 @@ pkg/cloud/dashboard/Cargo.lock docs/site/node_modules docs/site/package-lock.json +.vscode + +# tools is responsible for collecting sealer third party package binary tools +tools +#coverage.out +tmp diff --git a/Make b/Make deleted file mode 100644 index 7ee04ba118b..00000000000 --- a/Make +++ /dev/null @@ -1,192 +0,0 @@ -# Copyright © 2022 Alibaba Group Holding Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Help by default, even if it's not first -.DEFAULT_GOAL := help - -.PHONY: all -all: tidy gen add-copyright format lint cover build - -# ============================================================================== -# Build options - -ROOT_PACKAGE=github.com/sealerio/sealer -VERSION_PACKAGE=github.com/sealerio/sealer/pkg/version - -# ============================================================================== -# Includes - -include scripts/make-rules/common.mk # make sure include common.mk at the first include line -include scripts/make-rules/golang.mk -include scripts/make-rules/image.mk -include scripts/make-rules/deploy.mk -include scripts/make-rules/copyright.mk -include scripts/make-rules/gen.mk -include scripts/make-rules/ca.mk -include scripts/make-rules/release.mk -include scripts/make-rules/swagger.mk -include scripts/make-rules/dependencies.mk -include scripts/make-rules/tools.mk - -# ============================================================================== -# Usage - -define USAGE_OPTIONS - -Options: - DEBUG Whether to generate debug symbols. Default is 0. - BINS The binaries to build. Default is all of cmd. - This option is available when using: make build/build.multiarch - Example: make build BINS="iam-apiserver iam-authz-server" - IMAGES Backend images to make. Default is all of cmd starting with iam-. - This option is available when using: make image/image.multiarch/push/push.multiarch - Example: make image.multiarch IMAGES="iam-apiserver iam-authz-server" - REGISTRY_PREFIX Docker registry prefix. Default is marmotedu. - Example: make push REGISTRY_PREFIX=ccr.ccs.tencentyun.com/marmotedu VERSION=v1.6.2 - PLATFORMS The multiple platforms to build. Default is linux_amd64 and linux_arm64. - This option is available when using: make build.multiarch/image.multiarch/push.multiarch - Example: make image.multiarch IMAGES="iam-apiserver iam-pump" PLATFORMS="linux_amd64 linux_arm64" - VERSION The version information compiled into binaries. - The default is obtained from gsemver or git. - V Set to 1 enable verbose build. Default is 0. -endef -export USAGE_OPTIONS - -# ============================================================================== -# Targets - -Dirs=$(shell ls) - -# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) -ifneq (,$(shell go env GOBIN)) -GOBIN=$(shell go env GOPATH)/bin -else -GOBIN=$(shell go env GOBIN) -endif - - -fmt: ## Run go fmt against code. - go fmt ./... - -## vet: Run go vet against code. -vet: - go vet ./... - -## lint: Run go lint against code. -lint: - golangci-lint run -v ./... - -## style: code style: fmt,vet,lint -style: fmt vet lint - -## build: Build binaries by default -build: clean - @echo "build sealer and seautil bin" - scripts/build.sh - -## linux: Build binaries for linux -linux: clean - @echo "build sealer and seautil bin for linux" - GOOS=linux GOARCH=amd64 hack/build.sh $(GitTag) - -## linux-arm64: build binaries for linux -linux-arm64: clean - @echo "build sealer and seautil bin for linux" - GOOS=linux GOARCH=arm64 hack/build.sh $(GitTag) - -# sealer should be compiled in linux platform, otherwise there will be GraphDriver problem. -build-in-docker: - docker run --rm -v ${PWD}:/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux - -test-sealer: - @echo "run e2e test for sealer bin" - hack/test-sealer.sh - -clean: ## clean - @rm -rf _output - -install-addlicense: ## check license if not exist install addlicense tools -ifeq (, $(shell which addlicense)) - @{ \ - set -e ;\ - LICENSE_TMP_DIR=$$(mktemp -d) ;\ - cd $$LICENSE_TMP_DIR ;\ - go mod init tmp ;\ - go get -v github.com/google/addlicense ;\ - rm -rf $$LICENSE_TMP_DIR ;\ - } -ADDLICENSE_BIN=$(GOBIN)/addlicense -else -ADDLICENSE_BIN=$(shell which addlicense) -endif - -filelicense: SHELL:=/bin/bash -filelicense: ## add license - for file in ${Dirs} ; do \ - if [[ $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' ]]; then \ - $(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "Alibaba Group Holding Ltd." -f hack/LICENSE_TEMPLATE ./$$file ; \ - fi \ - done - - -install-gosec: ## check license if not exist install addlicense tools -ifeq (, $(shell which gosec)) - @{ \ - set -e ;\ - curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(GOBIN) v2.2.0 ;\ - } -GOSEC_BIN=$(GOBIN)/gosec -else -GOSEC_BIN=$(shell which gosec) -endif - -gosec: install-gosec - $(GOSEC_BIN) ./... - - -install-deepcopy-gen: -ifeq (, $(shell which deepcopy-gen)) - @{ \ - set -e ;\ - LICENSE_TMP_DIR=$$(mktemp -d) ;\ - cd $$LICENSE_TMP_DIR ;\ - go mod init tmp ;\ - go get -v k8s.io/code-generator/cmd/deepcopy-gen ;\ - rm -rf $$LICENSE_TMP_DIR ;\ - } -DEEPCOPY_BIN=$(GOBIN)/deepcopy-gen -else -DEEPCOPY_BIN=$(shell which deepcopy-gen) -endif - -HEAD_FILE := scripts/boilerplate.go.txt -INPUT_DIR := github.com/sealerio/sealer/types/api -deepcopy:install-deepcopy-gen - $(DEEPCOPY_BIN) \ - --input-dirs="$(INPUT_DIR)/v1" \ - -O zz_generated.deepcopy \ - --go-header-file "$(HEAD_FILE)" \ - --output-base "${GOPATH}/src" - $(DEEPCOPY_BIN) \ - --input-dirs="$(INPUT_DIR)/v2" \ - -O zz_generated.deepcopy \ - --go-header-file "$(HEAD_FILE)" \ - --output-base "${GOPATH}/src" - -## help: Show this help info. -.PHONY: help -help: Makefile - @printf "\nUsage: make ...\n\nTargets:\n" - @sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /' - @echo "$$USAGE_OPTIONS" \ No newline at end of file diff --git a/Makefile b/Makefile index 509dc5e5be2..1e260029b8a 100644 --- a/Makefile +++ b/Makefile @@ -12,19 +12,27 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Help by default, even if it's not first +# ============================================================================== +# define the default goal +# + .DEFAULT_GOAL := help .PHONY: all all: tidy gen add-copyright format lint cover build # ============================================================================== -# Build options +# Build set ROOT_PACKAGE=github.com/sealerio/sealer VERSION_PACKAGE=github.com/sealerio/sealer/pkg/version Dirs=$(shell ls) +GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) +GOOS ?= $(shell go env GOOS) +GOARCH ?= $(shell go env GOARCH) + +BUILD_SCRIPTS := scripts/build.sh # ============================================================================== # Includes @@ -34,9 +42,6 @@ include scripts/make-rules/golang.mk include scripts/make-rules/image.mk include scripts/make-rules/copyright.mk include scripts/make-rules/gen.mk -include scripts/make-rules/ca.mk -include scripts/make-rules/release.mk -include scripts/make-rules/swagger.mk include scripts/make-rules/dependencies.mk include scripts/make-rules/tools.mk @@ -46,25 +51,16 @@ include scripts/make-rules/tools.mk define USAGE_OPTIONS Options: - DEBUG Whether to generate debug symbols. Default is 0. - - BINS The binaries to build. Default is all of cmd. - This option is available when using: make build/build.multiarch - Example: make build BINS="iam-apiserver iam-authz-server" - - IMAGES Backend images to make. Default is all of cmd starting with iam-. - This option is available when using: make image/image.multiarch/push/push.multiarch - Example: make image.multiarch IMAGES="iam-apiserver iam-authz-server" - REGISTRY_PREFIX Docker registry prefix. Default is marmotedu. - Example: make push REGISTRY_PREFIX=ccr.ccs.tencentyun.com/marmotedu VERSION=v1.6.2 + DEBUG Whether or not to generate debug symbols. Default is 0. - PLATFORMS The multiple platforms to build. Default is linux_amd64 and linux_arm64. - This option is available when using: make build.multiarch/image.multiarch/push.multiarch - Example: make image.multiarch IMAGES="iam-apiserver iam-pump" PLATFORMS="linux_amd64 linux_arm64" + BINS Binaries to build. Default is all binaries under cmd. + This option is available when using: make {build}(.multiarch) + Example: make build BINS="sealer sealctl" - VERSION The version information compiled into binaries. - The default is obtained from gsemver or git. + PLATFORMS Platform to build for. Default is linux_arm64 and linux_amd64. + This option is available when using: make {build}.multiarch + Example: make build.multiarch PLATFORMS="linux_arm64 linux_amd64" V Set to 1 enable verbose build. Default is 0. endef @@ -72,18 +68,11 @@ export USAGE_OPTIONS # ============================================================================== # Targets -GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) -GOOS ?= $(shell go env GOOS) -GOARCH ?= $(shell go env GOARCH) - -TOOLS_DIR := hack/build.sh -# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) -ifneq (,$(shell go env GOBIN)) -GOBIN=$(shell go env GOPATH)/bin -else -GOBIN=$(shell go env GOBIN) -endif +## build: Build binaries by default +.PHONY: build +build: clean + @$(MAKE) go.build ## fmt: Run go fmt against code. .PHONY: fmt @@ -104,76 +93,47 @@ lint: .PHONY: style style: fmt vet lint -## build: Build binaries by default -build: clean - @echo "===========> build sealer and seautil bin" - @scripts/build.sh - ## linux-amd64: Build binaries for Linux (amd64) linux-amd64: clean @echo "Building sealer and seautil binaries for Linux (amd64)" - GOOS=linux GOARCH=amd64 $(TOOLS_DIR) $(GIT_TAG) + @GOOS=linux GOARCH=amd64 $(BUILD_SCRIPTS) $(GIT_TAG) ## linux-arm64: Build binaries for Linux (arm64) linux-arm64: clean @echo "Building sealer and seautil binaries for Linux (arm64)" - GOOS=linux GOARCH=arm64 $(TOOLS_DIR) $(GIT_TAG) + @GOOS=linux GOARCH=arm64 $(BUILD_SCRIPTS) $(GIT_TAG) ## build-in-docker: sealer should be compiled in linux platform, otherwise there will be GraphDriver problem. build-in-docker: - docker run --rm -v ${PWD}:/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux + @docker run --rm -v ${PWD}:/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux -## clean: Remove all files that are created by building. -.PHONY: clean -clean: - @echo "===========> Cleaning all build output" - @-rm -rf _output +## gen: Generate all necessary files. +.PHONY: gen +gen: + @$(MAKE) gen.run -## install-addlicense: check license if not exist install addlicense tools -install-addlicense: -ifeq (, $(shell which addlicense)) - @{ \ - set -e ;\ - LICENSE_TMP_DIR=$$(mktemp -d) ;\ - cd $$LICENSE_TMP_DIR ;\ - go mod init tmp ;\ - go get -v github.com/google/addlicense ;\ - rm -rf $$LICENSE_TMP_DIR ;\ - } -ADDLICENSE_BIN=$(GOBIN)/addlicense -else -ADDLICENSE_BIN=$(shell which addlicense) -endif +## verify-copyright: Verify the license headers for all files. +.PHONY: verify-copyright +verify-license: + @$(MAKE) copyright.verify -filelicense: SHELL:=/bin/bash -## filelicense: add license -filelicense: - for file in ${Dirs} ; do \ - if [[ $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' ]]; then \ - $(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "Alibaba Group Holding Ltd." -f scripts/LICENSE_TEMPLATE ./$$file ; \ - fi \ - done - - -## install-gosec: check license if not exist install addlicense tools -install-gosec: -ifeq (, $(shell which gosec)) - @{ \ - set -e ;\ - curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(GOBIN) v2.2.0 ;\ - } -GOSEC_BIN=$(GOBIN)/gosec -else -GOSEC_BIN=$(shell which gosec) -endif +## add-copyright: Add copyright ensure source code files have license headers. +.PHONY: add-copyright +add-license: + @$(MAKE) copyright.add gosec: install-gosec $(GOSEC_BIN) ./... +## tools: Install dependent tools. +.PHONY: tools +tools: + @$(MAKE) tools.install +## install-deepcopy-gen: check license if not exist install deepcopy-gen tools. install-deepcopy-gen: ifeq (, $(shell which deepcopy-gen)) - @{ \ + { \ set -e ;\ LICENSE_TMP_DIR=$$(mktemp -d) ;\ cd $$LICENSE_TMP_DIR ;\ @@ -186,23 +146,33 @@ else DEEPCOPY_BIN=$(shell which deepcopy-gen) endif -HEAD_FILE := scripts/boilerplate.go.txt -INPUT_DIR := github.com/sealerio/sealer/types/api -deepcopy:install-deepcopy-gen +# BOILERPLATE := scripts/boilerplate.go.txt +# INPUT_DIR := github.com/sealerio/sealer/types/api + +## deepcopy: generate deepcopy code. +deepcopy: install-deepcopy-gen $(DEEPCOPY_BIN) \ --input-dirs="$(INPUT_DIR)/v1" \ -O zz_generated.deepcopy \ - --go-header-file "$(HEAD_FILE)" \ + --go-header-file "$(BOILERPLATE)" \ --output-base "${GOPATH}/src" $(DEEPCOPY_BIN) \ --input-dirs="$(INPUT_DIR)/v2" \ -O zz_generated.deepcopy \ - --go-header-file "$(HEAD_FILE)" \ + --go-header-file "$(BOILERPLATE)" \ --output-base "${GOPATH}/src" +## clean: Remove all files that are created by building. +.PHONY: clean +clean: + @$(MAKE) go.clean + ## help: Show this help info. .PHONY: help help: Makefile - @printf "\nUsage: make ...\n\nTargets:\n" - @sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /' - @echo "$$USAGE_OPTIONS" \ No newline at end of file + $(call makehelp) + +## all-help: Show all help details info. +.PHONY: all-help +all-help: go.help copyright.help tools.help image.help help + $(call makeallhelp) \ No newline at end of file diff --git a/build/buildimage/differ.go b/build/buildimage/differ.go index 40b89e3c5eb..11c39236967 100644 --- a/build/buildimage/differ.go +++ b/build/buildimage/differ.go @@ -37,7 +37,7 @@ import ( osi "github.com/sealerio/sealer/utils/os" ) -// TODO: update the variable name +// TODO: update the variable name. var ( copyToManifests = "manifests" copyToChart = "charts" @@ -45,8 +45,10 @@ var ( copyToApplication = "application" ) -type parseContainerImageStringSliceFunc func(srcPath string) ([]string, error) -type parseContainerImageListFunc func(srcPath string) ([]*v12.ContainerImage, error) +type ( + parseContainerImageStringSliceFunc func(srcPath string) ([]string, error) + parseContainerImageListFunc func(srcPath string) ([]*v12.ContainerImage, error) +) var parseContainerImageStringSliceFuncMap = map[string]func(srcPath string) ([]string, error){ copyToManifests: parseYamlImages, @@ -274,7 +276,6 @@ func parseApplicationKubeImages(kubePath string) ([]string, error) { } ima, err := imageSearcher.ListImages(path) - if err != nil { return err } @@ -351,7 +352,6 @@ func parseYamlImages(srcPath string) ([]string, error) { } ima, err := imageSearcher.ListImages(path) - if err != nil { return err } diff --git a/build/kubefile/command/command.go b/build/kubefile/command/command.go index e14338dc60c..c9dc3dff3de 100644 --- a/build/kubefile/command/command.go +++ b/build/kubefile/command/command.go @@ -40,7 +40,7 @@ const ( // Deprecated Cmd = "cmd" - // the following commands are the intenal implementations for kube commands + // the following commands are the intenal implementations for kube commands. Add = "add" Arg = "arg" Copy = "copy" @@ -59,7 +59,7 @@ var ( LabelKubeCSIPrefix = fmt.Sprintf("%s-", LabelSupportedKubeCSIAlpha) ) -// SupportedCommands is list of all Kubefile commands +// SupportedCommands is list of all Kubefile commands. var SupportedCommands = map[string]struct{}{ Add: {}, Arg: {}, diff --git a/cmd/sealer/cmd/image/build.go b/cmd/sealer/cmd/image/build.go index dcbbea1720a..b4d6afed432 100644 --- a/cmd/sealer/cmd/image/build.go +++ b/cmd/sealer/cmd/image/build.go @@ -28,11 +28,11 @@ import ( "github.com/sealerio/sealer/pkg/imageengine" "github.com/sealerio/sealer/pkg/imageengine/buildah" "github.com/sealerio/sealer/pkg/rootfs" + "github.com/sealerio/sealer/pkg/version" v1 "github.com/sealerio/sealer/types/api/v1" osi "github.com/sealerio/sealer/utils/os" "github.com/sealerio/sealer/utils/strings" "github.com/sealerio/sealer/utils/yaml" - "github.com/sealerio/sealer/version" "github.com/containerd/containerd/platforms" "github.com/containers/buildah/define" diff --git a/cmd/sealer/cmd/root.go b/cmd/sealer/cmd/root.go index 4bc0389d2f9..d9c2233d6df 100644 --- a/cmd/sealer/cmd/root.go +++ b/cmd/sealer/cmd/root.go @@ -28,7 +28,7 @@ import ( "github.com/sealerio/sealer/cmd/sealer/cmd/image" "github.com/sealerio/sealer/common" "github.com/sealerio/sealer/pkg/logger" - "github.com/sealerio/sealer/version" + "github.com/sealerio/sealer/pkg/version" ) type rootOpts struct { diff --git a/cmd/sealer/cmd/version.go b/cmd/sealer/cmd/version.go index d22c8701657..bf9fcea467a 100644 --- a/cmd/sealer/cmd/version.go +++ b/cmd/sealer/cmd/version.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" - "github.com/sealerio/sealer/version" + "github.com/sealerio/sealer/pkg/version" ) var shortPrint bool diff --git a/cmd/seautil/cmd/version.go b/cmd/seautil/cmd/version.go index 68f3140d948..c8ce73419cf 100644 --- a/cmd/seautil/cmd/version.go +++ b/cmd/seautil/cmd/version.go @@ -22,7 +22,7 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/sealerio/sealer/version" + "github.com/sealerio/sealer/pkg/version" ) var shortPrint bool diff --git a/pkg/checker/node_checker.go b/pkg/checker/node_checker.go index 992e8571065..2b9648baba2 100644 --- a/pkg/checker/node_checker.go +++ b/pkg/checker/node_checker.go @@ -88,7 +88,7 @@ func (n *NodeChecker) Check(cluster *v2.Cluster, phase string) error { } func (n *NodeChecker) Output(nodeCLusterStatus NodeClusterStatus) error { - //t1, err := template.ParseFiles("templates/node_checker.tpl") + // t1, err := template.ParseFiles("templates/node_checker.tpl") t := template.New("node_checker") t, err := t.Parse( `Cluster Node Status diff --git a/version/base.go b/pkg/version/base.go similarity index 100% rename from version/base.go rename to pkg/version/base.go diff --git a/version/types.go b/pkg/version/types.go similarity index 100% rename from version/types.go rename to pkg/version/types.go diff --git a/version/version.go b/pkg/version/version.go similarity index 100% rename from version/version.go rename to pkg/version/version.go diff --git a/scripts/build.sh b/scripts/build.sh index 76c0c8958fe..c0112a2dce1 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -65,7 +65,7 @@ ldflags() { "-X '${SEALER_GO_PACKAGE}/version.${key}=${val}'" ) } - add_ldflag "buildDate" "$(date "+%F %T")" + add_ldflag "buildDate" "$(date "+%FT %T %z")" if [[ -n ${GIT_COMMIT-} ]]; then add_ldflag "gitCommit" "${GIT_COMMIT}" fi @@ -140,4 +140,3 @@ if [[ $MULTI_PLATFORM_BUILD ]]; then else build_binaries `go env GOOS` `go env GOARCH` fi - diff --git a/scripts/coverage.awk b/scripts/coverage.awk new file mode 100644 index 00000000000..49389054e2d --- /dev/null +++ b/scripts/coverage.awk @@ -0,0 +1,13 @@ +#!/usr/bin/env awk + +{ + print $0 + if (match($0, /^total:/)) { + sub(/%/, "", $NF); + printf("test coverage is %s%(quality gate is %s%)\n", $NF, target) + if (strtonum($NF) < target) { + printf("test coverage does not meet expectations: %d%, please add test cases!\n", target) + exit 1; + } + } +} diff --git a/scripts/make-rules/ca.mk b/scripts/make-rules/ca.mk deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk index ca6570d3422..3ed7650e47b 100644 --- a/scripts/make-rules/common.mk +++ b/scripts/make-rules/common.mk @@ -12,12 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. +# ============================================================================== +# Makefile helper functions for common tasks +# + SHELL := /bin/bash DIRS=$(shell ls) DEBUG ?= 0 GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) GIT_COMMIT ?= $(shell git rev-parse --short HEAD || echo "0.0.0") -BUILD_DATE=$(shell date +%FT%T%z) +BUILD_DATE=$(shell date '+%FT %T %z') # "buildDate":"2023-03-31T 20:05:43 +0800" # include the common makefile COMMON_SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) @@ -29,13 +33,13 @@ endif # OUTPUT_DIR: The directory where the build output is stored. ifeq ($(origin OUTPUT_DIR),undefined) -OUTPUT_DIR := $(ROOT_DIR)/dist +OUTPUT_DIR := $(ROOT_DIR)/_output $(shell mkdir -p $(OUTPUT_DIR)) endif # BIN_DIR: Directory where executable files are stored. ifeq ($(origin BIN_DIR),undefined) -BIN_DIR := $(ROOT_DIR)/out_put +BIN_DIR := $(OUTPUT_DIR)/bin $(shell mkdir -p $(BIN_DIR)) endif @@ -55,10 +59,31 @@ ifeq ($(origin VERSION), undefined) VERSION := $(shell git describe --abbrev=0 --dirty --always --tags | sed 's/-/./g') endif +# Check if the tree is dirty. default to dirty(maybe u should commit?) +GIT_TREE_STATE:="dirty" +ifeq (, $(shell git status --porcelain 2>/dev/null)) + GIT_TREE_STATE="clean" +endif +GIT_COMMIT:=$(shell git rev-parse HEAD) + +# Minimum test coverage +ifeq ($(origin COVERAGE),undefined) +COVERAGE := 60 +endif + +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif + # platforms: The OS must be linux when building docker images PLATFORMS ?= linux_amd64 linux_arm64 # TODO(sealer?): The OS can be linux/windows/darwin when building binaries? if only support linux # PLATFORMS ?= darwin_amd64 windows_amd64 linux_amd64 linux_arm64 + +# only support linux GOOS=linux # set a specific PLATFORM, defaults to the host platform @@ -83,12 +108,11 @@ endif # TODO: Whether you need to join utils? FIND := find . ! -path './utils/*' ! -path './vendor/*' XARGS := xargs -r -# CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/test $(ROOT_DIR)/build -# FIND := find $(CODE_DIRS) -# Linux command settings -CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/test $(ROOT_DIR)/staging -FIND := find $(CODE_DIRS) +# Linux command settings-CODE DIRS Copyright +# $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' +CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/test $(ROOT_DIR)/build $(ROOT_DIR)/scripts $(ROOT_DIR)/utils $(ROOT_DIR)/common +FINDS := find $(CODE_DIRS) # Makefile settings: Select different behaviors by determining whether V option is set ifeq ($(origin V), undefined) # ifndef V @@ -100,4 +124,47 @@ COMMA := , # SPACE: Used to separate strings SPACE := # SPACE: Replace multiple consecutive Spaces with a single space -SPACE += \ No newline at end of file +SPACE += + + +# ============================================================================== +# Makefile helper functions for common tasks + +# Help information for the makefile package +define makehelp + @printf "\n\033[1mUsage: make ...\033[0m\n\n\\033[1mTargets:\\033[0m\n\n" + @sed -n 's/^##//p' $< | awk -F':' '{printf "\033[36m%-28s\033[0m %s\n", $$1, $$2}' | sed -e 's/^/ /' + @printf "\n\033[1m$$USAGE_OPTIONS\033[0m\n" +endef + +# Here are some examples of builds +define MAKEFILE_EXAMPLE +# make build BINS=sealer Only a single sealer binary is built +# make fmt vet lint Run code style check +# make gen Generate all necessary files +# make deepcopy Generate deepcopy code +# make verify-copyright Verify the license headers for all files +# make install-deepcopy-gen Install deepcopy-gen tools if the license is missing +# make build BINS=sealer V=1 DEBUG=1 Build debug binaries for only sealer +# make build.multiarch PLATFORMS="linux_arm64 linux_amd64" V=1 Build binaries for both platforms +endef +export MAKEFILE_EXAMPLE + +# Define all help functions @printf "\n\033[1mCurrent sealer version information: $(shell sealer version):\033[0m\n\n" +define makeallhelp + @printf "\n\033[1mMake example:\033[0m\n\n" + $(call MAKEFILE_EXAMPLE) + @printf "\n\033[1mAriables:\033[0m\n\n" + @echo " DEBUG: $(DEBUG)" + @echo " BINS: $(BINS)" + @echo " PLATFORMS: $(PLATFORMS)" + @echo " V: $(V)" +endef + +# Help information for other makefile packages +CUT_OFF?="---------------------------------------------------------------------------------" +HELP_NAME:=$(shell basename $(MAKEFILE_LIST)) +define smallhelp + @sed -n 's/^##//p' $< | awk -F':' '{printf "\033[36m%-35s\033[0m %s\n", $$1, $$2}' | sed -e 's/^/ /' + @echo $(CUT_OFF) +endef \ No newline at end of file diff --git a/scripts/make-rules/copyright.mk b/scripts/make-rules/copyright.mk index e69de29bb2d..efb829d7c3d 100644 --- a/scripts/make-rules/copyright.mk +++ b/scripts/make-rules/copyright.mk @@ -0,0 +1,93 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============================================================================== +# wget https://github.com/google/addlicense/releases/download/v1.0.0/addlicense_1.0.0_Linux_x86_64.tar.gz +# Makefile helper functions for copyright +# + +# filelicense: SHELL:=/bin/bash +# ## filelicense: add license for all files +# filelicense: +# for file in ${Dirs} ; do \ +# if [[ $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' ]]; then \ +# $(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "Alibaba Group Holding Ltd." -f scripts/LICENSE_TEMPLATE ./$$file ; \ +# fi \ +# done +# +# install-addlicense: +# ifeq (, $(shell which addlicense)) +# @{ \ +# set -e ;\ +# LICENSE_TMP_DIR=$$(mktemp -d) ;\ +# cd $$LICENSE_TMP_DIR ;\ +# go mod init tmp ;\ +# go get -v github.com/google/addlicense ;\ +# rm -rf $$LICENSE_TMP_DIR ;\ +# } +# ADDLICENSE_BIN=$(GOBIN)/addlicense +# else +# ADDLICENSE_BIN=$(shell which addlicense) +# endif +# +# ## install-gosec: check license if not exist install addlicense tools. +# install-gosec: +# ifeq (, $(shell which gosec)) +# @{ \ +# set -e ;\ +# curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(GOBIN) v2.2.0 ;\ +# } +# GOSEC_BIN=$(GOBIN)/gosec +# else +# GOSEC_BIN=$(shell which gosec) +# endif + +LICENSE_TEMPLATE ?= $(ROOT_DIR)/scripts/LICENSE_TEMPLATE + +.PHONY: copyright.verify +# TODO: GOBIN -> TOOLS_DIR +copyright.verify: tools.verify.addlicense + @echo "===========> Validate boilerplate headers for assign files starting in the $(ROOT_DIR) directory" + @$(GOBIN)/addlicense -v -check -ignore **/test/** -f $(LICENSE_TEMPLATE) $(CODE_DIRS) + @echo "===========> End of boilerplate headers check..." + +.PHONY: copyright.add +## copyright.add: Add the boilerplate headers for all files +copyright.add: tools.verify.addlicense + @echo "===========> Adding $(LICENSE_TEMPLATE) the boilerplate headers for all files" + @$(GOBIN)/addlicense -y $(shell date +"%Y") -v -c "Alibaba Group Holding Ltd." -f $(LICENSE_TEMPLATE) $(CODE_DIRS) + @echo "===========> End the copyright is added..." + +# Addlicense Flags: +# -c string +# copyright holder (default "Google LLC") +# -check +# check only mode: verify presence of license headers and exit with non-zero code if missing +# -f string +# license file +# -ignore value +# file patterns to ignore, for example: -ignore **/*.go -ignore vendor/** +# -l string +# license type: apache, bsd, mit, mpl (default "apache") +# -s Include SPDX identifier in license header. Set -s=only to only include SPDX identifier. +# -skip value +# [deprecated: see -ignore] file extensions to skip, for example: -skip rb -skip go +# -v verbose mode: print the name of the files that are modified or were skipped +# -y string +# copyright year(s) (default "2023") + +.PHONY: copyright.help +## copyright.help: Show copyright help +copyright.help: scripts/make-rules/copyright.mk + $(call smallhelp) \ No newline at end of file diff --git a/scripts/make-rules/dependencies.mk b/scripts/make-rules/dependencies.mk index e69de29bb2d..d533d082933 100644 --- a/scripts/make-rules/dependencies.mk +++ b/scripts/make-rules/dependencies.mk @@ -0,0 +1,36 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================== +# Makefile helper functions for dependencies +# + +.PHONY: dependencies.run +dependencies.run: dependencies.packages dependencies.tools + +.PHONY: dependencies.packages +dependencies.packages: + @$(GO) mod tidy + +.PHONY: dependencies.tools +dependencies.tools: dependencies.tools.blocker dependencies.tools.critical + +.PHONY: dependencies.tools.blocker +dependencies.tools.blocker: go.build.verify $(addprefix tools.verify., $(BLOCKER_TOOLS)) + +.PHONY: dependencies.tools.critical +dependencies.tools.critical: $(addprefix tools.verify., $(CRITICAL_TOOLS)) + +.PHONY: dependencies.tools.trivial +dependencies.tools.trivial: $(addprefix tools.verify., $(TRIVIAL_TOOLS)) \ No newline at end of file diff --git a/scripts/make-rules/deploy.mk b/scripts/make-rules/deploy.mk deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/make-rules/gen.mk b/scripts/make-rules/gen.mk index f0c1821bfab..2fcf79bdae2 100644 --- a/scripts/make-rules/gen.mk +++ b/scripts/make-rules/gen.mk @@ -13,11 +13,91 @@ # limitations under the License. # ============================================================================== -# Makefile helper functions for generate necessary files +# Makefile helper functions for generate necessary files and docs +# https://cloud.redhat.com/blog/kubernetes-deep-dive-code-generation-customresources +# ! The stock of code generated by `make gen` should be idempotent # +## install-deepcopy-gen: check license if not exist install deepcopy-gen tools +# install-deepcopy-gen: +# ifeq (, $(shell which deepcopy-gen)) +# { \ +# set -e ;\ +# LICENSE_TMP_DIR=$$(mktemp -d) ;\ +# cd $$LICENSE_TMP_DIR ;\ +# go mod init tmp ;\ +# go get -v k8s.io/code-generator/cmd/deepcopy-gen ;\ +# rm -rf $$LICENSE_TMP_DIR ;\ +# } +# DEEPCOPY_BIN=$(GOBIN)/deepcopy-gen +# else +# DEEPCOPY_BIN=$(shell which deepcopy-gen) +# endif + +# BOILERPLATE := scripts/boilerplate.go.txt +# INPUT_DIR := github.com/sealerio/sealer/types/api + +## deepcopy: generate deepcopy code +# deepcopy: install-deepcopy-gen +# $(DEEPCOPY_BIN) \ +# --input-dirs="$(INPUT_DIR)/v1" \ +# -O zz_generated.deepcopy \ +# --go-header-file "$(BOILERPLATE)" \ +# --output-base "${GOPATH}/src" +# $(DEEPCOPY_BIN) \ +# --input-dirs="$(INPUT_DIR)/v2" \ +# -O zz_generated.deepcopy \ +# --go-header-file "$(BOILERPLATE)" \ +# --output-base "${GOPATH}/src" + +# When 'make gen.run' is executed, the previously generated files are actually cleaned up and then automatically generated separately +## gen.run: gen.deepcopy gen.docgo .PHONY: gen.run -#gen.run: gen.errcode gen.docgo -gen.run: gen.clean gen.deepcopy gen.docs +gen.run: gen.clean gen.deepcopyV1 gen.deepcopyV2 #gen.docs + +BOILERPLATE := $(ROOT_DIR)/scripts/boilerplate.go.txt + +INPUT_DIR := $(ROOT_DIR)/types/api/v1 +INPUT_DIRV2 := $(ROOT_DIR)/types/api/v2 +INPUT_DIRS := $(ROOT_PACKAGE)/types/api/v1 +INPUT_DIRSV2 := $(ROOT_PACKAGE)/types/api/v2 + +# TODO: output-base: $(ROOT_PACKAGE)/types/api/v2/...... +## gen.deepcopy: generate deepcopy v1 code +.PHONY: gen.deepcopyV1 +gen.deepcopyV1: tools.verify.deepcopy-gen + @echo "===========> Generating deepcopy go source files in $(INPUT_DIRS)" + @$(TOOLS_DIR)/deepcopy-gen \ + --input-dirs="$(INPUT_DIRS)" \ + --output-file-base zz_generated.deepcopy \ + --go-header-file "$(BOILERPLATE)" \ + --output-base "$(INPUT_DIR)" + +## gen.deepcopyV2: generate deepcopy v2 code +.PHONY: gen.deepcopyV2 +gen.deepcopyV2: tools.verify.deepcopy-gen + @echo "===========> Generating deepcopy go source files in $(INPUT_DIRSV2)" + @$(TOOLS_DIR)/deepcopy-gen \ + --input-dirs="$(INPUT_DIRSV2)" \ + --output-file-base zz_generated.deepcopy \ + --go-header-file "$(BOILERPLATE)" \ + --output-base "$()" + +## gen.docgo: generate doc.go +.PHONY: gen.docs +gen.docs: go.build + @echo "===========> Generating deep of documents use $(BIN_DIR)/$(PLATFORM)/sealer gen-doc" + @$(BIN_DIR)/$(PLATFORM)/sealer gen-doc + +## gen.clean: clean the previously generated files +.PHONY: gen.clean +gen.clean: + @echo "===========> Delete $(INPUT_DIR)..." +# @find $(INPUT_DIR) -type f -name '*_generated.*.go' -delete + @echo "===========> Delete $(INPUT_DIRS)" +# @find $(INPUT_DIRV2) -type f -name '*_generated.*.go' -delete -INPUT_DIR := $(ROOT_DIR)/types/api \ No newline at end of file +## gen.help: show help for gen +.PHONY: gen.help +gen.help: scripts/make-rules/gen.mk + $(call smallhelp) \ No newline at end of file diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index e69de29bb2d..3b7d187e0ec 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -0,0 +1,185 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================== +# Build management helpers. These functions help to set, save and load the +# + +GO := go +# ! go 1.8 some packages fail to be pulled out. You are advised to use the gvm switchover version of the tools toolkit +GO_SUPPORTED_VERSIONS ?= |1.18|1.19|1.20| + +GO_LDFLAGS += -X $(VERSION_PACKAGE).gitVersion=${GIT_TAG} \ + -X $(VERSION_PACKAGE).gitCommit=${GIT_COMMIT} \ + -X $(VERSION_PACKAGE).GitTreeState=$(GIT_TREE_STATE) \ + -X $(VERSION_PACKAGE).buildDate=${BUILD_DATE} \ + -s -w # -s -w deletes debugging information and symbol tables +# ifneq ($(DLV),) +# GO_BUILD_FLAGS += -gcflags "all=-N -l" +# LDFLAGS = "" +# endif +ifeq ($(DEBUG), 1) + GO_BUILD_FLAGS += -gcflags "all=-N -l" + GO_LDFLAGS= +endif +GO_BUILD_FLAGS += -tags "containers_image_openpgp netgo exclude_graphdriver_devicemapper static osusergo exclude_graphdriver_btrfs" -trimpath -ldflags "$(GO_LDFLAGS)" + +# ifeq ($(GOOS),windows) +# GO_OUT_EXT := .exe +# endif + +ifeq ($(ROOT_PACKAGE),) + $(error the variable ROOT_PACKAGE must be set prior to including golang.mk, ->/Makefile) +endif + +GOPATH ?= $(shell go env GOPATH) +ifeq ($(origin GOBIN), undefined) + GOBIN := $(GOPATH)/bin +endif + +# COMMANDS is Specify all files under ${ROOT_DIR}/cmd/ except those ending in.md +COMMANDS ?= $(filter-out %.md, $(wildcard ${ROOT_DIR}/cmd/*)) +ifeq (${COMMANDS},) + $(error Could not determine COMMANDS, set ROOT_DIR or run in source dir) +endif + +# BINS is the name of each file in ${COMMANDS}, excluding the directory path +# If there are no files in ${COMMANDS}, or if all files end in.md, ${BINS} will be empty +BINS ?= $(foreach cmd,${COMMANDS},$(notdir ${cmd})) +ifeq (${BINS},) + $(error Could not determine BINS, set ROOT_DIR or run in source dir) +endif + +# TODO: EXCLUDE_TESTS variable, which contains the name of the package to be excluded from the test +EXCLUDE_TESTS := github.com/sealerio/sealer/test github.com/sealerio/sealer/pkg/logger + +# ============================================================================== +# make: Nothing to be done build and build sub targets +# _output $(OUTPUT_DIR) +# ├── assets +# │ ├── sealer-unknown-linux-amd64.tar.gz +# │ ├── sealer-unknown-linux-amd64.tar.gz.sha256sum +# │ ├── seautil-unknown-linux-amd64.tar.gz +# │ └── seautil-unknown-linux-amd64.tar.gz.sha256sum +# └── bin $(BIN_DIR) +# ├── sealer +# │ └── linux_amd64 +# │ │ └── sealer +# │ └── linux_arm64 +# │ └── sealer +# └── seautil +# └── linux_amd64 +# └── seautil +# COMMAND=sealer +# PLATFORM=linux_amd64 +# OS=linux +# ARCH=amd64 +# BINS=sealer seautil +# BIN_DIR=/root/workspaces/sealer/_output/bin +# ============================================================================== + +## go.build.verify: Verify that a suitable version of Go exists +.PHONY: go.build.verify +go.build.verify: + @echo "===========> Verify that a suitable version of Go exists, current version: $(shell $(GO) version)" +ifneq ($(shell $(GO) version | grep -q -E '\bgo($(GO_SUPPORTED_VERSIONS))\b' && echo 0 || echo 1), 0) + $(error unsupported go version. Please make install one of the following supported version: '$(GO_SUPPORTED_VERSIONS)'.You can use make install. gvm to install gvm and switch to the specified version) +endif + +## go.bin.%: Verify binary for specific platform +.PHONY: go.bin.% +go.bin.%: + $(eval COMMAND := $(word 2,$(subst ., ,$*))) + $(eval PLATFORM := $(word 1,$(subst ., ,$*))) + @echo "===========> Verifying binary $(COMMAND) $(VERSION) for $(PLATFORM)" + @if [ ! -f $(BIN_DIR)/$(PLATFORM)/$(COMMAND) ]; then echo $(MAKE) go.build PLATFORM=$(PLATFORM); fi + +## go.build.%: Build binary for specific platform +.PHONY: go.build.% +go.build.%: + $(eval COMMAND := $(word 2,$(subst ., ,$*))) + $(eval PLATFORM := $(word 1,$(subst ., ,$*))) + $(eval OS := $(word 1,$(subst _, ,$(PLATFORM)))) + $(eval ARCH := $(word 2,$(subst _, ,$(PLATFORM)))) + @echo "COMMAND=$(COMMAND)" + @echo "PLATFORM=$(PLATFORM)" + @echo "OS=$(OS)" + @echo "ARCH=$(ARCH)" + @echo "BINS=$(BINS)" + @echo "BIN_DIR=$(BIN_DIR)" + @echo "===========> Building binary $(COMMAND) $(VERSION) for $(OS) $(ARCH)" + @mkdir -p $(OUTPUT_DIR)/bin/$(OS)/$(ARCH) + + @CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(OUTPUT_DIR)/bin/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_PACKAGE)/cmd/$(COMMAND) + +## go.build: Build binaries +.PHONY: go.build +go.build: go.build.verify $(addprefix go.build., $(addprefix $(PLATFORM)., $(BINS))) + @echo "COMMAND=$(COMMAND)" + @echo "PLATFORM=$(PLATFORM)" + @echo "OS=$(OS)" + @echo "ARCH=$(ARCH)" + @echo "===========> Building binary $(BINS) $(VERSION) for $(PLATFORM)" + +## go.build.multiarch: Build multi-arch binaries +.PHONY: go.build.multiarch +go.build.multiarch: go.build.verify $(foreach p,$(PLATFORMS),$(addprefix go.build., $(addprefix $(p)., $(BINS)))) + +## go.lint: Run golangci to lint source codes +.PHONY: go.lint +go.lint: tools.verify.golangci-lint + @echo "===========> Run golangci to lint source codes" + @golangci-lint run -c $(ROOT_DIR)/.golangci.yml $(ROOT_DIR)/... + +## go.test: Run unit test +.PHONY: go.test +go.test: tools.verify.go-junit-report + @echo "===========> Run unit test" +# @set -o pipefail;$(GO) test -race -cover -coverprofile=$(OUTPUT_DIR)/coverage.out \ +# -timeout=10m -shuffle=on -short -v `go list ./...|\ +# egrep -v $(subst $(SPACE),'|',$(sort $(EXCLUDE_TESTS)))` 2>&1 | \ +# tee >(go-junit-report --set-exit-code >$(OUTPUT_DIR)/report.xml) +# @sed -i '/mock_.*.go/d' $(OUTPUT_DIR)/coverage.out # remove mock_.*.go files from test coverage +# @$(GO) tool cover -html=$(OUTPUT_DIR)/coverage.out -o $(OUTPUT_DIR)/coverage.html + +## go.test.cover: Run unit test and check coverage +.PHONY: go.test.cover +go.test.cover: go.test + @$(GO) tool cover -func=$(OUTPUT_DIR)/coverage.out | \ + awk -v target=$(COVERAGE) -f $(ROOT_DIR)/scripts/coverage.awk + +## go.test.integration: Run integration test +.PHONY: go.format +go.format: tools.verify.goimports + @echo "===========> Formating codes" + @$(FIND) -type f -name '*.go' | xargs gofmt -s -w + @$(FIND) -type f -name '*.go' | xargs $(TOOLS_DIR)/goimports -l -w -local $(ROOT_PACKAGE) + @$(GO) mod edit -fmt + +## go.updates: Check for updates to go.mod dependencies +.PHONY: go.updates +go.updates: tools.verify.go-mod-outdated + @$(GO) list -u -m -json all | go-mod-outdated -update -direct + +## go.clean: Clean all builds +.PHONY: go.clean +go.clean: + @echo "===========> Cleaning all builds $(OUTPUT_DIR) and $(BIN_DIR)" + @-rm -vrf $(OUTPUT_DIR) $(BIN_DIR) + @echo "===========> End clean..." + +## copyright.help: Show copyright help +.PHONY: go.help +go.help: scripts/make-rules/golang.mk + $(call smallhelp) \ No newline at end of file diff --git a/scripts/make-rules/image.mk b/scripts/make-rules/image.mk index e69de29bb2d..35ef75db748 100644 --- a/scripts/make-rules/image.mk +++ b/scripts/make-rules/image.mk @@ -0,0 +1,155 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================== +# Makefile helper functions for docker image +# TODO: For the time being only used for compilation, it can be arm or amd, please do not delete it, it can be extended with new functions +# ============================================================================== +# Path: scripts/make-rules/image.mk +# docker registry: registry.example.com/namespace/image:tag as: registry.hub.docker.com/cubxxw/: +# + +DOCKER := docker +DOCKER_SUPPORTED_API_VERSION ?= 1.32|1.40 + +REGISTRY_PREFIX ?= cubxxw +BASE_IMAGE = centos:centos8 + +EXTRA_ARGS ?= --no-cache +_DOCKER_BUILD_EXTRA_ARGS := + +ifdef HTTP_PROXY +_DOCKER_BUILD_EXTRA_ARGS += --build-arg HTTP_PROXY=${HTTP_PROXY} +endif + +ifneq ($(EXTRA_ARGS), ) +_DOCKER_BUILD_EXTRA_ARGS += $(EXTRA_ARGS) +endif + +# Determine image files by looking into build/docker/*/Dockerfile +IMAGES_DIR ?= $(wildcard ${ROOT_DIR}/build/docker/*) +# Determine images names by stripping out the dir names +IMAGES ?= $(filter-out tools,$(foreach image,${IMAGES_DIR},$(notdir ${image}))) + +# ifeq (${IMAGES},) +# $(error Could not determine IMAGES, set ROOT_DIR or run in source dir) +# endif + +# ============================================================================== +# Image targets +# ============================================================================== + +.PHONY: image.verify +## image.verify: Verify docker version +image.verify: + $(eval API_VERSION := $(shell $(DOCKER) version | grep -E 'API version: {1,6}[0-9]' | head -n1 | awk '{print $$3} END { if (NR==0) print 0}' )) + $(eval PASS := $(shell echo "$(API_VERSION) > $(DOCKER_SUPPORTED_API_VERSION)" | bc)) + @if [ $(PASS) -ne 1 ]; then \ + $(DOCKER) -v ;\ + echo "Unsupported docker version. Docker API version should be greater than $(DOCKER_SUPPORTED_API_VERSION)"; \ + exit 1; \ + fi + +.PHONY: image.daemon.verify +## image.daemon.verify: Verify docker daemon experimental features +image.daemon.verify: + $(eval PASS := $(shell $(DOCKER) version | grep -q -E 'Experimental: {1,5}true' && echo 1 || echo 0)) + @if [ $(PASS) -ne 1 ]; then \ + echo "Experimental features of Docker daemon is not enabled. Please add \"experimental\": true in '/etc/docker/daemon.json' and then restart Docker daemon."; \ + exit 1; \ + fi + +.PHONY: image.build +## image.build: Build docker images +image.build: image.verify go.build.verify $(addprefix image.build., $(addprefix $(IMAGE_PLAT)., $(IMAGES))) + +.PHONY: image.build.multiarch +## image.build.multiarch: Build docker images for all platforms +image.build.multiarch: image.verify go.build.verify $(foreach p,$(PLATFORMS),$(addprefix image.build., $(addprefix $(p)., $(IMAGES)))) + +.PHONY: image.build.% +## image.build.%: Build docker image for a specific platform +image.build.%: go.build.% + $(eval IMAGE := $(COMMAND)) + $(eval IMAGE_PLAT := $(subst _,/,$(PLATFORM))) + @echo "===========> Building docker image $(IMAGE) $(VERSION) for $(IMAGE_PLAT)" + @mkdir -p $(TMP_DIR)/$(IMAGE) + @cat $(ROOT_DIR)/build/docker/$(IMAGE)/Dockerfile\ + | sed "s#BASE_IMAGE#$(BASE_IMAGE)#g" >$(TMP_DIR)/$(IMAGE)/Dockerfile + @cp $(OUTPUT_DIR)/platforms/$(IMAGE_PLAT)/$(IMAGE) $(TMP_DIR)/$(IMAGE)/ + @DST_DIR=$(TMP_DIR)/$(IMAGE) $(ROOT_DIR)/build/docker/$(IMAGE)/build.sh 2>/dev/null || true + $(eval BUILD_SUFFIX := $(_DOCKER_BUILD_EXTRA_ARGS) --pull -t $(REGISTRY_PREFIX)/$(IMAGE)-$(ARCH):$(VERSION) $(TMP_DIR)/$(IMAGE)) + @if [ $(shell $(GO) env GOARCH) != $(ARCH) ] ; then \ + $(MAKE) image.daemon.verify ;\ + $(DOCKER) build --platform $(IMAGE_PLAT) $(BUILD_SUFFIX) ; \ + else \ + $(DOCKER) build $(BUILD_SUFFIX) ; \ + fi + @rm -rf $(TMP_DIR)/$(IMAGE) + +.PHONY: image.push +## image.push: Push docker images +image.push: image.verify go.build.verify $(addprefix image.push., $(addprefix $(IMAGE_PLAT)., $(IMAGES))) + +.PHONY: image.push.multiarch +## image.push.multiarch: Push docker images for all platforms +image.push.multiarch: image.verify go.build.verify $(foreach p,$(PLATFORMS),$(addprefix image.push., $(addprefix $(p)., $(IMAGES)))) + +.PHONY: image.push.% +## image.push.%: Push docker image for a specific platform +image.push.%: image.build.% + @echo "===========> Pushing image $(IMAGE) $(VERSION) to $(REGISTRY_PREFIX)" + $(DOCKER) push $(REGISTRY_PREFIX)/$(IMAGE)-$(ARCH):$(VERSION) + +.PHONY: image.manifest.push +## image.manifest.push: Push manifest list for multi-arch images +image.manifest.push: export DOCKER_CLI_EXPERIMENTAL := enabled +image.manifest.push: image.verify go.build.verify \ +$(addprefix image.manifest.push., $(addprefix $(IMAGE_PLAT)., $(IMAGES))) + +.PHONY: image.manifest.push.% +## image.manifest.push.%: Push manifest list for multi-arch images for a specific platform +image.manifest.push.%: image.push.% image.manifest.remove.% + @echo "===========> Pushing manifest $(IMAGE) $(VERSION) to $(REGISTRY_PREFIX) and then remove the local manifest list" + @$(DOCKER) manifest create $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) \ + $(REGISTRY_PREFIX)/$(IMAGE)-$(ARCH):$(VERSION) + @$(DOCKER) manifest annotate $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) \ + $(REGISTRY_PREFIX)/$(IMAGE)-$(ARCH):$(VERSION) \ + --os $(OS) --arch ${ARCH} + @$(DOCKER) manifest push --purge $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) + +# Docker cli has a bug: https://github.com/docker/cli/issues/954 +# If you find your manifests were not updated, +# Please manually delete them in $HOME/.docker/manifests/ +# and re-run. +.PHONY: image.manifest.remove.% +## image.manifest.remove.%: Remove local manifest list +image.manifest.remove.%: + @rm -rf ${HOME}/.docker/manifests/docker.io_$(REGISTRY_PREFIX)_$(IMAGE)-$(VERSION) + +.PHONY: image.manifest.push.multiarch +## image.manifest.push.multiarch: Push manifest list for multi-arch images for all platforms +image.manifest.push.multiarch: image.push.multiarch $(addprefix image.manifest.push.multiarch., $(IMAGES)) + +.PHONY: image.manifest.push.multiarch.% +## image.manifest.push.multiarch.%: Push manifest list for multi-arch images for all platforms for a specific image +image.manifest.push.multiarch.%: + @echo "===========> Pushing manifest $* $(VERSION) to $(REGISTRY_PREFIX) and then remove the local manifest list" + REGISTRY_PREFIX=$(REGISTRY_PREFIX) PLATFROMS="$(PLATFORMS)" IMAGE=$* VERSION=$(VERSION) DOCKER_CLI_EXPERIMENTAL=enabled \ + $(ROOT_DIR)/build/lib/create-manifest.sh + +.PHONY: image.help +## image.help: Print help for image targets +image.help: scripts/make-rules/image.mk + $(call smallhelp) \ No newline at end of file diff --git a/scripts/make-rules/release.mk b/scripts/make-rules/release.mk deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/make-rules/swagger.mk b/scripts/make-rules/swagger.mk deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/scripts/make-rules/tools.mk b/scripts/make-rules/tools.mk index e69de29bb2d..b9f0b5a8927 100644 --- a/scripts/make-rules/tools.mk +++ b/scripts/make-rules/tools.mk @@ -0,0 +1,189 @@ +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================== +# Makefile helper functions for tools(https://github.com/avelino/awesome-go) -> DIR: {TOOT_DIR}/tools | (go >= 1.19) +# + +BUILD_TOOLS ?= golangci-lint goimports addlicense deepcopy-gen conversion-gen ginkgo + +.PHONY: tools.install +## tools.install: Install all tools +tools.install: $(addprefix tools.install., $(BUILD_TOOLS)) + +.PHONY: tools.install.% +## tools.install.%: Install a single tool +tools.install.%: + @echo "===========> Installing $,The default installation path is $(GOBIN)/$*" + @$(MAKE) install.$* + @echo "===========> $* installed successfully" + +.PHONY: tools.verify.% +## tools.verify.%: Check if a tool is installed and install it +tools.verify.%: + @echo "===========> Verifying $* is installed" + @if [ ! -f $(TOOLS_DIR)/$* ]; then GOBIN=$(TOOLS_DIR) $(MAKE) tools.install.$*; fi + +.PHONY: +## install.golangci-lint: Install golangci-lint +install.golangci-lint: + @echo "===========> Installing golangci-lint,The default installation path is $(GOBIN)/golangci-lint" + @$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@latest +# @golangci-lint completion bash > $(HOME)/.golangci-lint.bash +# @if ! grep -q .golangci-lint.bash $(HOME)/.bashrc; then echo "source \$$HOME/.golangci-lint.bash" >> $(HOME)/.bashrc; fi + +.PHONY: install.goimports +## install.goimports: Install goimports, used to format go source files +install.goimports: + @echo "===========> Installing goimports,The default installation path is $(GOBIN)/goimports" + @$(GO) install golang.org/x/tools/cmd/goimports@latest + +# Actions path: https://github.com/sealerio/sealer/tree/main/.github/workflows/go.yml#L37-L50 +.PHONY: install.addlicense +## install.addlicense: Install addlicense, used to add license header to source files +install.addlicense: + @$(GO) install github.com/google/addlicense@latest + +.PHONY: install.deepcopy-gen +## install.deepcopy-gen: Install deepcopy-gen, used to generate deep copy functions +install.deepcopy-gen: + @$(GO) install k8s.io/code-generator/cmd/deepcopy-gen@latest + +.PHONY: install.conversion-gen +## install.conversion-gen: Install conversion-gen, used to generate conversion functions +install.conversion-gen: + @$(GO) install k8s.io/code-generator/cmd/conversion-gen@latest + +.PHONY: install.ginkgo +## install.ginkgo: Install ginkgo to run a single test or set of tests +install.ginkgo: + @echo "===========> Installing ginkgo,The default installation path is $(GOBIN)/ginkgo" + @$(GO) install github.com/onsi/ginkgo/ginkgo@v1.16.2 + +# ============================================================================== +# Tools that might be used include go gvm +# + +.PHONY: install.go-junit-report +## go-junit-report: Install go-junit-report, used to convert go test output to junit xml +install.go-junit-report: + @$(GO) install github.com/jstemmer/go-junit-report@latest + +.PHONY: install.kube-score +## install.kube-score: Install kube-score, used to check kubernetes yaml files +install.kube-score: + @$(GO) install github.com/zegl/kube-score/cmd/kube-score@latest + +.PHONY: install.go-gitlint +## Install go-gitlint: Install go-gitlint, used to check git commit message +install.go-gitlint: + @$(GO) install github.com/marmotedu/go-gitlint/cmd/go-gitlint@latest + +.PHONY: install.gsemver +## install.gsemver: Install gsemver, used to generate semver +install.gsemver: + @$(GO) install github.com/arnaud-deprez/gsemver@latest + +.PHONY: install.git-chglog +## install.git-chglog: Install git-chglog, used to generate changelog +install.git-chglog: + @$(GO) install github.com/git-chglog/git-chglog/cmd/git-chglog@latest + +.PHONY: install.github-release +## install.github-release: Install github-release, used to create github release +install.github-release: + @$(GO) install github.com/github-release/github-release@latest + +.PHONY: install.gvm +## install.gvm: Install gvm, gvm is a Go version manager, built on top of the official go tool. +install.gvm: + @echo "===========> Installing gvm,The default installation path is ~/.gvm/scripts/gvm" + @bash < <(curl -s -S -L https://raw.gitee.com/moovweb/gvm/master/binscripts/gvm-installer) + @$(shell source /root/.gvm/scripts/gvm) + +.PHONY: install.coscli +## install.coscli: Install coscli. COSCLI is a command line tool for Tencent Cloud Object Storage (COS) +install.coscli: + @wget -q https://github.com/tencentyun/coscli/releases/download/v0.10.2-beta/coscli-linux -O ${HOME}/bin/coscli + @chmod +x ${HOME}/bin/coscli + +.PHONY: install.coscmd +## install.coscmd: Install coscmd, used to upload files to Tencent Cloud Object Storage (COS) +install.coscmd: + @if which pip &>/dev/null; then pip install coscmd; else pip3 install coscmd; fi + +.PHONY: install.golines +## install.golines: Install golines, used to format long lines +install.golines: + @$(GO) install github.com/segmentio/golines@latest + +.PHONY: install.go-mod-outdated +## install.go-mod-outdated: Install go-mod-outdated, used to check outdated dependencies +install.go-mod-outdated: + @$(GO) install github.com/psampaz/go-mod-outdated@latest + +.PHONY: install.mockgen +## install.mockgen: Install mockgen, used to generate mock functions +install.mockgen: + @$(GO) install github.com/golang/mock/mockgen@latest + +.PHONY: install.gotests +## install.gotests: Install gotests, used to generate test functions +install.gotests: + @$(GO) install github.com/cweill/gotests/gotests@latest + +.PHONY: install.protoc-gen-go +## install.protoc-gen-go: Install protoc-gen-go, used to generate go source files from protobuf files +install.protoc-gen-go: + @$(GO) install github.com/golang/protobuf/protoc-gen-go@latest + +.PHONY: install.cfssl +## install.cfssl: Install cfssl, used to generate certificates +install.cfssl: + @$(ROOT_DIR)/scripts/install/install.sh iam::install::install_cfssl + +.PHONY: install.depth +## install.depth: Install depth, used to check dependency tree +install.depth: + @$(GO) install github.com/KyleBanks/depth/cmd/depth@latest + +.PHONY: install.go-callvis +## install.go-callvis: Install go-callvis, used to visualize call graph +install.go-callvis: + @$(GO) install github.com/ofabry/go-callvis@latest + +.PHONY: install.gothanks +## install.gothanks: Install gothanks, used to thank go dependencies +install.gothanks: + @$(GO) install github.com/psampaz/gothanks@latest + +.PHONY: install.richgo +## install.richgo: Install richgo +install.richgo: + @$(GO) install github.com/kyoh86/richgo@latest + +.PHONY: install.rts +## install.rts: Install rts +install.rts: + @$(GO) install github.com/galeone/rts/cmd/rts@latest + +.PHONY: install.codegen +## install.codegen: Install code generator, used to generate code +install.codegen: + @$(GO) install ${ROOT_DIR}/tools/codegen/codegen.go + +.PHONY: tools.help +## tools.help: Display help information about the tools package +tools.help: scripts/make-rules/tools.mk + $(call smallhelp) \ No newline at end of file From 9de0087745447d916684e00ad9a0b7096890261b Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Thu, 20 Apr 2023 22:59:52 +0800 Subject: [PATCH 04/12] styles: Reformat part Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- scripts/make-rules/copyright.mk | 8 +++-- scripts/make-rules/golang.mk | 2 +- scripts/make-rules/image.mk | 28 +++++++-------- scripts/make-rules/tools.mk | 60 ++++++++++++++++----------------- 4 files changed, 50 insertions(+), 48 deletions(-) diff --git a/scripts/make-rules/copyright.mk b/scripts/make-rules/copyright.mk index efb829d7c3d..ab91a8956c9 100644 --- a/scripts/make-rules/copyright.mk +++ b/scripts/make-rules/copyright.mk @@ -55,15 +55,17 @@ LICENSE_TEMPLATE ?= $(ROOT_DIR)/scripts/LICENSE_TEMPLATE -.PHONY: copyright.verify + # TODO: GOBIN -> TOOLS_DIR +## copyright.verify: Validate boilerplate headers for assign files +.PHONY: copyright.verify copyright.verify: tools.verify.addlicense @echo "===========> Validate boilerplate headers for assign files starting in the $(ROOT_DIR) directory" @$(GOBIN)/addlicense -v -check -ignore **/test/** -f $(LICENSE_TEMPLATE) $(CODE_DIRS) @echo "===========> End of boilerplate headers check..." -.PHONY: copyright.add ## copyright.add: Add the boilerplate headers for all files +.PHONY: copyright.add copyright.add: tools.verify.addlicense @echo "===========> Adding $(LICENSE_TEMPLATE) the boilerplate headers for all files" @$(GOBIN)/addlicense -y $(shell date +"%Y") -v -c "Alibaba Group Holding Ltd." -f $(LICENSE_TEMPLATE) $(CODE_DIRS) @@ -87,7 +89,7 @@ copyright.add: tools.verify.addlicense # -y string # copyright year(s) (default "2023") -.PHONY: copyright.help ## copyright.help: Show copyright help +.PHONY: copyright.help copyright.help: scripts/make-rules/copyright.mk $(call smallhelp) \ No newline at end of file diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index 3b7d187e0ec..3bb49d94478 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -120,7 +120,7 @@ go.build.%: @echo "BIN_DIR=$(BIN_DIR)" @echo "===========> Building binary $(COMMAND) $(VERSION) for $(OS) $(ARCH)" @mkdir -p $(OUTPUT_DIR)/bin/$(OS)/$(ARCH) - + @CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(OUTPUT_DIR)/bin/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_PACKAGE)/cmd/$(COMMAND) ## go.build: Build binaries diff --git a/scripts/make-rules/image.mk b/scripts/make-rules/image.mk index 35ef75db748..efebf46984b 100644 --- a/scripts/make-rules/image.mk +++ b/scripts/make-rules/image.mk @@ -50,8 +50,8 @@ IMAGES ?= $(filter-out tools,$(foreach image,${IMAGES_DIR},$(notdir ${image}))) # Image targets # ============================================================================== -.PHONY: image.verify ## image.verify: Verify docker version +.PHONY: image.verify image.verify: $(eval API_VERSION := $(shell $(DOCKER) version | grep -E 'API version: {1,6}[0-9]' | head -n1 | awk '{print $$3} END { if (NR==0) print 0}' )) $(eval PASS := $(shell echo "$(API_VERSION) > $(DOCKER_SUPPORTED_API_VERSION)" | bc)) @@ -61,8 +61,8 @@ image.verify: exit 1; \ fi -.PHONY: image.daemon.verify ## image.daemon.verify: Verify docker daemon experimental features +.PHONY: image.daemon.verify image.daemon.verify: $(eval PASS := $(shell $(DOCKER) version | grep -q -E 'Experimental: {1,5}true' && echo 1 || echo 0)) @if [ $(PASS) -ne 1 ]; then \ @@ -70,16 +70,16 @@ image.daemon.verify: exit 1; \ fi -.PHONY: image.build ## image.build: Build docker images +.PHONY: image.build image.build: image.verify go.build.verify $(addprefix image.build., $(addprefix $(IMAGE_PLAT)., $(IMAGES))) -.PHONY: image.build.multiarch ## image.build.multiarch: Build docker images for all platforms +.PHONY: image.build.multiarch image.build.multiarch: image.verify go.build.verify $(foreach p,$(PLATFORMS),$(addprefix image.build., $(addprefix $(p)., $(IMAGES)))) -.PHONY: image.build.% ## image.build.%: Build docker image for a specific platform +.PHONY: image.build.% image.build.%: go.build.% $(eval IMAGE := $(COMMAND)) $(eval IMAGE_PLAT := $(subst _,/,$(PLATFORM))) @@ -98,28 +98,28 @@ image.build.%: go.build.% fi @rm -rf $(TMP_DIR)/$(IMAGE) -.PHONY: image.push ## image.push: Push docker images +.PHONY: image.push image.push: image.verify go.build.verify $(addprefix image.push., $(addprefix $(IMAGE_PLAT)., $(IMAGES))) -.PHONY: image.push.multiarch ## image.push.multiarch: Push docker images for all platforms +.PHONY: image.push.multiarch image.push.multiarch: image.verify go.build.verify $(foreach p,$(PLATFORMS),$(addprefix image.push., $(addprefix $(p)., $(IMAGES)))) -.PHONY: image.push.% ## image.push.%: Push docker image for a specific platform +.PHONY: image.push.% image.push.%: image.build.% @echo "===========> Pushing image $(IMAGE) $(VERSION) to $(REGISTRY_PREFIX)" $(DOCKER) push $(REGISTRY_PREFIX)/$(IMAGE)-$(ARCH):$(VERSION) -.PHONY: image.manifest.push ## image.manifest.push: Push manifest list for multi-arch images +.PHONY: image.manifest.push image.manifest.push: export DOCKER_CLI_EXPERIMENTAL := enabled image.manifest.push: image.verify go.build.verify \ $(addprefix image.manifest.push., $(addprefix $(IMAGE_PLAT)., $(IMAGES))) -.PHONY: image.manifest.push.% ## image.manifest.push.%: Push manifest list for multi-arch images for a specific platform +.PHONY: image.manifest.push.% image.manifest.push.%: image.push.% image.manifest.remove.% @echo "===========> Pushing manifest $(IMAGE) $(VERSION) to $(REGISTRY_PREFIX) and then remove the local manifest list" @$(DOCKER) manifest create $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) \ @@ -133,23 +133,23 @@ image.manifest.push.%: image.push.% image.manifest.remove.% # If you find your manifests were not updated, # Please manually delete them in $HOME/.docker/manifests/ # and re-run. -.PHONY: image.manifest.remove.% ## image.manifest.remove.%: Remove local manifest list +.PHONY: image.manifest.remove.% image.manifest.remove.%: @rm -rf ${HOME}/.docker/manifests/docker.io_$(REGISTRY_PREFIX)_$(IMAGE)-$(VERSION) -.PHONY: image.manifest.push.multiarch ## image.manifest.push.multiarch: Push manifest list for multi-arch images for all platforms +.PHONY: image.manifest.push.multiarch image.manifest.push.multiarch: image.push.multiarch $(addprefix image.manifest.push.multiarch., $(IMAGES)) -.PHONY: image.manifest.push.multiarch.% ## image.manifest.push.multiarch.%: Push manifest list for multi-arch images for all platforms for a specific image +.PHONY: image.manifest.push.multiarch.% image.manifest.push.multiarch.%: @echo "===========> Pushing manifest $* $(VERSION) to $(REGISTRY_PREFIX) and then remove the local manifest list" REGISTRY_PREFIX=$(REGISTRY_PREFIX) PLATFROMS="$(PLATFORMS)" IMAGE=$* VERSION=$(VERSION) DOCKER_CLI_EXPERIMENTAL=enabled \ $(ROOT_DIR)/build/lib/create-manifest.sh -.PHONY: image.help ## image.help: Print help for image targets +.PHONY: image.help image.help: scripts/make-rules/image.mk $(call smallhelp) \ No newline at end of file diff --git a/scripts/make-rules/tools.mk b/scripts/make-rules/tools.mk index b9f0b5a8927..3d03f0e5fe8 100644 --- a/scripts/make-rules/tools.mk +++ b/scripts/make-rules/tools.mk @@ -18,19 +18,19 @@ BUILD_TOOLS ?= golangci-lint goimports addlicense deepcopy-gen conversion-gen ginkgo -.PHONY: tools.install ## tools.install: Install all tools +.PHONY: tools.install tools.install: $(addprefix tools.install., $(BUILD_TOOLS)) -.PHONY: tools.install.% ## tools.install.%: Install a single tool +.PHONY: tools.install.% tools.install.%: @echo "===========> Installing $,The default installation path is $(GOBIN)/$*" @$(MAKE) install.$* @echo "===========> $* installed successfully" -.PHONY: tools.verify.% ## tools.verify.%: Check if a tool is installed and install it +.PHONY: tools.verify.% tools.verify.%: @echo "===========> Verifying $* is installed" @if [ ! -f $(TOOLS_DIR)/$* ]; then GOBIN=$(TOOLS_DIR) $(MAKE) tools.install.$*; fi @@ -43,30 +43,30 @@ install.golangci-lint: # @golangci-lint completion bash > $(HOME)/.golangci-lint.bash # @if ! grep -q .golangci-lint.bash $(HOME)/.bashrc; then echo "source \$$HOME/.golangci-lint.bash" >> $(HOME)/.bashrc; fi -.PHONY: install.goimports ## install.goimports: Install goimports, used to format go source files +.PHONY: install.goimports install.goimports: @echo "===========> Installing goimports,The default installation path is $(GOBIN)/goimports" @$(GO) install golang.org/x/tools/cmd/goimports@latest # Actions path: https://github.com/sealerio/sealer/tree/main/.github/workflows/go.yml#L37-L50 -.PHONY: install.addlicense ## install.addlicense: Install addlicense, used to add license header to source files +.PHONY: install.addlicense install.addlicense: @$(GO) install github.com/google/addlicense@latest -.PHONY: install.deepcopy-gen ## install.deepcopy-gen: Install deepcopy-gen, used to generate deep copy functions +.PHONY: install.deepcopy-gen install.deepcopy-gen: @$(GO) install k8s.io/code-generator/cmd/deepcopy-gen@latest -.PHONY: install.conversion-gen ## install.conversion-gen: Install conversion-gen, used to generate conversion functions +.PHONY: install.conversion-gen install.conversion-gen: @$(GO) install k8s.io/code-generator/cmd/conversion-gen@latest -.PHONY: install.ginkgo ## install.ginkgo: Install ginkgo to run a single test or set of tests +.PHONY: install.ginkgo install.ginkgo: @echo "===========> Installing ginkgo,The default installation path is $(GOBIN)/ginkgo" @$(GO) install github.com/onsi/ginkgo/ginkgo@v1.16.2 @@ -75,115 +75,115 @@ install.ginkgo: # Tools that might be used include go gvm # -.PHONY: install.go-junit-report ## go-junit-report: Install go-junit-report, used to convert go test output to junit xml +.PHONY: install.go-junit-report install.go-junit-report: @$(GO) install github.com/jstemmer/go-junit-report@latest -.PHONY: install.kube-score ## install.kube-score: Install kube-score, used to check kubernetes yaml files +.PHONY: install.kube-score install.kube-score: @$(GO) install github.com/zegl/kube-score/cmd/kube-score@latest -.PHONY: install.go-gitlint ## Install go-gitlint: Install go-gitlint, used to check git commit message +.PHONY: install.go-gitlint install.go-gitlint: @$(GO) install github.com/marmotedu/go-gitlint/cmd/go-gitlint@latest -.PHONY: install.gsemver ## install.gsemver: Install gsemver, used to generate semver +.PHONY: install.gsemver install.gsemver: @$(GO) install github.com/arnaud-deprez/gsemver@latest -.PHONY: install.git-chglog ## install.git-chglog: Install git-chglog, used to generate changelog +.PHONY: install.git-chglog install.git-chglog: @$(GO) install github.com/git-chglog/git-chglog/cmd/git-chglog@latest -.PHONY: install.github-release ## install.github-release: Install github-release, used to create github release +.PHONY: install.github-release install.github-release: @$(GO) install github.com/github-release/github-release@latest -.PHONY: install.gvm ## install.gvm: Install gvm, gvm is a Go version manager, built on top of the official go tool. +.PHONY: install.gvm install.gvm: @echo "===========> Installing gvm,The default installation path is ~/.gvm/scripts/gvm" @bash < <(curl -s -S -L https://raw.gitee.com/moovweb/gvm/master/binscripts/gvm-installer) @$(shell source /root/.gvm/scripts/gvm) -.PHONY: install.coscli ## install.coscli: Install coscli. COSCLI is a command line tool for Tencent Cloud Object Storage (COS) +.PHONY: install.coscli install.coscli: @wget -q https://github.com/tencentyun/coscli/releases/download/v0.10.2-beta/coscli-linux -O ${HOME}/bin/coscli @chmod +x ${HOME}/bin/coscli -.PHONY: install.coscmd ## install.coscmd: Install coscmd, used to upload files to Tencent Cloud Object Storage (COS) +.PHONY: install.coscmd install.coscmd: @if which pip &>/dev/null; then pip install coscmd; else pip3 install coscmd; fi -.PHONY: install.golines ## install.golines: Install golines, used to format long lines +.PHONY: install.golines install.golines: @$(GO) install github.com/segmentio/golines@latest -.PHONY: install.go-mod-outdated ## install.go-mod-outdated: Install go-mod-outdated, used to check outdated dependencies +.PHONY: install.go-mod-outdated install.go-mod-outdated: @$(GO) install github.com/psampaz/go-mod-outdated@latest -.PHONY: install.mockgen ## install.mockgen: Install mockgen, used to generate mock functions +.PHONY: install.mockgen install.mockgen: @$(GO) install github.com/golang/mock/mockgen@latest -.PHONY: install.gotests ## install.gotests: Install gotests, used to generate test functions +.PHONY: install.gotests install.gotests: @$(GO) install github.com/cweill/gotests/gotests@latest -.PHONY: install.protoc-gen-go ## install.protoc-gen-go: Install protoc-gen-go, used to generate go source files from protobuf files +.PHONY: install.protoc-gen-go install.protoc-gen-go: @$(GO) install github.com/golang/protobuf/protoc-gen-go@latest -.PHONY: install.cfssl ## install.cfssl: Install cfssl, used to generate certificates +.PHONY: install.cfssl install.cfssl: @$(ROOT_DIR)/scripts/install/install.sh iam::install::install_cfssl -.PHONY: install.depth ## install.depth: Install depth, used to check dependency tree +.PHONY: install.depth install.depth: @$(GO) install github.com/KyleBanks/depth/cmd/depth@latest -.PHONY: install.go-callvis ## install.go-callvis: Install go-callvis, used to visualize call graph +.PHONY: install.go-callvis install.go-callvis: @$(GO) install github.com/ofabry/go-callvis@latest -.PHONY: install.gothanks ## install.gothanks: Install gothanks, used to thank go dependencies +.PHONY: install.gothanks install.gothanks: @$(GO) install github.com/psampaz/gothanks@latest -.PHONY: install.richgo ## install.richgo: Install richgo +.PHONY: install.richgo install.richgo: @$(GO) install github.com/kyoh86/richgo@latest -.PHONY: install.rts ## install.rts: Install rts +.PHONY: install.rts install.rts: @$(GO) install github.com/galeone/rts/cmd/rts@latest -.PHONY: install.codegen ## install.codegen: Install code generator, used to generate code +.PHONY: install.codegen install.codegen: @$(GO) install ${ROOT_DIR}/tools/codegen/codegen.go -.PHONY: tools.help ## tools.help: Display help information about the tools package +.PHONY: tools.help tools.help: scripts/make-rules/tools.mk $(call smallhelp) \ No newline at end of file From baa95a15a6a60ba4cde33e4d7c4a574b95fe2921 Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Tue, 25 Apr 2023 00:38:32 +0800 Subject: [PATCH 05/12] fix: Partial optimization Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- Makefile | 6 +++--- scripts/make-rules/common.mk | 2 +- scripts/make-rules/golang.mk | 2 +- scripts/make-rules/tools.mk | 16 ++++++++++++++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 1e260029b8a..8aa58c90061 100644 --- a/Makefile +++ b/Makefile @@ -173,6 +173,6 @@ help: Makefile $(call makehelp) ## all-help: Show all help details info. -.PHONY: all-help -all-help: go.help copyright.help tools.help image.help help - $(call makeallhelp) \ No newline at end of file +.PHONY: help-all +help-all: go.help copyright.help tools.help image.help help + $(call makeallhelp) diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk index 3ed7650e47b..c4340a5faa4 100644 --- a/scripts/make-rules/common.mk +++ b/scripts/make-rules/common.mk @@ -140,7 +140,7 @@ endef # Here are some examples of builds define MAKEFILE_EXAMPLE # make build BINS=sealer Only a single sealer binary is built -# make fmt vet lint Run code style check +# make -j $(nproc) all Run tidy gen add-copyright format lint cover build concurrently # make gen Generate all necessary files # make deepcopy Generate deepcopy code # make verify-copyright Verify the license headers for all files diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index 3bb49d94478..33d654a06e7 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -159,7 +159,7 @@ go.test.cover: go.test @$(GO) tool cover -func=$(OUTPUT_DIR)/coverage.out | \ awk -v target=$(COVERAGE) -f $(ROOT_DIR)/scripts/coverage.awk -## go.test.integration: Run integration test +## go.test.format: Run unit test and format codes .PHONY: go.format go.format: tools.verify.goimports @echo "===========> Formating codes" diff --git a/scripts/make-rules/tools.mk b/scripts/make-rules/tools.mk index 3d03f0e5fe8..86fc6432f77 100644 --- a/scripts/make-rules/tools.mk +++ b/scripts/make-rules/tools.mk @@ -14,9 +14,25 @@ # ============================================================================== # Makefile helper functions for tools(https://github.com/avelino/awesome-go) -> DIR: {TOOT_DIR}/tools | (go >= 1.19) +# Why download to the tools directory, thinking we might often switch Go versions using gvm. # +# sealer build use BUILD_TOOLS BUILD_TOOLS ?= golangci-lint goimports addlicense deepcopy-gen conversion-gen ginkgo +# Code analysis tools +ANALYSIS_TOOLS = golangci-lint goimports golines go-callvis kube-score +# Code generation tools +GENERATION_TOOLS = deepcopy-gen conversion-gen protoc-gen-go cfssl rts codegen +# Testing tools +TEST_TOOLS = ginkgo junit-report gotests +# Version control tools +VERSION_CONTROL_TOOLS = addlicense go-gitlint git-chglog github-release gsemver +# Cloud storage tools +CLOUD_STORAGE_TOOLS = coscli coscmd +# Utility tools +UTILITY_TOOLS = go-mod-outdated mockgen gothanks richgo +# All tools +ALL_TOOLS ?= $(ANALYSIS_TOOLS) $(GENERATION_TOOLS) $(TEST_TOOLS) $(VERSION_CONTROL_TOOLS) $(CLOUD_STORAGE_TOOLS) $(UTILITY_TOOLS) ## tools.install: Install all tools .PHONY: tools.install From 2edc235d26793e4db55ed720798f058fd7ffd2e3 Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Tue, 25 Apr 2023 03:37:27 +0800 Subject: [PATCH 06/12] fix: Optimize the root makefile object Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- .gitignore | 4 +-- Makefile | 50 +++++++++++++++++++------- scripts/make-rules/common.mk | 3 ++ scripts/make-rules/copyright.mk | 3 +- scripts/make-rules/golang.mk | 64 +++++++++++++++++++++++---------- scripts/make-rules/tools.mk | 44 ++++++++++------------- 6 files changed, 109 insertions(+), 59 deletions(-) diff --git a/.gitignore b/.gitignore index 2d59c24af00..9b8db2b8ae0 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,6 @@ docs/site/package-lock.json .vscode # tools is responsible for collecting sealer third party package binary tools -tools +tools/ #coverage.out -tmp +tmp/ diff --git a/Makefile b/Makefile index 8aa58c90061..1f245b35699 100644 --- a/Makefile +++ b/Makefile @@ -27,17 +27,12 @@ all: tidy gen add-copyright format lint cover build ROOT_PACKAGE=github.com/sealerio/sealer VERSION_PACKAGE=github.com/sealerio/sealer/pkg/version -Dirs=$(shell ls) -GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) -GOOS ?= $(shell go env GOOS) -GOARCH ?= $(shell go env GOARCH) - BUILD_SCRIPTS := scripts/build.sh # ============================================================================== # Includes -include scripts/make-rules/common.mk # make sure include common.mk at the first include line +include scripts/make-rules/common.mk # make sure include common.mk at the first include line include scripts/make-rules/golang.mk include scripts/make-rules/image.mk include scripts/make-rules/copyright.mk @@ -74,20 +69,30 @@ export USAGE_OPTIONS build: clean @$(MAKE) go.build +## tidy: tidy go.mod +.PHONY: tidy +tidy: + @$(GO) mod tidy + +## vendor: vendor go.mod +.PHONY: vendor +vendor: + @$(GO) mod vendor + ## fmt: Run go fmt against code. .PHONY: fmt fmt: - go fmt ./... + @$(GO) fmt ./... ## vet: Run go vet against code. .PHONY: vet vet: - go vet ./... + @$(GO) vet ./... -## lint: Run go lint against code. +## lint: Check syntax and styling of go sources. .PHONY: lint lint: - golangci-lint run -v ./... + @$(MAKE) go.lint ## style: code style -> fmt,vet,lint .PHONY: style @@ -122,14 +127,35 @@ verify-license: add-license: @$(MAKE) copyright.add -gosec: install-gosec - $(GOSEC_BIN) ./... +## format: Gofmt (reformat) package sources (exclude vendor dir if existed). +.PHONY: format +format: + @$(MAKE) go.format ## tools: Install dependent tools. .PHONY: tools tools: @$(MAKE) tools.install +## test: Run unit test. +.PHONY: test +test: + @$(MAKE) go.test + +## cover: Run unit test and get test coverage. +.PHONY: cover +cover: + @$(MAKE) go.test.cover + +## updates: Check for updates to go.mod dependencies +.PHONY: updates + @$(MAKE) go.updates + +## imports: task to automatically handle import packages in Go files using goimports tool +.PHONY: imports +imports: + @$(MAKE) go.imports + ## install-deepcopy-gen: check license if not exist install deepcopy-gen tools. install-deepcopy-gen: ifeq (, $(shell which deepcopy-gen)) diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk index c4340a5faa4..6a411dba54f 100644 --- a/scripts/make-rules/common.mk +++ b/scripts/make-rules/common.mk @@ -17,6 +17,7 @@ # SHELL := /bin/bash +GO := go DIRS=$(shell ls) DEBUG ?= 0 GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) @@ -26,6 +27,8 @@ BUILD_DATE=$(shell date '+%FT %T %z') # "buildDate":"2023-03-31T 20:05:43 +0800" # include the common makefile COMMON_SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +SRC = $(shell find . -type f -name '*.go' -not -path "./vendor/*") + # ROOT_DIR: root directory of the code base ifeq ($(origin ROOT_DIR),undefined) ROOT_DIR := $(abspath $(shell cd $(COMMON_SELF_DIR)/../.. && pwd -P)) diff --git a/scripts/make-rules/copyright.mk b/scripts/make-rules/copyright.mk index ab91a8956c9..ea14fb07422 100644 --- a/scripts/make-rules/copyright.mk +++ b/scripts/make-rules/copyright.mk @@ -52,10 +52,11 @@ # else # GOSEC_BIN=$(shell which gosec) # endif +# gosec: install-gosec +# $(GOSEC_BIN) ./... LICENSE_TEMPLATE ?= $(ROOT_DIR)/scripts/LICENSE_TEMPLATE - # TODO: GOBIN -> TOOLS_DIR ## copyright.verify: Validate boilerplate headers for assign files .PHONY: copyright.verify diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index 33d654a06e7..40f46e165a9 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -18,7 +18,7 @@ GO := go # ! go 1.8 some packages fail to be pulled out. You are advised to use the gvm switchover version of the tools toolkit -GO_SUPPORTED_VERSIONS ?= |1.18|1.19|1.20| +GO_SUPPORTED_VERSIONS ?= |1.17|1.18|1.19|1.20| GO_LDFLAGS += -X $(VERSION_PACKAGE).gitVersion=${GIT_TAG} \ -X $(VERSION_PACKAGE).gitCommit=${GIT_COMMIT} \ @@ -62,7 +62,7 @@ ifeq (${BINS},) endif # TODO: EXCLUDE_TESTS variable, which contains the name of the package to be excluded from the test -EXCLUDE_TESTS := github.com/sealerio/sealer/test github.com/sealerio/sealer/pkg/logger +EXCLUDE_TESTS := github.com/sealerio/sealer/test github.com/sealerio/sealer/pkg/logger # ============================================================================== # make: Nothing to be done build and build sub targets @@ -143,39 +143,65 @@ go.lint: tools.verify.golangci-lint @golangci-lint run -c $(ROOT_DIR)/.golangci.yml $(ROOT_DIR)/... ## go.test: Run unit test -.PHONY: go.test -go.test: tools.verify.go-junit-report +go.test: @echo "===========> Run unit test" -# @set -o pipefail;$(GO) test -race -cover -coverprofile=$(OUTPUT_DIR)/coverage.out \ -# -timeout=10m -shuffle=on -short -v `go list ./...|\ -# egrep -v $(subst $(SPACE),'|',$(sort $(EXCLUDE_TESTS)))` 2>&1 | \ -# tee >(go-junit-report --set-exit-code >$(OUTPUT_DIR)/report.xml) -# @sed -i '/mock_.*.go/d' $(OUTPUT_DIR)/coverage.out # remove mock_.*.go files from test coverage -# @$(GO) tool cover -html=$(OUTPUT_DIR)/coverage.out -o $(OUTPUT_DIR)/coverage.html - -## go.test.cover: Run unit test and check coverage + @$(GO) test ./... + +## go.test.junit-report: Run unit test +.PHONY: go.test.junit-report +go.test.junit-report: tools.verify.go-junit-report + @echo "===========> Run unit test > $(TMP_DIR)/report.xml" + @$(GO) test -v -coverprofile=$(TMP_DIR)/coverage.out 2>&1 ./... | $(TOOLS_DIR)/go-junit-report -set-exit-code > $(TMP_DIR)/report.xml + @sed -i '/mock_.*.go/d' $(TMP_DIR)/coverage.out + @echo "===========> Test coverage of Go code is reported to $(TMP_DIR)/coverage.html by generating HTML" + @$(GO) tool cover -html=$(TMP_DIR)/coverage.out -o $(TMP_DIR)/coverage.html + +# .PHONY: go.test.junit-report +# go.test.junit-report: tools.verify.go-junit-report +# @echo "===========> Run unit test" +# @$(GO) test -race -cover -coverprofile=$(OUTPUT_DIR)/coverage.out \ +# -timeout=10m -shuffle=on -short -v `go list ./pkg/hook/ |\ +# egrep -v $(subst $(SPACE),'|',$(sort $(EXCLUDE_TESTS)))` 2>&1 | \ +# tee >(go-junit-report --set-exit-code >$(OUTPUT_DIR)/report.xml) +# @sed -i '/mock_.*.go/d' $(OUTPUT_DIR)/coverage.out # remove mock_.*.go files from test coverage +# @$(GO) tool cover -html=$(OUTPUT_DIR)/coverage.out -o $(OUTPUT_DIR)/coverage.html + +## go.test.cover: Run unit test with coverage .PHONY: go.test.cover -go.test.cover: go.test - @$(GO) tool cover -func=$(OUTPUT_DIR)/coverage.out | \ +go.test.cover: go.test.junit-report + @touch $(TMP_DIR)/coverage.out + @$(GO) tool cover -func=$(TMP_DIR)/coverage.out | \ awk -v target=$(COVERAGE) -f $(ROOT_DIR)/scripts/coverage.awk ## go.test.format: Run unit test and format codes .PHONY: go.format -go.format: tools.verify.goimports +go.format: tools.verify.golines tools.verify.goimports @echo "===========> Formating codes" - @$(FIND) -type f -name '*.go' | xargs gofmt -s -w - @$(FIND) -type f -name '*.go' | xargs $(TOOLS_DIR)/goimports -l -w -local $(ROOT_PACKAGE) + @$(FIND) -type f -name '*.go' | $(XARGS) gofmt -s -w + @$(FIND) -type f -name '*.go' | $(XARGS) $(TOOLS_DIR)/goimports -w -local $(ROOT_PACKAGE) + @$(FIND) -type f -name '*.go' | $(XARGS) $(TOOLS_DIR)/golines -w --max-len=120 --reformat-tags --shorten-comments --ignore-generated . @$(GO) mod edit -fmt +## imports: task to automatically handle import packages in Go files using goimports tool +.PHONY: go.imports +go.imports: tools.verify.goimports + @$(TOOLS_DIR)/goimports -l -w $(SRC) + +## lint: Run the golangci-lint +.PHONY: go.lint +go.lint: tools.verify.golangci-lint + @echo "===========> Run golangci to lint source codes" + @$(TOOLS_DIR)/golangci-lint run -c $(ROOT_DIR)/.golangci.yml $(ROOT_DIR)/... + ## go.updates: Check for updates to go.mod dependencies .PHONY: go.updates go.updates: tools.verify.go-mod-outdated @$(GO) list -u -m -json all | go-mod-outdated -update -direct -## go.clean: Clean all builds +## go.clean: Clean all builds directories and files .PHONY: go.clean go.clean: - @echo "===========> Cleaning all builds $(OUTPUT_DIR) and $(BIN_DIR)" + @echo "===========> Cleaning all builds OUTPUT_DIR($(OUTPUT_DIR)) AND BIN_DIR($(BIN_DIR))" @-rm -vrf $(OUTPUT_DIR) $(BIN_DIR) @echo "===========> End clean..." diff --git a/scripts/make-rules/tools.mk b/scripts/make-rules/tools.mk index 86fc6432f77..31d5e321e58 100644 --- a/scripts/make-rules/tools.mk +++ b/scripts/make-rules/tools.mk @@ -18,7 +18,7 @@ # # sealer build use BUILD_TOOLS -BUILD_TOOLS ?= golangci-lint goimports addlicense deepcopy-gen conversion-gen ginkgo +BUILD_TOOLS ?= golangci-lint goimports addlicense deepcopy-gen conversion-gen ginkgo junit-report # Code analysis tools ANALYSIS_TOOLS = golangci-lint goimports golines go-callvis kube-score # Code generation tools @@ -27,34 +27,41 @@ GENERATION_TOOLS = deepcopy-gen conversion-gen protoc-gen-go cfssl rts codegen TEST_TOOLS = ginkgo junit-report gotests # Version control tools VERSION_CONTROL_TOOLS = addlicense go-gitlint git-chglog github-release gsemver -# Cloud storage tools -CLOUD_STORAGE_TOOLS = coscli coscmd # Utility tools UTILITY_TOOLS = go-mod-outdated mockgen gothanks richgo # All tools -ALL_TOOLS ?= $(ANALYSIS_TOOLS) $(GENERATION_TOOLS) $(TEST_TOOLS) $(VERSION_CONTROL_TOOLS) $(CLOUD_STORAGE_TOOLS) $(UTILITY_TOOLS) +ALL_TOOLS ?= $(ANALYSIS_TOOLS) $(GENERATION_TOOLS) $(TEST_TOOLS) $(VERSION_CONTROL_TOOLS) $(UTILITY_TOOLS) -## tools.install: Install all tools +## tools.install: Install a must tools .PHONY: tools.install tools.install: $(addprefix tools.install., $(BUILD_TOOLS)) -## tools.install.%: Install a single tool +## tools.install-all: Install all tools +.PHONY: tools.install-all +tools.install-all: $(addprefix tools.install-all., $(ALL_TOOLS)) + +## tools.install.%: Install a single tool in $GOBIN/ .PHONY: tools.install.% tools.install.%: @echo "===========> Installing $,The default installation path is $(GOBIN)/$*" @$(MAKE) install.$* - @echo "===========> $* installed successfully" + +## tools.install-all.%: Parallelism install a single tool in ./tools/* +.PHONY: tools.install-all.% +tools.install-all.%: + @echo "===========> Installing $,The default installation path is $(TOOLS_DIR)/$*" + @$(MAKE) -j $(nproc) install.$* ## tools.verify.%: Check if a tool is installed and install it .PHONY: tools.verify.% tools.verify.%: @echo "===========> Verifying $* is installed" @if [ ! -f $(TOOLS_DIR)/$* ]; then GOBIN=$(TOOLS_DIR) $(MAKE) tools.install.$*; fi + @echo "===========> $* is install in $(TOOLS_DIR)/$*" .PHONY: ## install.golangci-lint: Install golangci-lint install.golangci-lint: - @echo "===========> Installing golangci-lint,The default installation path is $(GOBIN)/golangci-lint" @$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@latest # @golangci-lint completion bash > $(HOME)/.golangci-lint.bash # @if ! grep -q .golangci-lint.bash $(HOME)/.bashrc; then echo "source \$$HOME/.golangci-lint.bash" >> $(HOME)/.bashrc; fi @@ -62,7 +69,6 @@ install.golangci-lint: ## install.goimports: Install goimports, used to format go source files .PHONY: install.goimports install.goimports: - @echo "===========> Installing goimports,The default installation path is $(GOBIN)/goimports" @$(GO) install golang.org/x/tools/cmd/goimports@latest # Actions path: https://github.com/sealerio/sealer/tree/main/.github/workflows/go.yml#L37-L50 @@ -84,18 +90,17 @@ install.conversion-gen: ## install.ginkgo: Install ginkgo to run a single test or set of tests .PHONY: install.ginkgo install.ginkgo: - @echo "===========> Installing ginkgo,The default installation path is $(GOBIN)/ginkgo" @$(GO) install github.com/onsi/ginkgo/ginkgo@v1.16.2 -# ============================================================================== -# Tools that might be used include go gvm -# - ## go-junit-report: Install go-junit-report, used to convert go test output to junit xml .PHONY: install.go-junit-report install.go-junit-report: @$(GO) install github.com/jstemmer/go-junit-report@latest +# ============================================================================== +# Tools that might be used include go gvm +# + ## install.kube-score: Install kube-score, used to check kubernetes yaml files .PHONY: install.kube-score install.kube-score: @@ -128,17 +133,6 @@ install.gvm: @bash < <(curl -s -S -L https://raw.gitee.com/moovweb/gvm/master/binscripts/gvm-installer) @$(shell source /root/.gvm/scripts/gvm) -## install.coscli: Install coscli. COSCLI is a command line tool for Tencent Cloud Object Storage (COS) -.PHONY: install.coscli -install.coscli: - @wget -q https://github.com/tencentyun/coscli/releases/download/v0.10.2-beta/coscli-linux -O ${HOME}/bin/coscli - @chmod +x ${HOME}/bin/coscli - -## install.coscmd: Install coscmd, used to upload files to Tencent Cloud Object Storage (COS) -.PHONY: install.coscmd -install.coscmd: - @if which pip &>/dev/null; then pip install coscmd; else pip3 install coscmd; fi - ## install.golines: Install golines, used to format long lines .PHONY: install.golines install.golines: From 2f5e6c68da37dc5444748d848a971ac894b76859 Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Tue, 25 Apr 2023 14:57:42 +0800 Subject: [PATCH 07/12] fix: Code generator and post-generation logic Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> fix: part about build issues Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> fix: part about build issues Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- Makefile | 94 ++---- pkg/env/test/template/kubeadm.yaml | 15 +- scripts/make-rules/common.mk | 3 +- scripts/make-rules/copyright.mk | 39 +-- scripts/make-rules/gen.mk | 22 +- scripts/make-rules/golang.mk | 22 +- scripts/make-rules/tools.mk | 8 +- types/api/v1/zz_generated.deepcopy.go | 93 +++++- types/api/v2/zz_generated.deepcopy.go | 396 +++++++++++++++++++++++++- 9 files changed, 540 insertions(+), 152 deletions(-) diff --git a/Makefile b/Makefile index 1f245b35699..09f47adf986 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ export USAGE_OPTIONS ## build: Build binaries by default .PHONY: build -build: clean +build: @$(MAKE) go.build ## tidy: tidy go.mod @@ -98,45 +98,15 @@ lint: .PHONY: style style: fmt vet lint -## linux-amd64: Build binaries for Linux (amd64) -linux-amd64: clean - @echo "Building sealer and seautil binaries for Linux (amd64)" - @GOOS=linux GOARCH=amd64 $(BUILD_SCRIPTS) $(GIT_TAG) - -## linux-arm64: Build binaries for Linux (arm64) -linux-arm64: clean - @echo "Building sealer and seautil binaries for Linux (arm64)" - @GOOS=linux GOARCH=arm64 $(BUILD_SCRIPTS) $(GIT_TAG) - -## build-in-docker: sealer should be compiled in linux platform, otherwise there will be GraphDriver problem. -build-in-docker: - @docker run --rm -v ${PWD}:/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux - -## gen: Generate all necessary files. -.PHONY: gen -gen: - @$(MAKE) gen.run - -## verify-copyright: Verify the license headers for all files. -.PHONY: verify-copyright -verify-license: - @$(MAKE) copyright.verify - -## add-copyright: Add copyright ensure source code files have license headers. -.PHONY: add-copyright -add-license: - @$(MAKE) copyright.add +## linux.%: Build binaries for Linux (make linux.amd64 OR make linux.arm64) +linux.%: + @$(MAKE) go.linux.$* ## format: Gofmt (reformat) package sources (exclude vendor dir if existed). .PHONY: format format: @$(MAKE) go.format -## tools: Install dependent tools. -.PHONY: tools -tools: - @$(MAKE) tools.install - ## test: Run unit test. .PHONY: test test: @@ -156,43 +126,35 @@ cover: imports: @$(MAKE) go.imports -## install-deepcopy-gen: check license if not exist install deepcopy-gen tools. -install-deepcopy-gen: -ifeq (, $(shell which deepcopy-gen)) - { \ - set -e ;\ - LICENSE_TMP_DIR=$$(mktemp -d) ;\ - cd $$LICENSE_TMP_DIR ;\ - go mod init tmp ;\ - go get -v k8s.io/code-generator/cmd/deepcopy-gen ;\ - rm -rf $$LICENSE_TMP_DIR ;\ - } -DEEPCOPY_BIN=$(GOBIN)/deepcopy-gen -else -DEEPCOPY_BIN=$(shell which deepcopy-gen) -endif - -# BOILERPLATE := scripts/boilerplate.go.txt -# INPUT_DIR := github.com/sealerio/sealer/types/api - -## deepcopy: generate deepcopy code. -deepcopy: install-deepcopy-gen - $(DEEPCOPY_BIN) \ - --input-dirs="$(INPUT_DIR)/v1" \ - -O zz_generated.deepcopy \ - --go-header-file "$(BOILERPLATE)" \ - --output-base "${GOPATH}/src" - $(DEEPCOPY_BIN) \ - --input-dirs="$(INPUT_DIR)/v2" \ - -O zz_generated.deepcopy \ - --go-header-file "$(BOILERPLATE)" \ - --output-base "${GOPATH}/src" - ## clean: Remove all files that are created by building. .PHONY: clean clean: @$(MAKE) go.clean +## tools: Install dependent tools. +.PHONY: tools +tools: + @$(MAKE) tools.install + +## build-in-docker: sealer should be compiled in linux platform, otherwise there will be GraphDriver problem. +build-in-docker: + @docker run --rm -v ${PWD}:/usr/src/sealer -w /usr/src/sealer registry.cn-qingdao.aliyuncs.com/sealer-io/sealer-build:v1 make linux + +## gen: Generate all necessary files. +.PHONY: gen +gen: + @$(MAKE) gen.run + +## verify-copyright: Verify the license headers for all files. +.PHONY: verify-copyright +verify-copyright: + @$(MAKE) copyright.verify + +## add-copyright: Add copyright ensure source code files have license headers. +.PHONY: add-copyright +add-copyright: + @$(MAKE) copyright.add + ## help: Show this help info. .PHONY: help help: Makefile diff --git a/pkg/env/test/template/kubeadm.yaml b/pkg/env/test/template/kubeadm.yaml index 6c0ecad5ea3..ca48eb936ff 100755 --- a/pkg/env/test/template/kubeadm.yaml +++ b/pkg/env/test/template/kubeadm.yaml @@ -1,10 +1,11 @@ -# Copyright © 2023 Alibaba Group Holding Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 +apiVersion: kubeadm.k8s.io/v1beta3 +kind: ClusterConfiguration +kubernetesVersion: v1.19.8 +controlPlaneEndpoint: "apiserver.cluster.local:6443" +imageRepository: sea.hub:5000/library +networking: + podSubnet: 100.64.0.0/10 + serviceSubnet: 10.96.0.0/16e.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk index 6a411dba54f..9e3b9d1d4ef 100644 --- a/scripts/make-rules/common.mk +++ b/scripts/make-rules/common.mk @@ -17,7 +17,7 @@ # SHELL := /bin/bash -GO := go +GO:=go DIRS=$(shell ls) DEBUG ?= 0 GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) @@ -129,7 +129,6 @@ SPACE := # SPACE: Replace multiple consecutive Spaces with a single space SPACE += - # ============================================================================== # Makefile helper functions for common tasks diff --git a/scripts/make-rules/copyright.mk b/scripts/make-rules/copyright.mk index ea14fb07422..8002c92a0a5 100644 --- a/scripts/make-rules/copyright.mk +++ b/scripts/make-rules/copyright.mk @@ -17,47 +17,10 @@ # Makefile helper functions for copyright # -# filelicense: SHELL:=/bin/bash -# ## filelicense: add license for all files -# filelicense: -# for file in ${Dirs} ; do \ -# if [[ $$file != '_output' && $$file != 'docs' && $$file != 'vendor' && $$file != 'logger' && $$file != 'applications' ]]; then \ -# $(ADDLICENSE_BIN) -y $(shell date +"%Y") -c "Alibaba Group Holding Ltd." -f scripts/LICENSE_TEMPLATE ./$$file ; \ -# fi \ -# done -# -# install-addlicense: -# ifeq (, $(shell which addlicense)) -# @{ \ -# set -e ;\ -# LICENSE_TMP_DIR=$$(mktemp -d) ;\ -# cd $$LICENSE_TMP_DIR ;\ -# go mod init tmp ;\ -# go get -v github.com/google/addlicense ;\ -# rm -rf $$LICENSE_TMP_DIR ;\ -# } -# ADDLICENSE_BIN=$(GOBIN)/addlicense -# else -# ADDLICENSE_BIN=$(shell which addlicense) -# endif -# -# ## install-gosec: check license if not exist install addlicense tools. -# install-gosec: -# ifeq (, $(shell which gosec)) -# @{ \ -# set -e ;\ -# curl -sfL https://raw.githubusercontent.com/securego/gosec/master/install.sh | sh -s -- -b $(GOBIN) v2.2.0 ;\ -# } -# GOSEC_BIN=$(GOBIN)/gosec -# else -# GOSEC_BIN=$(shell which gosec) -# endif -# gosec: install-gosec -# $(GOSEC_BIN) ./... - LICENSE_TEMPLATE ?= $(ROOT_DIR)/scripts/LICENSE_TEMPLATE # TODO: GOBIN -> TOOLS_DIR +# Questions about go mod instead of go path: https://github.com/kubernetes/kubernetes/issues/117181 ## copyright.verify: Validate boilerplate headers for assign files .PHONY: copyright.verify copyright.verify: tools.verify.addlicense diff --git a/scripts/make-rules/gen.mk b/scripts/make-rules/gen.mk index 2fcf79bdae2..7519bb23485 100644 --- a/scripts/make-rules/gen.mk +++ b/scripts/make-rules/gen.mk @@ -57,10 +57,10 @@ gen.run: gen.clean gen.deepcopyV1 gen.deepcopyV2 #gen.docs BOILERPLATE := $(ROOT_DIR)/scripts/boilerplate.go.txt -INPUT_DIR := $(ROOT_DIR)/types/api/v1 -INPUT_DIRV2 := $(ROOT_DIR)/types/api/v2 -INPUT_DIRS := $(ROOT_PACKAGE)/types/api/v1 -INPUT_DIRSV2 := $(ROOT_PACKAGE)/types/api/v2 +INPUT_DIR := ./types/api/v1 +INPUT_DIRV2 := ./types/api/v2 +OUTPUT_DIRS := $(ROOT_DIR)/types/api/v1/../../.. +OUTPUT_DIRSV2 := $(ROOT_DIR)/types/api/v2/../../.. # TODO: output-base: $(ROOT_PACKAGE)/types/api/v2/...... ## gen.deepcopy: generate deepcopy v1 code @@ -68,20 +68,20 @@ INPUT_DIRSV2 := $(ROOT_PACKAGE)/types/api/v2 gen.deepcopyV1: tools.verify.deepcopy-gen @echo "===========> Generating deepcopy go source files in $(INPUT_DIRS)" @$(TOOLS_DIR)/deepcopy-gen \ - --input-dirs="$(INPUT_DIRS)" \ + --input-dirs="$(INPUT_DIR)" \ --output-file-base zz_generated.deepcopy \ --go-header-file "$(BOILERPLATE)" \ - --output-base "$(INPUT_DIR)" + --output-base "$(OUTPUT_DIRS)" ## gen.deepcopyV2: generate deepcopy v2 code .PHONY: gen.deepcopyV2 gen.deepcopyV2: tools.verify.deepcopy-gen @echo "===========> Generating deepcopy go source files in $(INPUT_DIRSV2)" @$(TOOLS_DIR)/deepcopy-gen \ - --input-dirs="$(INPUT_DIRSV2)" \ + --input-dirs="$(INPUT_DIRV2)" \ --output-file-base zz_generated.deepcopy \ --go-header-file "$(BOILERPLATE)" \ - --output-base "$()" + --output-base "$(OUTPUT_DIRSV2)" ## gen.docgo: generate doc.go .PHONY: gen.docs @@ -93,9 +93,9 @@ gen.docs: go.build .PHONY: gen.clean gen.clean: @echo "===========> Delete $(INPUT_DIR)..." -# @find $(INPUT_DIR) -type f -name '*_generated.*.go' -delete - @echo "===========> Delete $(INPUT_DIRS)" -# @find $(INPUT_DIRV2) -type f -name '*_generated.*.go' -delete + @find $(INPUT_DIR) -type f -name '*_generated.*.go' -delete + @echo "===========> Delete $(INPUT_DIRSV2)" + @find $(INPUT_DIRV2) -type f -name '*_generated.*.go' -delete ## gen.help: show help for gen .PHONY: gen.help diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index 40f46e165a9..4e8328a6b0b 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -136,15 +136,23 @@ go.build: go.build.verify $(addprefix go.build., $(addprefix $(PLATFORM)., $(BIN .PHONY: go.build.multiarch go.build.multiarch: go.build.verify $(foreach p,$(PLATFORMS),$(addprefix go.build., $(addprefix $(p)., $(BINS)))) +## go.linux.%: Build linux_amd64 binaries +.PHONY: go.linux.% +go.linux.%: + @echo "Building sealer and seautil binaries for Linux $*" + @GOOS=linux GOARCH=$* $(BUILD_SCRIPTS) $(GIT_TAG) + @echo "$(shell go version)" + @echo "===========> Building binary for Linux $* $(BUILDAPP) *[Git Info]: $(VERSION)-$(GIT_TAG)-$(GIT_COMMIT)" + ## go.lint: Run golangci to lint source codes .PHONY: go.lint go.lint: tools.verify.golangci-lint @echo "===========> Run golangci to lint source codes" - @golangci-lint run -c $(ROOT_DIR)/.golangci.yml $(ROOT_DIR)/... + @$(TOOLS_DIR)/golangci-lint run -c $(ROOT_DIR)/.golangci.yml $(ROOT_DIR)/... ## go.test: Run unit test +.PHONY: go.test go.test: - @echo "===========> Run unit test" @$(GO) test ./... ## go.test.junit-report: Run unit test @@ -173,7 +181,7 @@ go.test.cover: go.test.junit-report @$(GO) tool cover -func=$(TMP_DIR)/coverage.out | \ awk -v target=$(COVERAGE) -f $(ROOT_DIR)/scripts/coverage.awk -## go.test.format: Run unit test and format codes +## go.format: Run unit test and format codes .PHONY: go.format go.format: tools.verify.golines tools.verify.goimports @echo "===========> Formating codes" @@ -187,12 +195,6 @@ go.format: tools.verify.golines tools.verify.goimports go.imports: tools.verify.goimports @$(TOOLS_DIR)/goimports -l -w $(SRC) -## lint: Run the golangci-lint -.PHONY: go.lint -go.lint: tools.verify.golangci-lint - @echo "===========> Run golangci to lint source codes" - @$(TOOLS_DIR)/golangci-lint run -c $(ROOT_DIR)/.golangci.yml $(ROOT_DIR)/... - ## go.updates: Check for updates to go.mod dependencies .PHONY: go.updates go.updates: tools.verify.go-mod-outdated @@ -208,4 +210,4 @@ go.clean: ## copyright.help: Show copyright help .PHONY: go.help go.help: scripts/make-rules/golang.mk - $(call smallhelp) \ No newline at end of file + $(call smallhelp) diff --git a/scripts/make-rules/tools.mk b/scripts/make-rules/tools.mk index 31d5e321e58..fd81fe3ad2f 100644 --- a/scripts/make-rules/tools.mk +++ b/scripts/make-rules/tools.mk @@ -18,13 +18,13 @@ # # sealer build use BUILD_TOOLS -BUILD_TOOLS ?= golangci-lint goimports addlicense deepcopy-gen conversion-gen ginkgo junit-report +BUILD_TOOLS ?= golangci-lint goimports addlicense deepcopy-gen conversion-gen ginkgo go-junit-report # Code analysis tools ANALYSIS_TOOLS = golangci-lint goimports golines go-callvis kube-score # Code generation tools GENERATION_TOOLS = deepcopy-gen conversion-gen protoc-gen-go cfssl rts codegen # Testing tools -TEST_TOOLS = ginkgo junit-report gotests +TEST_TOOLS = ginkgo go-junit-report gotests # Version control tools VERSION_CONTROL_TOOLS = addlicense go-gitlint git-chglog github-release gsemver # Utility tools @@ -63,8 +63,6 @@ tools.verify.%: ## install.golangci-lint: Install golangci-lint install.golangci-lint: @$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@latest -# @golangci-lint completion bash > $(HOME)/.golangci-lint.bash -# @if ! grep -q .golangci-lint.bash $(HOME)/.bashrc; then echo "source \$$HOME/.golangci-lint.bash" >> $(HOME)/.bashrc; fi ## install.goimports: Install goimports, used to format go source files .PHONY: install.goimports @@ -92,7 +90,7 @@ install.conversion-gen: install.ginkgo: @$(GO) install github.com/onsi/ginkgo/ginkgo@v1.16.2 -## go-junit-report: Install go-junit-report, used to convert go test output to junit xml +## install.go-junit-report: Install go-junit-report, used to convert go test output to junit xml .PHONY: install.go-junit-report install.go-junit-report: @$(GO) install github.com/jstemmer/go-junit-report@latest diff --git a/types/api/v1/zz_generated.deepcopy.go b/types/api/v1/zz_generated.deepcopy.go index d9ce093a594..e5b280976e7 100644 --- a/types/api/v1/zz_generated.deepcopy.go +++ b/types/api/v1/zz_generated.deepcopy.go @@ -20,7 +20,7 @@ package v1 import ( - "net" + net "net" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -236,7 +236,13 @@ func (in *Hosts) DeepCopyInto(out *Hosts) { if in.IPList != nil { in, out := &in.IPList, &out.IPList *out = make([]net.IP, len(*in)) - copy(*out, *in) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = make(net.IP, len(*in)) + copy(*out, *in) + } + } } return } @@ -279,6 +285,87 @@ func (in *Image) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageArg) DeepCopyInto(out *ImageArg) { + *out = *in + if in.Parent != nil { + in, out := &in.Parent, &out.Parent + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Current != nil { + in, out := &in.Current, &out.Current + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageArg. +func (in *ImageArg) DeepCopy() *ImageArg { + if in == nil { + return nil + } + out := new(ImageArg) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageCmd) DeepCopyInto(out *ImageCmd) { + *out = *in + if in.Parent != nil { + in, out := &in.Parent, &out.Parent + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Current != nil { + in, out := &in.Current, &out.Current + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageCmd. +func (in *ImageCmd) DeepCopy() *ImageCmd { + if in == nil { + return nil + } + out := new(ImageCmd) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageConfig) DeepCopyInto(out *ImageConfig) { + *out = *in + in.Cmd.DeepCopyInto(&out.Cmd) + in.Args.DeepCopyInto(&out.Args) + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageConfig. +func (in *ImageConfig) DeepCopy() *ImageConfig { + if in == nil { + return nil + } + out := new(ImageConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImageList) DeepCopyInto(out *ImageList) { *out = *in @@ -321,7 +408,7 @@ func (in *ImageSpec) DeepCopyInto(out *ImageSpec) { copy(*out, *in) } out.Platform = in.Platform - out.ImageConfig = in.ImageConfig + in.ImageConfig.DeepCopyInto(&out.ImageConfig) return } diff --git a/types/api/v2/zz_generated.deepcopy.go b/types/api/v2/zz_generated.deepcopy.go index dfa685a7bea..d89586a26ce 100644 --- a/types/api/v2/zz_generated.deepcopy.go +++ b/types/api/v2/zz_generated.deepcopy.go @@ -20,11 +20,27 @@ package v2 import ( - "net" + net "net" runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppFile) DeepCopyInto(out *AppFile) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppFile. +func (in *AppFile) DeepCopy() *AppFile { + if in == nil { + return nil + } + out := new(AppFile) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Application) DeepCopyInto(out *Application) { *out = *in @@ -53,6 +69,32 @@ func (in *Application) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApplicationConfig) DeepCopyInto(out *ApplicationConfig) { + *out = *in + if in.Files != nil { + in, out := &in.Files, &out.Files + *out = make([]AppFile, len(*in)) + copy(*out, *in) + } + if in.Launch != nil { + in, out := &in.Launch, &out.Launch + *out = new(Launch) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationConfig. +func (in *ApplicationConfig) DeepCopy() *ApplicationConfig { + if in == nil { + return nil + } + out := new(ApplicationConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ApplicationList) DeepCopyInto(out *ApplicationList) { *out = *in @@ -89,6 +131,16 @@ func (in *ApplicationList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ApplicationSpec) DeepCopyInto(out *ApplicationSpec) { *out = *in + if in.Cmds != nil { + in, out := &in.Cmds, &out.Cmds + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.LaunchApps != nil { + in, out := &in.LaunchApps, &out.LaunchApps + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.Configs != nil { in, out := &in.Configs, &out.Configs *out = make([]ApplicationConfig, len(*in)) @@ -110,21 +162,17 @@ func (in *ApplicationSpec) DeepCopy() *ApplicationSpec { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ApplicationConfig) DeepCopyInto(out *ApplicationConfig) { +func (in *ApplicationStatus) DeepCopyInto(out *ApplicationStatus) { *out = *in - - out.Name = in.Name - out.Launch = in.Launch - return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationConfig. -func (in *ApplicationConfig) DeepCopy() *ApplicationConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationStatus. +func (in *ApplicationStatus) DeepCopy() *ApplicationStatus { if in == nil { return nil } - out := new(ApplicationConfig) + out := new(ApplicationStatus) in.DeepCopyInto(out) return out } @@ -198,6 +246,21 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.CMDArgs != nil { + in, out := &in.CMDArgs, &out.CMDArgs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.CMD != nil { + in, out := &in.CMD, &out.CMD + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.APPNames != nil { + in, out := &in.APPNames, &out.APPNames + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.Hosts != nil { in, out := &in.Hosts, &out.Hosts *out = make([]Host, len(*in)) @@ -206,6 +269,15 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { } } out.SSH = in.SSH + out.ContainerRuntime = in.ContainerRuntime + if in.HostAliases != nil { + in, out := &in.HostAliases, &out.HostAliases + *out = make([]HostAlias, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Registry.DeepCopyInto(&out.Registry) return } @@ -235,13 +307,99 @@ func (in *ClusterStatus) DeepCopy() *ClusterStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerRuntimeConfig) DeepCopyInto(out *ContainerRuntimeConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerRuntimeConfig. +func (in *ContainerRuntimeConfig) DeepCopy() *ContainerRuntimeConfig { + if in == nil { + return nil + } + out := new(ContainerRuntimeConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Delete) DeepCopyInto(out *Delete) { + *out = *in + if in.Cmds != nil { + in, out := &in.Cmds, &out.Cmds + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Delete. +func (in *Delete) DeepCopy() *Delete { + if in == nil { + return nil + } + out := new(Delete) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalRegistry) DeepCopyInto(out *ExternalRegistry) { + *out = *in + out.RegistryConfig = in.RegistryConfig + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalRegistry. +func (in *ExternalRegistry) DeepCopy() *ExternalRegistry { + if in == nil { + return nil + } + out := new(ExternalRegistry) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Helm) DeepCopyInto(out *Helm) { + *out = *in + if in.ValueFiles != nil { + in, out := &in.ValueFiles, &out.ValueFiles + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Values != nil { + in, out := &in.Values, &out.Values + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Helm. +func (in *Helm) DeepCopy() *Helm { + if in == nil { + return nil + } + out := new(Helm) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Host) DeepCopyInto(out *Host) { *out = *in if in.IPS != nil { in, out := &in.IPS, &out.IPS *out = make([]net.IP, len(*in)) - copy(*out, *in) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = make(net.IP, len(*in)) + copy(*out, *in) + } + } } if in.Roles != nil { in, out := &in.Roles, &out.Roles @@ -254,6 +412,18 @@ func (in *Host) DeepCopyInto(out *Host) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Taints != nil { + in, out := &in.Taints, &out.Taints + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -266,3 +436,209 @@ func (in *Host) DeepCopy() *Host { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HostAlias) DeepCopyInto(out *HostAlias) { + *out = *in + if in.Hostnames != nil { + in, out := &in.Hostnames, &out.Hostnames + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostAlias. +func (in *HostAlias) DeepCopy() *HostAlias { + if in == nil { + return nil + } + out := new(HostAlias) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Kubectl) DeepCopyInto(out *Kubectl) { + *out = *in + if in.FileNames != nil { + in, out := &in.FileNames, &out.FileNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Kubectl. +func (in *Kubectl) DeepCopy() *Kubectl { + if in == nil { + return nil + } + out := new(Kubectl) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Launch) DeepCopyInto(out *Launch) { + *out = *in + if in.Cmds != nil { + in, out := &in.Cmds, &out.Cmds + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Launch. +func (in *Launch) DeepCopy() *Launch { + if in == nil { + return nil + } + out := new(Launch) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalRegistry) DeepCopyInto(out *LocalRegistry) { + *out = *in + out.RegistryConfig = in.RegistryConfig + if in.HA != nil { + in, out := &in.HA, &out.HA + *out = new(bool) + **out = **in + } + if in.Insecure != nil { + in, out := &in.Insecure, &out.Insecure + *out = new(bool) + **out = **in + } + in.Cert.DeepCopyInto(&out.Cert) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalRegistry. +func (in *LocalRegistry) DeepCopy() *LocalRegistry { + if in == nil { + return nil + } + out := new(LocalRegistry) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Registry) DeepCopyInto(out *Registry) { + *out = *in + if in.LocalRegistry != nil { + in, out := &in.LocalRegistry, &out.LocalRegistry + *out = new(LocalRegistry) + (*in).DeepCopyInto(*out) + } + if in.ExternalRegistry != nil { + in, out := &in.ExternalRegistry, &out.ExternalRegistry + *out = new(ExternalRegistry) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Registry. +func (in *Registry) DeepCopy() *Registry { + if in == nil { + return nil + } + out := new(Registry) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegistryConfig) DeepCopyInto(out *RegistryConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryConfig. +func (in *RegistryConfig) DeepCopy() *RegistryConfig { + if in == nil { + return nil + } + out := new(RegistryConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Shell) DeepCopyInto(out *Shell) { + *out = *in + if in.Envs != nil { + in, out := &in.Envs, &out.Envs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.FilePaths != nil { + in, out := &in.FilePaths, &out.FilePaths + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Shell. +func (in *Shell) DeepCopy() *Shell { + if in == nil { + return nil + } + out := new(Shell) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubjectAltName) DeepCopyInto(out *SubjectAltName) { + *out = *in + if in.DNSNames != nil { + in, out := &in.DNSNames, &out.DNSNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.IPs != nil { + in, out := &in.IPs, &out.IPs + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubjectAltName. +func (in *SubjectAltName) DeepCopy() *SubjectAltName { + if in == nil { + return nil + } + out := new(SubjectAltName) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSCert) DeepCopyInto(out *TLSCert) { + *out = *in + if in.SubjectAltName != nil { + in, out := &in.SubjectAltName, &out.SubjectAltName + *out = new(SubjectAltName) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSCert. +func (in *TLSCert) DeepCopy() *TLSCert { + if in == nil { + return nil + } + out := new(TLSCert) + in.DeepCopyInto(out) + return out +} From 1b23e59e402569df840ff81ec99e07c84dd5e48e Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Sat, 6 May 2023 16:27:15 +0800 Subject: [PATCH 08/12] feat(build): add options to the build script and optimize the details of the script Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- scripts/build.sh | 144 ++++++++++++++++++++++++++--------- scripts/make-rules/common.mk | 16 ++-- scripts/make-rules/golang.mk | 4 +- scripts/make-rules/tools.mk | 7 +- 4 files changed, 126 insertions(+), 45 deletions(-) diff --git a/scripts/build.sh b/scripts/build.sh index c0112a2dce1..d8a3bee487b 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,37 +1,28 @@ -#!/bin/bash -# Copyright © 2021 Alibaba Group Holding Ltd. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# ----------------------------------------------------------------------------- -# Build management helpers. These functions help to set, save and load the -# following variables: -# -# GIT_TAG - The version for sealer. -# MULTI_PLATFORM_BUILD - Need build all platform.(linux and darwin) +#!/usr/bin/env bash +## Build script +# Build helper functions. These functions help to set up, save, and load the following variables: +# +# GIT_TAG - the version number of sealer +# MULTI_PLATFORM_BUILD - whether to build for all platforms (linux and darwin) + +# Set GO111MODULE=on to enable Go Modules when using go mod to manage dependencies export GO111MODULE=on +# Turn on command tracing so that each command is output when the script is run set -x +# Get the absolute path of the current script and set the variable SEALER_ROOT to this value SEALER_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +# Set the variables THIS_PLATFORM_BIN and THIS_PLATFORM_ASSETS for use when building binaries and assets (such as tar.gz files) export THIS_PLATFORM_BIN="${SEALER_ROOT}/_output/bin" export THIS_PLATFORM_ASSETS="${SEALER_ROOT}/_output/assets" -# fix containers dependency issue -# https://github.com/containers/image/pull/271/files -# for btrfs, we just use overlay at present, so there is no need to include btrfs, otherwise we need fix some lib problems +# Fixed container dependency issues +# Link -> https://github.com/containers/image/pull/271/files +# For btrfs, we are currently only using overlays, so we don't need to include btrfs, otherwise we need to fix some lib issues GO_BUILD_FLAGS="containers_image_openpgp exclude_graphdriver_devicemapper exclude_graphdriver_btrfs" +# Output debug information debug() { timestamp=$(date +"[%m%d %H:%M:%S]") echo "[debug] ${timestamp} ${1-}" >&2 @@ -41,6 +32,7 @@ debug() { done } +# Get version information get_version_vars() { GIT_VERSION=unknown if [[ $GIT_TAG ]]; then @@ -55,6 +47,8 @@ get_version_vars() { debug "commit id: $GIT_COMMIT" } +# Parameters used when building the program +# Used to pass parameters such as compilation time, version number, commit ID, etc. ldflags() { local -a ldflags function add_ldflag() { @@ -78,17 +72,19 @@ ldflags() { echo "${ldflags[*]-}" } +# Package path for sealer source code readonly SEALER_GO_PACKAGE=github.com/sealerio/sealer -# The server platform we are building on. +# Platforms supported when building the program readonly SEALER_SUPPORTED_PLATFORMS=( linux/amd64 linux/arm64 ) +# Check if the program needs to be built check() { timestamp=$(date +"[%m%d %H:%M:%S]") ret=$1 - if [[ $ret -eq 0 ]];then + if [[ $ret -eq 0 ]]; then echo "[info] ${timestamp} ${2-} up to date." else echo "[err] ${timestamp} ${2-} is out of date. Please run $0" @@ -96,6 +92,7 @@ check() { fi } +# Function for building the program build_binaries() { get_version_vars goldflags="${GOLDFLAGS=-s -w} $(ldflags)" @@ -124,19 +121,98 @@ build_binaries() { mv *.tar.gz* $THIS_PLATFORM_ASSETS/ debug "output tar.gz: $THIS_PLATFORM_ASSETS/seautil-$tarFile" debug "output sha256sum: $THIS_PLATFORM_ASSETS/seautil-$tarFile.sha256sum" + debug "" +} + +# Display help information +show_help() { +cat << EOF +Usage: $0 [-h] [-p PLATFORMS] [-a] [-b BINARIES] +Build Sealer binaries for one or more platforms. + DOTO: I recommend using a Makefile for a more immersive experience + + -h, --help display this help and exit + + -p, --platform build binaries for the specified platform(s), e.g. linux/amd64 or linux/arm64. + Multiple platforms should be separated by comma, e.g. linux/amd64,linux/arm64. + + -a, --all build binaries for all supported platforms + + -b, --binary build the specified binary/binaries, e.g. sealer or seautil. + Multiple binaries should be separated by comma, e.g. sealer,seautil. + (note: currently only supported in Makefile) + +EOF } +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case "$1" in + -h|--help) + show_help + exit 0 + ;; + -p|--platform) + shift + PLATFORMS=$1 + ;; + -a|--all) + ALL_PLATFORMS=true + ;; + -b|--binary) + shift + BINARIES=$1 + ;; + *) + echo "Unknown option: $1" + show_help + exit 1 + ;; + esac + shift +done + debug "root dir: $SEALER_ROOT" debug "build dir: $THIS_PLATFORM_BIN" -#Multi platform -if [[ $MULTI_PLATFORM_BUILD ]]; then - for platform in "${SEALER_SUPPORTED_PLATFORMS[@]}"; do - OS=${platform%/*} - ARCH=${platform##*/} - build_binaries $OS $ARCH - done; +# Build binaries for the specified platforms +if [[ -n "$PLATFORMS" ]]; then + IFS=',' read -ra PLATFORM_LIST <<< "$PLATFORMS" + for platform in "${PLATFORM_LIST[@]}"; do + OS=${platform%/*} + ARCH=${platform##*/} + build_binaries "$OS" "$ARCH" + done +# Build binaries for all supported platforms +elif [[ "$ALL_PLATFORMS" = true ]]; then + for platform in "${SEALER_SUPPORTED_PLATFORMS[@]}"; do + OS=${platform%/*} + ARCH=${platform##*/} + build_binaries "$OS" "$ARCH" + done +# Build the specified binaries +elif [[ -n "$BINARIES" ]]; then + IFS=',' read -ra BINARY_LIST <<< "$BINARIES" + for binary in "${BINARY_LIST[@]}"; do + case "$binary" in + sealer) + build_binaries `go env GOOS` `go env GOARCH` + ;; + seautil) + osarch=`go env GOOS`_`go env GOARCH` + GOOS=`go env GOOS` GOARCH=`go env GOARCH` go build -o $THIS_PLATFORM_BIN/seautil/$osarch/seautil -mod vendor -ldflags "$(ldflags)" $SEALER_ROOT/cmd/seautil/main.go + check $? "build seautil" + debug "output bin: $THIS_PLATFORM_BIN/seautil/$osarch/seautil" + ;; + *) + echo "Unknown binary: $binary" + show_help + exit 1 + ;; + esac + done +# Build all binaries for the current platform by default else build_binaries `go env GOOS` `go env GOARCH` -fi +fi \ No newline at end of file diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk index 9e3b9d1d4ef..1b8444159ad 100644 --- a/scripts/make-rules/common.mk +++ b/scripts/make-rules/common.mk @@ -141,14 +141,14 @@ endef # Here are some examples of builds define MAKEFILE_EXAMPLE -# make build BINS=sealer Only a single sealer binary is built -# make -j $(nproc) all Run tidy gen add-copyright format lint cover build concurrently -# make gen Generate all necessary files -# make deepcopy Generate deepcopy code -# make verify-copyright Verify the license headers for all files -# make install-deepcopy-gen Install deepcopy-gen tools if the license is missing -# make build BINS=sealer V=1 DEBUG=1 Build debug binaries for only sealer -# make build.multiarch PLATFORMS="linux_arm64 linux_amd64" V=1 Build binaries for both platforms +# make build BINS=sealer Only a single sealer binary is built. +# make -j $(nproc) all Run tidy gen add-copyright format lint cover build concurrently. +# make gen Generate all necessary files. +# make linux.arm64 sealer is compiled on arm64 platform. +# make verify-copyright Verify the license headers for all files. +# make install-deepcopy-gen Install deepcopy-gen tools if the license is missing. +# make build BINS=sealer V=1 DEBUG=1 Build debug binaries for only sealer. +# make build.multiarch PLATFORMS="linux_arm64 linux_amd64" V=1 Build binaries for both platforms. endef export MAKEFILE_EXAMPLE diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index 4e8328a6b0b..b98daf2653a 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -121,7 +121,7 @@ go.build.%: @echo "===========> Building binary $(COMMAND) $(VERSION) for $(OS) $(ARCH)" @mkdir -p $(OUTPUT_DIR)/bin/$(OS)/$(ARCH) - @CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(OUTPUT_DIR)/bin/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_PACKAGE)/cmd/$(COMMAND) +# @CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(OUTPUT_DIR)/bin/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_PACKAGE)/cmd/$(COMMAND) ## go.build: Build binaries .PHONY: go.build @@ -136,7 +136,7 @@ go.build: go.build.verify $(addprefix go.build., $(addprefix $(PLATFORM)., $(BIN .PHONY: go.build.multiarch go.build.multiarch: go.build.verify $(foreach p,$(PLATFORMS),$(addprefix go.build., $(addprefix $(p)., $(BINS)))) -## go.linux.%: Build linux_amd64 binaries +## go.linux.%: Build linux_amd64 OR linux_arm64 binaries .PHONY: go.linux.% go.linux.%: @echo "Building sealer and seautil binaries for Linux $*" diff --git a/scripts/make-rules/tools.mk b/scripts/make-rules/tools.mk index fd81fe3ad2f..96173297d3a 100644 --- a/scripts/make-rules/tools.mk +++ b/scripts/make-rules/tools.mk @@ -28,7 +28,7 @@ TEST_TOOLS = ginkgo go-junit-report gotests # Version control tools VERSION_CONTROL_TOOLS = addlicense go-gitlint git-chglog github-release gsemver # Utility tools -UTILITY_TOOLS = go-mod-outdated mockgen gothanks richgo +UTILITY_TOOLS = go-mod-outdated mockgen gothanks richgo kubeconform # All tools ALL_TOOLS ?= $(ANALYSIS_TOOLS) $(GENERATION_TOOLS) $(TEST_TOOLS) $(VERSION_CONTROL_TOOLS) $(UTILITY_TOOLS) @@ -104,6 +104,11 @@ install.go-junit-report: install.kube-score: @$(GO) install github.com/zegl/kube-score/cmd/kube-score@latest +## install.kubeconform: Install kubeconform, used to check kubernetes yaml files +.PHONY: install.kubeconform +install.kubeconform: + @$(GO) install github.com/yannh/kubeconform/cmd/kubeconform@latest + ## Install go-gitlint: Install go-gitlint, used to check git commit message .PHONY: install.go-gitlint install.go-gitlint: From d0ef7e1fc0f637ac388461dc6b1e29692509ad69 Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Sat, 6 May 2023 19:02:19 +0800 Subject: [PATCH 09/12] feat: implement multiple solutions for building Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- scripts/build.sh | 16 ++++++++++++++++ scripts/make-rules/common.mk | 2 -- scripts/make-rules/golang.mk | 32 ++++++++++++++++++-------------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/scripts/build.sh b/scripts/build.sh index d8a3bee487b..cd39880ba37 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,5 +1,21 @@ #!/usr/bin/env bash +# Copyright © 2022 Alibaba Group Holding Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ============================================================================== + ## Build script # Build helper functions. These functions help to set up, save, and load the following variables: diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk index 1b8444159ad..5d34e8a5ad7 100644 --- a/scripts/make-rules/common.mk +++ b/scripts/make-rules/common.mk @@ -83,8 +83,6 @@ endif # platforms: The OS must be linux when building docker images PLATFORMS ?= linux_amd64 linux_arm64 -# TODO(sealer?): The OS can be linux/windows/darwin when building binaries? if only support linux -# PLATFORMS ?= darwin_amd64 windows_amd64 linux_amd64 linux_arm64 # only support linux GOOS=linux diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index b98daf2653a..223a62a6568 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -33,7 +33,10 @@ ifeq ($(DEBUG), 1) GO_BUILD_FLAGS += -gcflags "all=-N -l" GO_LDFLAGS= endif -GO_BUILD_FLAGS += -tags "containers_image_openpgp netgo exclude_graphdriver_devicemapper static osusergo exclude_graphdriver_btrfs" -trimpath -ldflags "$(GO_LDFLAGS)" +# Fixed container dependency issues +# Link -> https://github.com/containers/image/pull/271/files +# For btrfs, we are currently only using overlays, so we don't need to include btrfs, otherwise we need to fix some lib issues +GO_BUILD_FLAGS += -tags "containers_image_openpgp exclude_graphdriver_devicemapper exclude_graphdriver_btrfs" # ifeq ($(GOOS),windows) # GO_OUT_EXT := .exe @@ -103,7 +106,7 @@ go.bin.%: $(eval COMMAND := $(word 2,$(subst ., ,$*))) $(eval PLATFORM := $(word 1,$(subst ., ,$*))) @echo "===========> Verifying binary $(COMMAND) $(VERSION) for $(PLATFORM)" - @if [ ! -f $(BIN_DIR)/$(PLATFORM)/$(COMMAND) ]; then echo $(MAKE) go.build PLATFORM=$(PLATFORM); fi + @if [ ! -f $(BIN_DIR)/$(COMMAND)/$(PLATFORM)/$(COMMAND) ]; then echo $(MAKE) go.build PLATFORM=$(PLATFORM); fi ## go.build.%: Build binary for specific platform .PHONY: go.build.% @@ -114,22 +117,23 @@ go.build.%: $(eval ARCH := $(word 2,$(subst _, ,$(PLATFORM)))) @echo "COMMAND=$(COMMAND)" @echo "PLATFORM=$(PLATFORM)" - @echo "OS=$(OS)" - @echo "ARCH=$(ARCH)" - @echo "BINS=$(BINS)" @echo "BIN_DIR=$(BIN_DIR)" - @echo "===========> Building binary $(COMMAND) $(VERSION) for $(OS) $(ARCH)" - @mkdir -p $(OUTPUT_DIR)/bin/$(OS)/$(ARCH) - -# @CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(OUTPUT_DIR)/bin/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_PACKAGE)/cmd/$(COMMAND) + @echo "===========> Building binary $(COMMAND) $(VERSION) for $(OS)_$(ARCH)" + @mkdir -p $(BIN_DIR)/$(COMMAND)/$(PLATFORM) + @if [ "$(COMMAND)" == "sealer" ] || [ "$(COMMAND)" == "seautil" ]; then \ + CGO_ENABLED=1; \ + CC=x86_64-linux-gnu-gcc; \ + if [ "$(ARCH)" == "arm64" ]; then \ + CC=aarch64-linux-gnu-gcc; \ + fi; \ + CGO_ENABLED=$$CGO_ENABLED CC=$$CC GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(BIN_DIR)/$(COMMAND)/$(PLATFORM) -mod vendor $(ROOT_PACKAGE)/cmd/$(COMMAND); \ + else \ + CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(BIN_DIR)/$(COMMAND)/$(PLATFORM) -mod vendor $(ROOT_PACKAGE)/cmd/$(COMMAND); \ + fi ## go.build: Build binaries .PHONY: go.build go.build: go.build.verify $(addprefix go.build., $(addprefix $(PLATFORM)., $(BINS))) - @echo "COMMAND=$(COMMAND)" - @echo "PLATFORM=$(PLATFORM)" - @echo "OS=$(OS)" - @echo "ARCH=$(ARCH)" @echo "===========> Building binary $(BINS) $(VERSION) for $(PLATFORM)" ## go.build.multiarch: Build multi-arch binaries @@ -153,7 +157,7 @@ go.lint: tools.verify.golangci-lint ## go.test: Run unit test .PHONY: go.test go.test: - @$(GO) test ./... + @$(GO) test $(GO_BUILD_FLAGS) ./... ## go.test.junit-report: Run unit test .PHONY: go.test.junit-report From 77288d10b38be0caf006fc00975e4f82505495e7 Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Sun, 7 May 2023 15:50:24 +0800 Subject: [PATCH 10/12] fix: partial makefile fixes issues Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- Makefile | 5 +++++ pkg/env/test/template/kubeadm.yaml | 15 --------------- pkg/version/base.go | 1 + pkg/version/types.go | 20 +++++++++++++++++++- scripts/make-rules/dependencies.mk | 2 +- scripts/make-rules/golang.mk | 20 +++++++++++++------- 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 09f47adf986..71ebb03e982 100644 --- a/Makefile +++ b/Makefile @@ -98,6 +98,11 @@ lint: .PHONY: style style: fmt vet lint +## linux: Build the all with a build script +.PHONY: linux +linux: + @$(MAKE) go.linux-a + ## linux.%: Build binaries for Linux (make linux.amd64 OR make linux.arm64) linux.%: @$(MAKE) go.linux.$* diff --git a/pkg/env/test/template/kubeadm.yaml b/pkg/env/test/template/kubeadm.yaml index ca48eb936ff..02ec2c0e3c7 100755 --- a/pkg/env/test/template/kubeadm.yaml +++ b/pkg/env/test/template/kubeadm.yaml @@ -1,18 +1,3 @@ -apiVersion: kubeadm.k8s.io/v1beta3 -kind: ClusterConfiguration -kubernetesVersion: v1.19.8 -controlPlaneEndpoint: "apiserver.cluster.local:6443" -imageRepository: sea.hub:5000/library -networking: - podSubnet: 100.64.0.0/10 - serviceSubnet: 10.96.0.0/16e.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration kubernetesVersion: v1.19.8 diff --git a/pkg/version/base.go b/pkg/version/base.go index 5ce150a191e..d8672dc5f03 100644 --- a/pkg/version/base.go +++ b/pkg/version/base.go @@ -57,4 +57,5 @@ var ( gitCommit = "" // sha1 from git, output of $(git rev-parse HEAD) buildDate = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ') + ) diff --git a/pkg/version/types.go b/pkg/version/types.go index 8a83cfdcff3..813b54d21b1 100644 --- a/pkg/version/types.go +++ b/pkg/version/types.go @@ -14,6 +14,8 @@ package version +import "fmt" + // Info contains versioning information. // TODO: Add []string of api versions supported? It's still unclear // how we'll want to distribute that information. @@ -28,7 +30,23 @@ type Info struct { Platform string `json:"platform"` } +type Output struct { + SealosVersion Info `json:"SealosVersion,omitempty" yaml:"SealosVersion,omitempty"` + CriRuntimeVersion *CriRuntimeVersion `json:"CriVersionInfo,omitempty" yaml:"CriVersionInfo,omitempty"` + KubernetesVersion *KubernetesVersion `json:"KubernetesVersionInfo,omitempty" yaml:"KubernetesVersionInfo,omitempty"` + KubectlVersion *KubectlVersion `json:"KubectlVersionInfo,omitempty yaml:"KubectlVersionInfo,omitempty"` +} + +type CriRuntimeVersion struct { +} + +type KubernetesVersion struct { +} + +type KubectlVersion struct { +} + // String returns info as a human-friendly version string. func (info Info) String() string { - return info.GitVersion + return fmt.Sprintf("%s-%s", info.GitVersion, info.GitCommit) } diff --git a/scripts/make-rules/dependencies.mk b/scripts/make-rules/dependencies.mk index d533d082933..de879589638 100644 --- a/scripts/make-rules/dependencies.mk +++ b/scripts/make-rules/dependencies.mk @@ -33,4 +33,4 @@ dependencies.tools.blocker: go.build.verify $(addprefix tools.verify., $(BLOCKER dependencies.tools.critical: $(addprefix tools.verify., $(CRITICAL_TOOLS)) .PHONY: dependencies.tools.trivial -dependencies.tools.trivial: $(addprefix tools.verify., $(TRIVIAL_TOOLS)) \ No newline at end of file +dependencies.tools.trivial: $(addprefix tools.verify., $(TRIVIAL_TOOLS)) diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index 223a62a6568..c8197d802b3 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -25,10 +25,10 @@ GO_LDFLAGS += -X $(VERSION_PACKAGE).gitVersion=${GIT_TAG} \ -X $(VERSION_PACKAGE).GitTreeState=$(GIT_TREE_STATE) \ -X $(VERSION_PACKAGE).buildDate=${BUILD_DATE} \ -s -w # -s -w deletes debugging information and symbol tables -# ifneq ($(DLV),) -# GO_BUILD_FLAGS += -gcflags "all=-N -l" -# LDFLAGS = "" -# endif +ifneq ($(DLV),) + GO_BUILD_FLAGS += -gcflags "all=-N -l" + LDFLAGS = "" +endif ifeq ($(DEBUG), 1) GO_BUILD_FLAGS += -gcflags "all=-N -l" GO_LDFLAGS= @@ -126,7 +126,7 @@ go.build.%: if [ "$(ARCH)" == "arm64" ]; then \ CC=aarch64-linux-gnu-gcc; \ fi; \ - CGO_ENABLED=$$CGO_ENABLED CC=$$CC GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(BIN_DIR)/$(COMMAND)/$(PLATFORM) -mod vendor $(ROOT_PACKAGE)/cmd/$(COMMAND); \ + CGO_ENABLED=$$CGO_ENABLED CC=$$CC GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(BIN_DIR)/$(COMMAND)/$(PLATFORM) $(ROOT_PACKAGE)/cmd/$(COMMAND); \ else \ CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(BIN_DIR)/$(COMMAND)/$(PLATFORM) -mod vendor $(ROOT_PACKAGE)/cmd/$(COMMAND); \ fi @@ -140,11 +140,17 @@ go.build: go.build.verify $(addprefix go.build., $(addprefix $(PLATFORM)., $(BIN .PHONY: go.build.multiarch go.build.multiarch: go.build.verify $(foreach p,$(PLATFORMS),$(addprefix go.build., $(addprefix $(p)., $(BINS)))) +## go.linux-a: Build the project with a build script, use: ./scripts/build.sh -h +.PHONY: go.linux-a +go.linux-a: + @chmod +x $(BUILD_SCRIPTS) + @$(BUILD_SCRIPTS) -a + ## go.linux.%: Build linux_amd64 OR linux_arm64 binaries .PHONY: go.linux.% go.linux.%: @echo "Building sealer and seautil binaries for Linux $*" - @GOOS=linux GOARCH=$* $(BUILD_SCRIPTS) $(GIT_TAG) + @chmod +x $(BUILD_SCRIPTS);GOOS=linux GOARCH=$* $(BUILD_SCRIPTS) -p linux/$* @echo "$(shell go version)" @echo "===========> Building binary for Linux $* $(BUILDAPP) *[Git Info]: $(VERSION)-$(GIT_TAG)-$(GIT_COMMIT)" @@ -163,7 +169,7 @@ go.test: .PHONY: go.test.junit-report go.test.junit-report: tools.verify.go-junit-report @echo "===========> Run unit test > $(TMP_DIR)/report.xml" - @$(GO) test -v -coverprofile=$(TMP_DIR)/coverage.out 2>&1 ./... | $(TOOLS_DIR)/go-junit-report -set-exit-code > $(TMP_DIR)/report.xml + @$(GO) test -v -coverprofile=$(TMP_DIR)/coverage.out 2>&1 $(GO_BUILD_FLAGS) ./... | $(TOOLS_DIR)/go-junit-report -set-exit-code > $(TMP_DIR)/report.xml @sed -i '/mock_.*.go/d' $(TMP_DIR)/coverage.out @echo "===========> Test coverage of Go code is reported to $(TMP_DIR)/coverage.html by generating HTML" @$(GO) tool cover -html=$(TMP_DIR)/coverage.out -o $(TMP_DIR)/coverage.html From 7c086967e1ee44d33e095780639b0ee006edf6ad Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Sun, 7 May 2023 19:40:32 +0800 Subject: [PATCH 11/12] feat: more friendly output from sealer version is supported Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- cmd/sealer/cmd/version.go | 76 +- cmd/seautil/cmd/version.go | 83 +- go.mod | 4 + go.sum | 4 + pkg/version/base.go | 5 +- pkg/version/types.go | 62 +- pkg/version/version.go | 45 +- scripts/build.sh | 2 +- scripts/make-rules/common.mk | 2 +- scripts/make-rules/golang.mk | 26 +- vendor/github.com/fatih/color/LICENSE.md | 20 + vendor/github.com/fatih/color/README.md | 178 +++ vendor/github.com/fatih/color/color.go | 618 ++++++++++ vendor/github.com/fatih/color/doc.go | 135 +++ vendor/github.com/gosuri/uitable/.travis.yml | 6 + vendor/github.com/gosuri/uitable/LICENSE | 10 + vendor/github.com/gosuri/uitable/Makefile | 4 + vendor/github.com/gosuri/uitable/README.md | 67 ++ vendor/github.com/gosuri/uitable/table.go | 205 ++++ .../gosuri/uitable/util/strutil/strutil.go | 101 ++ .../gosuri/uitable/util/wordwrap/LICENSE.md | 21 + .../gosuri/uitable/util/wordwrap/README.md | 39 + .../gosuri/uitable/util/wordwrap/wordwrap.go | 85 ++ vendor/github.com/mattn/go-colorable/LICENSE | 21 + .../github.com/mattn/go-colorable/README.md | 48 + .../mattn/go-colorable/colorable_appengine.go | 38 + .../mattn/go-colorable/colorable_others.go | 38 + .../mattn/go-colorable/colorable_windows.go | 1047 +++++++++++++++++ .../github.com/mattn/go-colorable/go.test.sh | 12 + .../mattn/go-colorable/noncolorable.go | 57 + vendor/github.com/mattn/go-isatty/LICENSE | 9 + vendor/github.com/mattn/go-isatty/README.md | 50 + vendor/github.com/mattn/go-isatty/doc.go | 2 + vendor/github.com/mattn/go-isatty/go.test.sh | 12 + .../github.com/mattn/go-isatty/isatty_bsd.go | 19 + .../mattn/go-isatty/isatty_others.go | 16 + .../mattn/go-isatty/isatty_plan9.go | 23 + .../mattn/go-isatty/isatty_solaris.go | 21 + .../mattn/go-isatty/isatty_tcgets.go | 19 + .../mattn/go-isatty/isatty_windows.go | 125 ++ vendor/modules.txt | 14 + 41 files changed, 3306 insertions(+), 63 deletions(-) create mode 100644 vendor/github.com/fatih/color/LICENSE.md create mode 100644 vendor/github.com/fatih/color/README.md create mode 100644 vendor/github.com/fatih/color/color.go create mode 100644 vendor/github.com/fatih/color/doc.go create mode 100644 vendor/github.com/gosuri/uitable/.travis.yml create mode 100644 vendor/github.com/gosuri/uitable/LICENSE create mode 100644 vendor/github.com/gosuri/uitable/Makefile create mode 100644 vendor/github.com/gosuri/uitable/README.md create mode 100644 vendor/github.com/gosuri/uitable/table.go create mode 100644 vendor/github.com/gosuri/uitable/util/strutil/strutil.go create mode 100644 vendor/github.com/gosuri/uitable/util/wordwrap/LICENSE.md create mode 100644 vendor/github.com/gosuri/uitable/util/wordwrap/README.md create mode 100644 vendor/github.com/gosuri/uitable/util/wordwrap/wordwrap.go create mode 100644 vendor/github.com/mattn/go-colorable/LICENSE create mode 100644 vendor/github.com/mattn/go-colorable/README.md create mode 100644 vendor/github.com/mattn/go-colorable/colorable_appengine.go create mode 100644 vendor/github.com/mattn/go-colorable/colorable_others.go create mode 100644 vendor/github.com/mattn/go-colorable/colorable_windows.go create mode 100644 vendor/github.com/mattn/go-colorable/go.test.sh create mode 100644 vendor/github.com/mattn/go-colorable/noncolorable.go create mode 100644 vendor/github.com/mattn/go-isatty/LICENSE create mode 100644 vendor/github.com/mattn/go-isatty/README.md create mode 100644 vendor/github.com/mattn/go-isatty/doc.go create mode 100644 vendor/github.com/mattn/go-isatty/go.test.sh create mode 100644 vendor/github.com/mattn/go-isatty/isatty_bsd.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_others.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_plan9.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_solaris.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_tcgets.go create mode 100644 vendor/github.com/mattn/go-isatty/isatty_windows.go diff --git a/cmd/sealer/cmd/version.go b/cmd/sealer/cmd/version.go index bf9fcea467a..0f9b9793ad7 100644 --- a/cmd/sealer/cmd/version.go +++ b/cmd/sealer/cmd/version.go @@ -19,31 +19,89 @@ import ( "fmt" "github.com/spf13/cobra" + "gopkg.in/yaml.v2" "github.com/sealerio/sealer/pkg/version" ) -var shortPrint bool +var ( + shortPrint bool + output string +) +var sealerErr error func NewVersionCmd() *cobra.Command { versionCmd := &cobra.Command{ Use: "version", - Short: "show sealer and related versions", + Short: "Print version info", Args: cobra.NoArgs, Example: `sealer version`, RunE: func(cmd *cobra.Command, args []string) error { - marshalled, err := json.Marshal(version.Get()) - if err != nil { - return err + // Validate validates the provided options. + if output != "" && output != "yaml" && output != "json" { + return fmt.Errorf("output format must be yaml or json") } if shortPrint { fmt.Println(version.Get().String()) - } else { - fmt.Println(string(marshalled)) + return nil } - return nil + return PrintInfo() }, } - versionCmd.Flags().BoolVar(&shortPrint, "short", false, "if true, print sealer's own version number.") + versionCmd.Flags().BoolVar(&shortPrint, "short", false, "If true, print just the version number.") + versionCmd.Flags().StringVarP(&output, "output", "o", "yaml", "choose `yaml` or `json` format to print version info") return versionCmd } + +func PrintInfo() error { + OutputInfo := &version.Output{} + OutputInfo.SealerVersion = version.Get() + + if err := PrintToStd(OutputInfo); err != nil { + return err + } + //TODO! + // missinfo := []string{} + // if OutputInfo.KubernetesVersion == nil { + // missinfo = append(missinfo, "kubernetes version") + // } + // if OutputInfo.CriRuntimeVersion == nil { + // missinfo = append(missinfo, "cri runtime version") + // } + // if OutputInfo.KubernetesVersion == nil || OutputInfo.CriRuntimeVersion == nil { + // fmt.Printf("WARNING: Failed to get %s.\nCheck kubernetes status or use command \"sealer run\" to launch kubernetes\n", strings.Join(missinfo, " and ")) + // } + // if OutputInfo.K0sVersion == nil { + // fmt.Println("WARNING: Failed to get k0s version.\nCheck k0s status or use command \"sealer run\" to launch k0s\n") + // } + // if OutputInfo.K3sVersion == nil { + // fmt.Println("WARNING: Failed to get k3s version.\nCheck k3s status or use command \"sealer run\" to launch k3s\n") + // } + return nil +} + +func PrintToStd(OutputInfo *version.Output) error { + var ( + marshalled []byte + err error + ) + switch output { + case "yaml": + marshalled, err = yaml.Marshal(&OutputInfo) + if err != nil { + return fmt.Errorf("fail to marshal yaml: %w", err) + } + fmt.Println(string(marshalled)) + case "json": + marshalled, err = json.Marshal(&OutputInfo) + if err != nil { + return fmt.Errorf("fail to marshal json: %w", err) + } + fmt.Println(string(marshalled)) + default: + // There is a bug in the program if we hit this case. + // However, we follow a policy of never panicking. + return fmt.Errorf("versionOptions were not validated: --output=%q should have been rejected", output) + } + return sealerErr +} diff --git a/cmd/seautil/cmd/version.go b/cmd/seautil/cmd/version.go index c8ce73419cf..21a56becf2b 100644 --- a/cmd/seautil/cmd/version.go +++ b/cmd/seautil/cmd/version.go @@ -16,35 +16,90 @@ package cmd import ( "encoding/json" - "fmt" //nolint:imports - "os" + "fmt" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "gopkg.in/yaml.v2" "github.com/sealerio/sealer/pkg/version" ) -var shortPrint bool +var ( + shortPrint bool + output string +) func NewVersionCmd() *cobra.Command { versionCmd := &cobra.Command{ - Use: "version", - Short: "version", - Long: `sealer version`, - Run: func(cmd *cobra.Command, args []string) { - marshalled, err := json.Marshal(version.Get()) - if err != nil { - logrus.Error(err) - os.Exit(1) + Use: "version", + Short: "Print version info", + Args: cobra.NoArgs, + Example: `seautil version`, + RunE: func(cmd *cobra.Command, args []string) error { + //output default to be yaml + if output == "yaml" && output == "json" { + return fmt.Errorf("output format must be yaml or json") } if shortPrint { fmt.Println(version.Get().String()) - } else { - fmt.Println(string(marshalled)) + return nil } + return PrintInfo() }, } versionCmd.Flags().BoolVar(&shortPrint, "short", false, "If true, print just the version number.") + versionCmd.Flags().StringVarP(&output, "output", "o", "yaml", "choose `yaml` or `json` format to print version info") return versionCmd } + +func PrintInfo() error { + OutputInfo := &version.Output{} + OutputInfo.SealerVersion = version.Get() + + if err := PrintToStd(OutputInfo); err != nil { + return err + } + // missinfo := []string{} + // if OutputInfo.KubernetesVersion == nil { + // missinfo = append(missinfo, "kubernetes version") + // } + // if OutputInfo.CriRuntimeVersion == nil { + // missinfo = append(missinfo, "cri runtime version") + // } + // if OutputInfo.KubernetesVersion == nil || OutputInfo.CriRuntimeVersion == nil { + // fmt.Printf("WARNING: Failed to get %s.\nCheck kubernetes status or use command \"sealer run\" to launch kubernetes\n", strings.Join(missinfo, " and ")) + // } + // if OutputInfo.K0sVersion == nil { + // fmt.Println("WARNING: Failed to get k0s version.\nCheck k0s status or use command \"sealer run\" to launch k0s\n") + // } + // if OutputInfo.K3sVersion == nil { + // fmt.Println("WARNING: Failed to get k3s version.\nCheck k3s status or use command \"sealer run\" to launch k3s\n") + // } + return nil +} + +func PrintToStd(OutputInfo *version.Output) error { + var ( + marshalled []byte + err error + ) + switch output { + case "yaml": + marshalled, err = yaml.Marshal(&OutputInfo) + if err != nil { + return fmt.Errorf("fail to marshal yaml: %w", err) + } + fmt.Println(string(marshalled)) + case "json": + marshalled, err = json.Marshal(&OutputInfo) + if err != nil { + return fmt.Errorf("fail to marshal json: %w", err) + } + fmt.Println(string(marshalled)) + default: + // There is a bug in the program if we hit this case. + // However, we follow a policy of never panicking. + return fmt.Errorf("versionOptions were not validated: --output=%q should have been rejected", output) + } + return nil +} diff --git a/go.mod b/go.mod index e71805ffe05..28ca087b0ac 100644 --- a/go.mod +++ b/go.mod @@ -89,6 +89,7 @@ require ( github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/emicklei/go-restful/v3 v3.8.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/fsouza/go-dockerclient v1.8.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect @@ -108,6 +109,7 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gorilla/mux v1.8.0 // indirect + github.com/gosuri/uitable v0.0.4 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -127,6 +129,8 @@ require ( github.com/magiconair/properties v1.8.5 // indirect github.com/mailru/easyjson v0.7.6 // indirect github.com/manifoldco/promptui v0.9.0 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect diff --git a/go.sum b/go.sum index 89f651a5a87..6f6e707c28d 100644 --- a/go.sum +++ b/go.sum @@ -614,6 +614,7 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= @@ -1015,6 +1016,7 @@ github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/g github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= +github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -1346,6 +1348,7 @@ github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= @@ -1360,6 +1363,7 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= diff --git a/pkg/version/base.go b/pkg/version/base.go index d8672dc5f03..4923ab07d6c 100644 --- a/pkg/version/base.go +++ b/pkg/version/base.go @@ -53,9 +53,12 @@ var ( // NOTE: The $Format strings are replaced during 'git archive' thanks to the // companion .gitattributes file containing 'export-subst' in this same // directory. See also https://git-scm.com/docs/gitattributes - gitVersion = "unknown" + // GitVersion is semantic version. + gitVersion = "v0.0.0-main+$Format:%h$" gitCommit = "" // sha1 from git, output of $(git rev-parse HEAD) buildDate = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ') + // GitTreeState state of git tree, either "clean" or "dirty". + gitTreeState = "" ) diff --git a/pkg/version/types.go b/pkg/version/types.go index 813b54d21b1..e442856faf8 100644 --- a/pkg/version/types.go +++ b/pkg/version/types.go @@ -14,39 +14,77 @@ package version -import "fmt" +import ( + "fmt" +) // Info contains versioning information. // TODO: Add []string of api versions supported? It's still unclear // how we'll want to distribute that information. type Info struct { - Major string `json:"major,omitempty"` - Minor string `json:"minor,omitempty"` - GitVersion string `json:"gitVersion"` - GitCommit string `json:"gitCommit,omitempty"` - BuildDate string `json:"buildDate"` - GoVersion string `json:"goVersion"` - Compiler string `json:"compiler"` - Platform string `json:"platform"` + Major string `json:"major,omitempty"` + Minor string `json:"minor,omitempty"` + GitVersion string `json:"gitVersion"` + GitCommit string `json:"gitCommit,omitempty"` + GitTreeState string `json:"gitTreeState"` + BuildDate string `json:"buildDate"` + GoVersion string `json:"goVersion"` + Compiler string `json:"compiler"` + Platform string `json:"platform"` } type Output struct { - SealosVersion Info `json:"SealosVersion,omitempty" yaml:"SealosVersion,omitempty"` + SealerVersion Info `json:"Version,omitempty" yaml:"SealerVersion,omitempty"` CriRuntimeVersion *CriRuntimeVersion `json:"CriVersionInfo,omitempty" yaml:"CriVersionInfo,omitempty"` KubernetesVersion *KubernetesVersion `json:"KubernetesVersionInfo,omitempty" yaml:"KubernetesVersionInfo,omitempty"` - KubectlVersion *KubectlVersion `json:"KubectlVersionInfo,omitempty yaml:"KubectlVersionInfo,omitempty"` + K0sVersion *k0sVersion `json:"k0sVersionInfo,omitempty" yaml:"k0sVersionInfo,omitempty"` + K3sVersion *k3sVersion `json:"k3sVersionInfo,omitempty" yaml:"k3sVersionInfo,omitempty"` } type CriRuntimeVersion struct { + // Version of the kubelet runtime API. + Version string `json:"Version,omitempty" yaml:"Version,omitempty"` + // Name of the container runtime. + RuntimeName string `json:"RuntimeName,omitempty" yaml:"RuntimeName,omitempty"` + // Version of the container runtime. The string must be + // semver-compatible. + RuntimeVersion string `json:"RuntimeVersion,omitempty" yaml:"RuntimeVersion,omitempty"` + // API version of the container runtime. The string must be + // semver-compatible. + RuntimeAPIVersion string `json:"RuntimeApiVersion,omitempty" yaml:"RuntimeApiVersion,omitempty"` } type KubernetesVersion struct { + ClientVersion *KubectlInfo `json:"clientVersion,omitempty" yaml:"clientVersion,omitempty"` + KustomizeVersion string `json:"kustomizeVersion,omitempty" yaml:"kustomizeVersion,omitempty"` + ServerVersion *KubectlInfo `json:"serverVersion,omitempty" yaml:"serverVersion,omitempty"` } -type KubectlVersion struct { +type k0sVersion struct { + K0sVersion string `json:"k9sVersion,omitempty" yaml:"k0sVersion,omitempty"` +} + +type k3sVersion struct { + K3sVersion string `json:"k3sVersion,omitempty" yaml:"k3sVersion,omitempty"` +} + +type KubectlInfo struct { + Major string `json:"major" yaml:"major"` + Minor string `json:"minor" yaml:"minor"` + GitVersion string `json:"gitVersion" yaml:"gitVersion"` + GitCommit string `json:"gitCommit" yaml:"gitCommit"` + GitTreeState string `json:"gitTreeState" yaml:"gitTreeState"` + BuildDate string `json:"buildDate" yaml:"buildDate"` + GoVersion string `json:"goVersion" yaml:"goVersion"` + Compiler string `json:"compiler" yaml:"compiler"` + Platform string `json:"platform" yaml:"platform"` } // String returns info as a human-friendly version string. func (info Info) String() string { + if s, err := info.Text(); err == nil { + return string(s) + } + return fmt.Sprintf("%s-%s", info.GitVersion, info.GitCommit) } diff --git a/pkg/version/version.go b/pkg/version/version.go index 0bfafb5fd37..4f99cad3a5c 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -15,8 +15,11 @@ package version import ( + "encoding/json" "fmt" "runtime" + + "github.com/gosuri/uitable" ) // Get returns the overall codebase version. It's for detecting @@ -25,18 +28,44 @@ func Get() Info { // These variables typically come from -ldflags settings and in // their absence fallback to the settings in ./base.go return Info{ - Major: gitMajor, - Minor: gitMinor, - GitVersion: gitVersion, - GitCommit: gitCommit, - BuildDate: buildDate, - GoVersion: runtime.Version(), - Compiler: runtime.Compiler, - Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), + Major: gitMajor, + Minor: gitMinor, + GitVersion: gitVersion, + GitCommit: gitCommit, + GitTreeState: gitTreeState, + BuildDate: buildDate, + GoVersion: runtime.Version(), + Compiler: runtime.Compiler, + Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), } } + // GetSingleVersion returns single version of sealer func GetSingleVersion() string { return gitVersion } + +func (info Info) ToJSON() string { + s, _ := json.Marshal(info) + + return string(s) +} + +// Text encodes the version information into UTF-8-encoded text and +// returns the result. +func (info Info) Text() ([]byte, error) { + table := uitable.New() + table.RightAlign(0) + table.MaxColWidth = 80 + table.Separator = " " + table.AddRow("gitVersion:", info.GitVersion) + table.AddRow("gitCommit:", info.GitCommit) + table.AddRow("gitTreeState:", info.GitTreeState) + table.AddRow("buildDate:", info.BuildDate) + table.AddRow("goVersion:", info.GoVersion) + table.AddRow("compiler:", info.Compiler) + table.AddRow("platform:", info.Platform) + + return table.Bytes(), nil +} diff --git a/scripts/build.sh b/scripts/build.sh index cd39880ba37..5e7303e8c81 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -72,7 +72,7 @@ ldflags() { local val=${2} # If you update these, also update the list component-base/version/def.bzl. ldflags+=( - "-X '${SEALER_GO_PACKAGE}/version.${key}=${val}'" + "-X '${SEALER_GO_PACKAGE}/pkg/version.${key}=${val}'" ) } add_ldflag "buildDate" "$(date "+%FT %T %z")" diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk index 5d34e8a5ad7..2e588b8d6d9 100644 --- a/scripts/make-rules/common.mk +++ b/scripts/make-rules/common.mk @@ -22,7 +22,7 @@ DIRS=$(shell ls) DEBUG ?= 0 GIT_TAG := $(shell git describe --exact-match --tags --abbrev=0 2> /dev/null || echo untagged) GIT_COMMIT ?= $(shell git rev-parse --short HEAD || echo "0.0.0") -BUILD_DATE=$(shell date '+%FT %T %z') # "buildDate":"2023-03-31T 20:05:43 +0800" +BUILD_DATE ?=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ') # Blank error: date '+%FT %T %z':"buildDate":"2023-03-31T 20:05:43 +0800" # include the common makefile COMMON_SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index c8197d802b3..f92a9fc70e1 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -20,15 +20,11 @@ GO := go # ! go 1.8 some packages fail to be pulled out. You are advised to use the gvm switchover version of the tools toolkit GO_SUPPORTED_VERSIONS ?= |1.17|1.18|1.19|1.20| -GO_LDFLAGS += -X $(VERSION_PACKAGE).gitVersion=${GIT_TAG} \ - -X $(VERSION_PACKAGE).gitCommit=${GIT_COMMIT} \ - -X $(VERSION_PACKAGE).GitTreeState=$(GIT_TREE_STATE) \ - -X $(VERSION_PACKAGE).buildDate=${BUILD_DATE} \ +GO_LDFLAGS += -X $(VERSION_PACKAGE).gitVersion=$(GIT_TAG) \ + -X $(VERSION_PACKAGE).gitCommit=$(GIT_COMMIT) \ + -X $(VERSION_PACKAGE).gitTreeState=$(GIT_TREE_STATE) \ + -X $(VERSION_PACKAGE).buildDate=$(BUILD_DATE) \ -s -w # -s -w deletes debugging information and symbol tables -ifneq ($(DLV),) - GO_BUILD_FLAGS += -gcflags "all=-N -l" - LDFLAGS = "" -endif ifeq ($(DEBUG), 1) GO_BUILD_FLAGS += -gcflags "all=-N -l" GO_LDFLAGS= @@ -36,11 +32,7 @@ endif # Fixed container dependency issues # Link -> https://github.com/containers/image/pull/271/files # For btrfs, we are currently only using overlays, so we don't need to include btrfs, otherwise we need to fix some lib issues -GO_BUILD_FLAGS += -tags "containers_image_openpgp exclude_graphdriver_devicemapper exclude_graphdriver_btrfs" - -# ifeq ($(GOOS),windows) -# GO_OUT_EXT := .exe -# endif +GO_BUILD_FLAGS += -tags "containers_image_openpgp exclude_graphdriver_devicemapper exclude_graphdriver_btrfs" -trimpath -ldflags "$(GO_LDFLAGS)" ifeq ($(ROOT_PACKAGE),) $(error the variable ROOT_PACKAGE must be set prior to including golang.mk, ->/Makefile) @@ -115,9 +107,9 @@ go.build.%: $(eval PLATFORM := $(word 1,$(subst ., ,$*))) $(eval OS := $(word 1,$(subst _, ,$(PLATFORM)))) $(eval ARCH := $(word 2,$(subst _, ,$(PLATFORM)))) - @echo "COMMAND=$(COMMAND)" - @echo "PLATFORM=$(PLATFORM)" - @echo "BIN_DIR=$(BIN_DIR)" + @echo "=====> COMMAND=$(COMMAND)" + @echo "=====> PLATFORM=$(PLATFORM)" + @echo "=====> BIN_DIR=$(BIN_DIR)" @echo "===========> Building binary $(COMMAND) $(VERSION) for $(OS)_$(ARCH)" @mkdir -p $(BIN_DIR)/$(COMMAND)/$(PLATFORM) @if [ "$(COMMAND)" == "sealer" ] || [ "$(COMMAND)" == "seautil" ]; then \ @@ -136,7 +128,7 @@ go.build.%: go.build: go.build.verify $(addprefix go.build., $(addprefix $(PLATFORM)., $(BINS))) @echo "===========> Building binary $(BINS) $(VERSION) for $(PLATFORM)" -## go.build.multiarch: Build multi-arch binaries +## go.multiarch: Build multi-arch binaries .PHONY: go.build.multiarch go.build.multiarch: go.build.verify $(foreach p,$(PLATFORMS),$(addprefix go.build., $(addprefix $(p)., $(BINS)))) diff --git a/vendor/github.com/fatih/color/LICENSE.md b/vendor/github.com/fatih/color/LICENSE.md new file mode 100644 index 00000000000..25fdaf639df --- /dev/null +++ b/vendor/github.com/fatih/color/LICENSE.md @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Fatih Arslan + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/fatih/color/README.md b/vendor/github.com/fatih/color/README.md new file mode 100644 index 00000000000..5152bf59bf8 --- /dev/null +++ b/vendor/github.com/fatih/color/README.md @@ -0,0 +1,178 @@ +# color [![](https://github.com/fatih/color/workflows/build/badge.svg)](https://github.com/fatih/color/actions) [![PkgGoDev](https://pkg.go.dev/badge/github.com/fatih/color)](https://pkg.go.dev/github.com/fatih/color) + +Color lets you use colorized outputs in terms of [ANSI Escape +Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It +has support for Windows too! The API can be used in several ways, pick one that +suits you. + +![Color](https://user-images.githubusercontent.com/438920/96832689-03b3e000-13f4-11eb-9803-46f4c4de3406.jpg) + + +## Install + +```bash +go get github.com/fatih/color +``` + +## Examples + +### Standard colors + +```go +// Print with default helper functions +color.Cyan("Prints text in cyan.") + +// A newline will be appended automatically +color.Blue("Prints %s in blue.", "text") + +// These are using the default foreground colors +color.Red("We have red") +color.Magenta("And many others ..") + +``` + +### Mix and reuse colors + +```go +// Create a new color object +c := color.New(color.FgCyan).Add(color.Underline) +c.Println("Prints cyan text with an underline.") + +// Or just add them to New() +d := color.New(color.FgCyan, color.Bold) +d.Printf("This prints bold cyan %s\n", "too!.") + +// Mix up foreground and background colors, create new mixes! +red := color.New(color.FgRed) + +boldRed := red.Add(color.Bold) +boldRed.Println("This will print text in bold red.") + +whiteBackground := red.Add(color.BgWhite) +whiteBackground.Println("Red text with white background.") +``` + +### Use your own output (io.Writer) + +```go +// Use your own io.Writer output +color.New(color.FgBlue).Fprintln(myWriter, "blue color!") + +blue := color.New(color.FgBlue) +blue.Fprint(writer, "This will print text in blue.") +``` + +### Custom print functions (PrintFunc) + +```go +// Create a custom print function for convenience +red := color.New(color.FgRed).PrintfFunc() +red("Warning") +red("Error: %s", err) + +// Mix up multiple attributes +notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() +notice("Don't forget this...") +``` + +### Custom fprint functions (FprintFunc) + +```go +blue := color.New(color.FgBlue).FprintfFunc() +blue(myWriter, "important notice: %s", stars) + +// Mix up with multiple attributes +success := color.New(color.Bold, color.FgGreen).FprintlnFunc() +success(myWriter, "Don't forget this...") +``` + +### Insert into noncolor strings (SprintFunc) + +```go +// Create SprintXxx functions to mix strings with other non-colorized strings: +yellow := color.New(color.FgYellow).SprintFunc() +red := color.New(color.FgRed).SprintFunc() +fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error")) + +info := color.New(color.FgWhite, color.BgGreen).SprintFunc() +fmt.Printf("This %s rocks!\n", info("package")) + +// Use helper functions +fmt.Println("This", color.RedString("warning"), "should be not neglected.") +fmt.Printf("%v %v\n", color.GreenString("Info:"), "an important message.") + +// Windows supported too! Just don't forget to change the output to color.Output +fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) +``` + +### Plug into existing code + +```go +// Use handy standard colors +color.Set(color.FgYellow) + +fmt.Println("Existing text will now be in yellow") +fmt.Printf("This one %s\n", "too") + +color.Unset() // Don't forget to unset + +// You can mix up parameters +color.Set(color.FgMagenta, color.Bold) +defer color.Unset() // Use it in your function + +fmt.Println("All text will now be bold magenta.") +``` + +### Disable/Enable color + +There might be a case where you want to explicitly disable/enable color output. the +`go-isatty` package will automatically disable color output for non-tty output streams +(for example if the output were piped directly to `less`). + +The `color` package also disables color output if the [`NO_COLOR`](https://no-color.org) environment +variable is set (regardless of its value). + +`Color` has support to disable/enable colors programatically both globally and +for single color definitions. For example suppose you have a CLI app and a +`--no-color` bool flag. You can easily disable the color output with: + +```go +var flagNoColor = flag.Bool("no-color", false, "Disable color output") + +if *flagNoColor { + color.NoColor = true // disables colorized output +} +``` + +It also has support for single color definitions (local). You can +disable/enable color output on the fly: + +```go +c := color.New(color.FgCyan) +c.Println("Prints cyan text") + +c.DisableColor() +c.Println("This is printed without any color") + +c.EnableColor() +c.Println("This prints again cyan...") +``` + +## GitHub Actions + +To output color in GitHub Actions (or other CI systems that support ANSI colors), make sure to set `color.NoColor = false` so that it bypasses the check for non-tty output streams. + +## Todo + +* Save/Return previous values +* Evaluate fmt.Formatter interface + + +## Credits + + * [Fatih Arslan](https://github.com/fatih) + * Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) + +## License + +The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go new file mode 100644 index 00000000000..98a60f3c88d --- /dev/null +++ b/vendor/github.com/fatih/color/color.go @@ -0,0 +1,618 @@ +package color + +import ( + "fmt" + "io" + "os" + "strconv" + "strings" + "sync" + + "github.com/mattn/go-colorable" + "github.com/mattn/go-isatty" +) + +var ( + // NoColor defines if the output is colorized or not. It's dynamically set to + // false or true based on the stdout's file descriptor referring to a terminal + // or not. It's also set to true if the NO_COLOR environment variable is + // set (regardless of its value). This is a global option and affects all + // colors. For more control over each color block use the methods + // DisableColor() individually. + NoColor = noColorExists() || os.Getenv("TERM") == "dumb" || + (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) + + // Output defines the standard output of the print functions. By default + // os.Stdout is used. + Output = colorable.NewColorableStdout() + + // Error defines a color supporting writer for os.Stderr. + Error = colorable.NewColorableStderr() + + // colorsCache is used to reduce the count of created Color objects and + // allows to reuse already created objects with required Attribute. + colorsCache = make(map[Attribute]*Color) + colorsCacheMu sync.Mutex // protects colorsCache +) + +// noColorExists returns true if the environment variable NO_COLOR exists. +func noColorExists() bool { + _, exists := os.LookupEnv("NO_COLOR") + return exists +} + +// Color defines a custom color object which is defined by SGR parameters. +type Color struct { + params []Attribute + noColor *bool +} + +// Attribute defines a single SGR Code +type Attribute int + +const escape = "\x1b" + +// Base attributes +const ( + Reset Attribute = iota + Bold + Faint + Italic + Underline + BlinkSlow + BlinkRapid + ReverseVideo + Concealed + CrossedOut +) + +// Foreground text colors +const ( + FgBlack Attribute = iota + 30 + FgRed + FgGreen + FgYellow + FgBlue + FgMagenta + FgCyan + FgWhite +) + +// Foreground Hi-Intensity text colors +const ( + FgHiBlack Attribute = iota + 90 + FgHiRed + FgHiGreen + FgHiYellow + FgHiBlue + FgHiMagenta + FgHiCyan + FgHiWhite +) + +// Background text colors +const ( + BgBlack Attribute = iota + 40 + BgRed + BgGreen + BgYellow + BgBlue + BgMagenta + BgCyan + BgWhite +) + +// Background Hi-Intensity text colors +const ( + BgHiBlack Attribute = iota + 100 + BgHiRed + BgHiGreen + BgHiYellow + BgHiBlue + BgHiMagenta + BgHiCyan + BgHiWhite +) + +// New returns a newly created color object. +func New(value ...Attribute) *Color { + c := &Color{ + params: make([]Attribute, 0), + } + + if noColorExists() { + c.noColor = boolPtr(true) + } + + c.Add(value...) + return c +} + +// Set sets the given parameters immediately. It will change the color of +// output with the given SGR parameters until color.Unset() is called. +func Set(p ...Attribute) *Color { + c := New(p...) + c.Set() + return c +} + +// Unset resets all escape attributes and clears the output. Usually should +// be called after Set(). +func Unset() { + if NoColor { + return + } + + fmt.Fprintf(Output, "%s[%dm", escape, Reset) +} + +// Set sets the SGR sequence. +func (c *Color) Set() *Color { + if c.isNoColorSet() { + return c + } + + fmt.Fprintf(Output, c.format()) + return c +} + +func (c *Color) unset() { + if c.isNoColorSet() { + return + } + + Unset() +} + +func (c *Color) setWriter(w io.Writer) *Color { + if c.isNoColorSet() { + return c + } + + fmt.Fprintf(w, c.format()) + return c +} + +func (c *Color) unsetWriter(w io.Writer) { + if c.isNoColorSet() { + return + } + + if NoColor { + return + } + + fmt.Fprintf(w, "%s[%dm", escape, Reset) +} + +// Add is used to chain SGR parameters. Use as many as parameters to combine +// and create custom color objects. Example: Add(color.FgRed, color.Underline). +func (c *Color) Add(value ...Attribute) *Color { + c.params = append(c.params, value...) + return c +} + +func (c *Color) prepend(value Attribute) { + c.params = append(c.params, 0) + copy(c.params[1:], c.params[0:]) + c.params[0] = value +} + +// Fprint formats using the default formats for its operands and writes to w. +// Spaces are added between operands when neither is a string. +// It returns the number of bytes written and any write error encountered. +// On Windows, users should wrap w with colorable.NewColorable() if w is of +// type *os.File. +func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + c.setWriter(w) + defer c.unsetWriter(w) + + return fmt.Fprint(w, a...) +} + +// Print formats using the default formats for its operands and writes to +// standard output. Spaces are added between operands when neither is a +// string. It returns the number of bytes written and any write error +// encountered. This is the standard fmt.Print() method wrapped with the given +// color. +func (c *Color) Print(a ...interface{}) (n int, err error) { + c.Set() + defer c.unset() + + return fmt.Fprint(Output, a...) +} + +// Fprintf formats according to a format specifier and writes to w. +// It returns the number of bytes written and any write error encountered. +// On Windows, users should wrap w with colorable.NewColorable() if w is of +// type *os.File. +func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + c.setWriter(w) + defer c.unsetWriter(w) + + return fmt.Fprintf(w, format, a...) +} + +// Printf formats according to a format specifier and writes to standard output. +// It returns the number of bytes written and any write error encountered. +// This is the standard fmt.Printf() method wrapped with the given color. +func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { + c.Set() + defer c.unset() + + return fmt.Fprintf(Output, format, a...) +} + +// Fprintln formats using the default formats for its operands and writes to w. +// Spaces are always added between operands and a newline is appended. +// On Windows, users should wrap w with colorable.NewColorable() if w is of +// type *os.File. +func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + c.setWriter(w) + defer c.unsetWriter(w) + + return fmt.Fprintln(w, a...) +} + +// Println formats using the default formats for its operands and writes to +// standard output. Spaces are always added between operands and a newline is +// appended. It returns the number of bytes written and any write error +// encountered. This is the standard fmt.Print() method wrapped with the given +// color. +func (c *Color) Println(a ...interface{}) (n int, err error) { + c.Set() + defer c.unset() + + return fmt.Fprintln(Output, a...) +} + +// Sprint is just like Print, but returns a string instead of printing it. +func (c *Color) Sprint(a ...interface{}) string { + return c.wrap(fmt.Sprint(a...)) +} + +// Sprintln is just like Println, but returns a string instead of printing it. +func (c *Color) Sprintln(a ...interface{}) string { + return c.wrap(fmt.Sprintln(a...)) +} + +// Sprintf is just like Printf, but returns a string instead of printing it. +func (c *Color) Sprintf(format string, a ...interface{}) string { + return c.wrap(fmt.Sprintf(format, a...)) +} + +// FprintFunc returns a new function that prints the passed arguments as +// colorized with color.Fprint(). +func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) { + return func(w io.Writer, a ...interface{}) { + c.Fprint(w, a...) + } +} + +// PrintFunc returns a new function that prints the passed arguments as +// colorized with color.Print(). +func (c *Color) PrintFunc() func(a ...interface{}) { + return func(a ...interface{}) { + c.Print(a...) + } +} + +// FprintfFunc returns a new function that prints the passed arguments as +// colorized with color.Fprintf(). +func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) { + return func(w io.Writer, format string, a ...interface{}) { + c.Fprintf(w, format, a...) + } +} + +// PrintfFunc returns a new function that prints the passed arguments as +// colorized with color.Printf(). +func (c *Color) PrintfFunc() func(format string, a ...interface{}) { + return func(format string, a ...interface{}) { + c.Printf(format, a...) + } +} + +// FprintlnFunc returns a new function that prints the passed arguments as +// colorized with color.Fprintln(). +func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) { + return func(w io.Writer, a ...interface{}) { + c.Fprintln(w, a...) + } +} + +// PrintlnFunc returns a new function that prints the passed arguments as +// colorized with color.Println(). +func (c *Color) PrintlnFunc() func(a ...interface{}) { + return func(a ...interface{}) { + c.Println(a...) + } +} + +// SprintFunc returns a new function that returns colorized strings for the +// given arguments with fmt.Sprint(). Useful to put into or mix into other +// string. Windows users should use this in conjunction with color.Output, example: +// +// put := New(FgYellow).SprintFunc() +// fmt.Fprintf(color.Output, "This is a %s", put("warning")) +func (c *Color) SprintFunc() func(a ...interface{}) string { + return func(a ...interface{}) string { + return c.wrap(fmt.Sprint(a...)) + } +} + +// SprintfFunc returns a new function that returns colorized strings for the +// given arguments with fmt.Sprintf(). Useful to put into or mix into other +// string. Windows users should use this in conjunction with color.Output. +func (c *Color) SprintfFunc() func(format string, a ...interface{}) string { + return func(format string, a ...interface{}) string { + return c.wrap(fmt.Sprintf(format, a...)) + } +} + +// SprintlnFunc returns a new function that returns colorized strings for the +// given arguments with fmt.Sprintln(). Useful to put into or mix into other +// string. Windows users should use this in conjunction with color.Output. +func (c *Color) SprintlnFunc() func(a ...interface{}) string { + return func(a ...interface{}) string { + return c.wrap(fmt.Sprintln(a...)) + } +} + +// sequence returns a formatted SGR sequence to be plugged into a "\x1b[...m" +// an example output might be: "1;36" -> bold cyan +func (c *Color) sequence() string { + format := make([]string, len(c.params)) + for i, v := range c.params { + format[i] = strconv.Itoa(int(v)) + } + + return strings.Join(format, ";") +} + +// wrap wraps the s string with the colors attributes. The string is ready to +// be printed. +func (c *Color) wrap(s string) string { + if c.isNoColorSet() { + return s + } + + return c.format() + s + c.unformat() +} + +func (c *Color) format() string { + return fmt.Sprintf("%s[%sm", escape, c.sequence()) +} + +func (c *Color) unformat() string { + return fmt.Sprintf("%s[%dm", escape, Reset) +} + +// DisableColor disables the color output. Useful to not change any existing +// code and still being able to output. Can be used for flags like +// "--no-color". To enable back use EnableColor() method. +func (c *Color) DisableColor() { + c.noColor = boolPtr(true) +} + +// EnableColor enables the color output. Use it in conjunction with +// DisableColor(). Otherwise this method has no side effects. +func (c *Color) EnableColor() { + c.noColor = boolPtr(false) +} + +func (c *Color) isNoColorSet() bool { + // check first if we have user set action + if c.noColor != nil { + return *c.noColor + } + + // if not return the global option, which is disabled by default + return NoColor +} + +// Equals returns a boolean value indicating whether two colors are equal. +func (c *Color) Equals(c2 *Color) bool { + if len(c.params) != len(c2.params) { + return false + } + + for _, attr := range c.params { + if !c2.attrExists(attr) { + return false + } + } + + return true +} + +func (c *Color) attrExists(a Attribute) bool { + for _, attr := range c.params { + if attr == a { + return true + } + } + + return false +} + +func boolPtr(v bool) *bool { + return &v +} + +func getCachedColor(p Attribute) *Color { + colorsCacheMu.Lock() + defer colorsCacheMu.Unlock() + + c, ok := colorsCache[p] + if !ok { + c = New(p) + colorsCache[p] = c + } + + return c +} + +func colorPrint(format string, p Attribute, a ...interface{}) { + c := getCachedColor(p) + + if !strings.HasSuffix(format, "\n") { + format += "\n" + } + + if len(a) == 0 { + c.Print(format) + } else { + c.Printf(format, a...) + } +} + +func colorString(format string, p Attribute, a ...interface{}) string { + c := getCachedColor(p) + + if len(a) == 0 { + return c.SprintFunc()(format) + } + + return c.SprintfFunc()(format, a...) +} + +// Black is a convenient helper function to print with black foreground. A +// newline is appended to format by default. +func Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) } + +// Red is a convenient helper function to print with red foreground. A +// newline is appended to format by default. +func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) } + +// Green is a convenient helper function to print with green foreground. A +// newline is appended to format by default. +func Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) } + +// Yellow is a convenient helper function to print with yellow foreground. +// A newline is appended to format by default. +func Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) } + +// Blue is a convenient helper function to print with blue foreground. A +// newline is appended to format by default. +func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) } + +// Magenta is a convenient helper function to print with magenta foreground. +// A newline is appended to format by default. +func Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) } + +// Cyan is a convenient helper function to print with cyan foreground. A +// newline is appended to format by default. +func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) } + +// White is a convenient helper function to print with white foreground. A +// newline is appended to format by default. +func White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) } + +// BlackString is a convenient helper function to return a string with black +// foreground. +func BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) } + +// RedString is a convenient helper function to return a string with red +// foreground. +func RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) } + +// GreenString is a convenient helper function to return a string with green +// foreground. +func GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) } + +// YellowString is a convenient helper function to return a string with yellow +// foreground. +func YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) } + +// BlueString is a convenient helper function to return a string with blue +// foreground. +func BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) } + +// MagentaString is a convenient helper function to return a string with magenta +// foreground. +func MagentaString(format string, a ...interface{}) string { + return colorString(format, FgMagenta, a...) +} + +// CyanString is a convenient helper function to return a string with cyan +// foreground. +func CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) } + +// WhiteString is a convenient helper function to return a string with white +// foreground. +func WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) } + +// HiBlack is a convenient helper function to print with hi-intensity black foreground. A +// newline is appended to format by default. +func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) } + +// HiRed is a convenient helper function to print with hi-intensity red foreground. A +// newline is appended to format by default. +func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) } + +// HiGreen is a convenient helper function to print with hi-intensity green foreground. A +// newline is appended to format by default. +func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) } + +// HiYellow is a convenient helper function to print with hi-intensity yellow foreground. +// A newline is appended to format by default. +func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) } + +// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A +// newline is appended to format by default. +func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) } + +// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground. +// A newline is appended to format by default. +func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) } + +// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A +// newline is appended to format by default. +func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) } + +// HiWhite is a convenient helper function to print with hi-intensity white foreground. A +// newline is appended to format by default. +func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) } + +// HiBlackString is a convenient helper function to return a string with hi-intensity black +// foreground. +func HiBlackString(format string, a ...interface{}) string { + return colorString(format, FgHiBlack, a...) +} + +// HiRedString is a convenient helper function to return a string with hi-intensity red +// foreground. +func HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) } + +// HiGreenString is a convenient helper function to return a string with hi-intensity green +// foreground. +func HiGreenString(format string, a ...interface{}) string { + return colorString(format, FgHiGreen, a...) +} + +// HiYellowString is a convenient helper function to return a string with hi-intensity yellow +// foreground. +func HiYellowString(format string, a ...interface{}) string { + return colorString(format, FgHiYellow, a...) +} + +// HiBlueString is a convenient helper function to return a string with hi-intensity blue +// foreground. +func HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) } + +// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta +// foreground. +func HiMagentaString(format string, a ...interface{}) string { + return colorString(format, FgHiMagenta, a...) +} + +// HiCyanString is a convenient helper function to return a string with hi-intensity cyan +// foreground. +func HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) } + +// HiWhiteString is a convenient helper function to return a string with hi-intensity white +// foreground. +func HiWhiteString(format string, a ...interface{}) string { + return colorString(format, FgHiWhite, a...) +} diff --git a/vendor/github.com/fatih/color/doc.go b/vendor/github.com/fatih/color/doc.go new file mode 100644 index 00000000000..04541de786f --- /dev/null +++ b/vendor/github.com/fatih/color/doc.go @@ -0,0 +1,135 @@ +/* +Package color is an ANSI color package to output colorized or SGR defined +output to the standard output. The API can be used in several way, pick one +that suits you. + +Use simple and default helper functions with predefined foreground colors: + + color.Cyan("Prints text in cyan.") + + // a newline will be appended automatically + color.Blue("Prints %s in blue.", "text") + + // More default foreground colors.. + color.Red("We have red") + color.Yellow("Yellow color too!") + color.Magenta("And many others ..") + + // Hi-intensity colors + color.HiGreen("Bright green color.") + color.HiBlack("Bright black means gray..") + color.HiWhite("Shiny white color!") + +However there are times where custom color mixes are required. Below are some +examples to create custom color objects and use the print functions of each +separate color object. + + // Create a new color object + c := color.New(color.FgCyan).Add(color.Underline) + c.Println("Prints cyan text with an underline.") + + // Or just add them to New() + d := color.New(color.FgCyan, color.Bold) + d.Printf("This prints bold cyan %s\n", "too!.") + + + // Mix up foreground and background colors, create new mixes! + red := color.New(color.FgRed) + + boldRed := red.Add(color.Bold) + boldRed.Println("This will print text in bold red.") + + whiteBackground := red.Add(color.BgWhite) + whiteBackground.Println("Red text with White background.") + + // Use your own io.Writer output + color.New(color.FgBlue).Fprintln(myWriter, "blue color!") + + blue := color.New(color.FgBlue) + blue.Fprint(myWriter, "This will print text in blue.") + +You can create PrintXxx functions to simplify even more: + + // Create a custom print function for convenient + red := color.New(color.FgRed).PrintfFunc() + red("warning") + red("error: %s", err) + + // Mix up multiple attributes + notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() + notice("don't forget this...") + +You can also FprintXxx functions to pass your own io.Writer: + + blue := color.New(FgBlue).FprintfFunc() + blue(myWriter, "important notice: %s", stars) + + // Mix up with multiple attributes + success := color.New(color.Bold, color.FgGreen).FprintlnFunc() + success(myWriter, don't forget this...") + + +Or create SprintXxx functions to mix strings with other non-colorized strings: + + yellow := New(FgYellow).SprintFunc() + red := New(FgRed).SprintFunc() + + fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) + + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Printf("this %s rocks!\n", info("package")) + +Windows support is enabled by default. All Print functions work as intended. +However only for color.SprintXXX functions, user should use fmt.FprintXXX and +set the output to color.Output: + + fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) + + info := New(FgWhite, BgGreen).SprintFunc() + fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) + +Using with existing code is possible. Just use the Set() method to set the +standard output to the given parameters. That way a rewrite of an existing +code is not required. + + // Use handy standard colors. + color.Set(color.FgYellow) + + fmt.Println("Existing text will be now in Yellow") + fmt.Printf("This one %s\n", "too") + + color.Unset() // don't forget to unset + + // You can mix up parameters + color.Set(color.FgMagenta, color.Bold) + defer color.Unset() // use it in your function + + fmt.Println("All text will be now bold magenta.") + +There might be a case where you want to disable color output (for example to +pipe the standard output of your app to somewhere else). `Color` has support to +disable colors both globally and for single color definition. For example +suppose you have a CLI app and a `--no-color` bool flag. You can easily disable +the color output with: + + var flagNoColor = flag.Bool("no-color", false, "Disable color output") + + if *flagNoColor { + color.NoColor = true // disables colorized output + } + +You can also disable the color by setting the NO_COLOR environment variable to any value. + +It also has support for single color definitions (local). You can +disable/enable color output on the fly: + + c := color.New(color.FgCyan) + c.Println("Prints cyan text") + + c.DisableColor() + c.Println("This is printed without any color") + + c.EnableColor() + c.Println("This prints again cyan...") +*/ +package color diff --git a/vendor/github.com/gosuri/uitable/.travis.yml b/vendor/github.com/gosuri/uitable/.travis.yml new file mode 100644 index 00000000000..26fc3b438bf --- /dev/null +++ b/vendor/github.com/gosuri/uitable/.travis.yml @@ -0,0 +1,6 @@ +language: go +sudo: false +install: + - go get ./... +go: + - tip diff --git a/vendor/github.com/gosuri/uitable/LICENSE b/vendor/github.com/gosuri/uitable/LICENSE new file mode 100644 index 00000000000..e436d90439d --- /dev/null +++ b/vendor/github.com/gosuri/uitable/LICENSE @@ -0,0 +1,10 @@ +MIT License +=========== + +Copyright (c) 2015, Greg Osuri + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/gosuri/uitable/Makefile b/vendor/github.com/gosuri/uitable/Makefile new file mode 100644 index 00000000000..60246a8a93c --- /dev/null +++ b/vendor/github.com/gosuri/uitable/Makefile @@ -0,0 +1,4 @@ +test: + @go test ./... + +.PHONY: test diff --git a/vendor/github.com/gosuri/uitable/README.md b/vendor/github.com/gosuri/uitable/README.md new file mode 100644 index 00000000000..683b538d132 --- /dev/null +++ b/vendor/github.com/gosuri/uitable/README.md @@ -0,0 +1,67 @@ +# uitable [![GoDoc](https://godoc.org/github.com/gosuri/uitable?status.svg)](https://godoc.org/github.com/gosuri/uitable) [![Build Status](https://travis-ci.org/gosuri/uitable.svg?branch=master)](https://travis-ci.org/gosuri/uitable) + +uitable is a go library for representing data as tables for terminal applications. It provides primitives for sizing and wrapping columns to improve readability. + +## Example Usage + +Full source code for the example is available at [example/main.go](example/main.go) + +```go +table := uitable.New() +table.MaxColWidth = 50 + +table.AddRow("NAME", "BIRTHDAY", "BIO") +for _, hacker := range hackers { + table.AddRow(hacker.Name, hacker.Birthday, hacker.Bio) +} +fmt.Println(table) +``` + +Will render the data as: + +```sh +NAME BIRTHDAY BIO +Ada Lovelace December 10, 1815 Ada was a British mathematician and writer, chi... +Alan Turing June 23, 1912 Alan was a British pioneering computer scientis... +``` + +For wrapping in two columns: + +```go +table = uitable.New() +table.MaxColWidth = 80 +table.Wrap = true // wrap columns + +for _, hacker := range hackers { + table.AddRow("Name:", hacker.Name) + table.AddRow("Birthday:", hacker.Birthday) + table.AddRow("Bio:", hacker.Bio) + table.AddRow("") // blank +} +fmt.Println(table) +``` + +Will render the data as: + +``` +Name: Ada Lovelace +Birthday: December 10, 1815 +Bio: Ada was a British mathematician and writer, chiefly known for her work on + Charles Babbage's early mechanical general-purpose computer, the Analytical + Engine + +Name: Alan Turing +Birthday: June 23, 1912 +Bio: Alan was a British pioneering computer scientist, mathematician, logician, + cryptanalyst and theoretical biologist +``` + +## Installation + +``` +$ go get -v github.com/gosuri/uitable +``` + + +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/gosuri/uitable/trend.png)](https://bitdeli.com/free "Bitdeli Badge") + diff --git a/vendor/github.com/gosuri/uitable/table.go b/vendor/github.com/gosuri/uitable/table.go new file mode 100644 index 00000000000..b764e51502c --- /dev/null +++ b/vendor/github.com/gosuri/uitable/table.go @@ -0,0 +1,205 @@ +// Package uitable provides a decorator for formating data as a table +package uitable + +import ( + "fmt" + "strings" + "sync" + + "github.com/fatih/color" + "github.com/gosuri/uitable/util/strutil" + "github.com/gosuri/uitable/util/wordwrap" +) + +// Separator is the default column seperator +var Separator = "\t" + +// Table represents a decorator that renders the data in formatted in a table +type Table struct { + // Rows is the collection of rows in the table + Rows []*Row + + // MaxColWidth is the maximum allowed width for cells in the table + MaxColWidth uint + + // Wrap when set to true wraps the contents of the columns when the length exceeds the MaxColWidth + Wrap bool + + // Separator is the seperator for columns in the table. Default is "\t" + Separator string + + mtx *sync.RWMutex + rightAlign map[int]bool +} + +// New returns a new Table with default values +func New() *Table { + return &Table{ + Separator: Separator, + mtx: new(sync.RWMutex), + rightAlign: map[int]bool{}, + } +} + +// AddRow adds a new row to the table +func (t *Table) AddRow(data ...interface{}) *Table { + t.mtx.Lock() + defer t.mtx.Unlock() + r := NewRow(data...) + t.Rows = append(t.Rows, r) + return t +} + +// Bytes returns the []byte value of table +func (t *Table) Bytes() []byte { + return []byte(t.String()) +} + +func (t *Table) RightAlign(col int) { + t.mtx.Lock() + t.rightAlign[col] = true + t.mtx.Unlock() +} + +// String returns the string value of table +func (t *Table) String() string { + t.mtx.RLock() + defer t.mtx.RUnlock() + + if len(t.Rows) == 0 { + return "" + } + + // determine the width for each column (cell in a row) + var colwidths []uint + for _, row := range t.Rows { + for i, cell := range row.Cells { + // resize colwidth array + if i+1 > len(colwidths) { + colwidths = append(colwidths, 0) + } + cellwidth := cell.LineWidth() + if t.MaxColWidth != 0 && cellwidth > t.MaxColWidth { + cellwidth = t.MaxColWidth + } + + if cellwidth > colwidths[i] { + colwidths[i] = cellwidth + } + } + } + + var lines []string + for _, row := range t.Rows { + row.Separator = t.Separator + for i, cell := range row.Cells { + cell.Width = colwidths[i] + cell.Wrap = t.Wrap + cell.RightAlign = t.rightAlign[i] + } + lines = append(lines, row.String()) + } + return strutil.Join(lines, "\n") +} + +// Row represents a row in a table +type Row struct { + // Cells is the group of cell for the row + Cells []*Cell + + // Separator for tabular columns + Separator string +} + +// NewRow returns a new Row and adds the data to the row +func NewRow(data ...interface{}) *Row { + r := &Row{Cells: make([]*Cell, len(data))} + for i, d := range data { + r.Cells[i] = &Cell{Data: d} + } + return r +} + +// String returns the string representation of the row +func (r *Row) String() string { + // get the max number of lines for each cell + var lc int // line count + for _, cell := range r.Cells { + if clc := len(strings.Split(cell.String(), "\n")); clc > lc { + lc = clc + } + } + + // allocate a two-dimentional array of cells for each line and add size them + cells := make([][]*Cell, lc) + for x := 0; x < lc; x++ { + cells[x] = make([]*Cell, len(r.Cells)) + for y := 0; y < len(r.Cells); y++ { + cells[x][y] = &Cell{Width: r.Cells[y].Width} + } + } + + // insert each line in a cell as new cell in the cells array + for y, cell := range r.Cells { + lines := strings.Split(cell.String(), "\n") + for x, line := range lines { + cells[x][y].Data = line + } + } + + // format each line + lines := make([]string, lc) + for x := range lines { + line := make([]string, len(cells[x])) + for y := range cells[x] { + line[y] = cells[x][y].String() + } + lines[x] = strutil.Join(line, r.Separator) + } + return strings.Join(lines, "\n") +} + +// Cell represents a column in a row +type Cell struct { + // Width is the width of the cell + Width uint + + // Wrap when true wraps the contents of the cell when the lenght exceeds the width + Wrap bool + + // RightAlign when true aligns contents to the right + RightAlign bool + + // Data is the cell data + Data interface{} +} + +// LineWidth returns the max width of all the lines in a cell +func (c *Cell) LineWidth() uint { + width := 0 + for _, s := range strings.Split(c.String(), "\n") { + w := strutil.StringWidth(s) + if w > width { + width = w + } + } + return uint(width) +} + +// String returns the string formated representation of the cell +func (c *Cell) String() string { + if c.Data == nil { + return strutil.PadLeft(" ", int(c.Width), ' ') + } + col := color.New(color.FgBlack) + col.DisableColor() + s := fmt.Sprintf("%v", col.Sprint(c.Data)) + if c.Width > 0 { + if c.Wrap && uint(len(s)) > c.Width { + return wordwrap.WrapString(s, c.Width) + } else { + return strutil.Resize(s, c.Width, c.RightAlign) + } + } + return s +} diff --git a/vendor/github.com/gosuri/uitable/util/strutil/strutil.go b/vendor/github.com/gosuri/uitable/util/strutil/strutil.go new file mode 100644 index 00000000000..53f30a8fd3b --- /dev/null +++ b/vendor/github.com/gosuri/uitable/util/strutil/strutil.go @@ -0,0 +1,101 @@ +// Package strutil provides various utilities for manipulating strings +package strutil + +import ( + "bytes" + "regexp" + + "github.com/mattn/go-runewidth" +) + +const ansi = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))" + +var re = regexp.MustCompile(ansi) + +// PadRight returns a new string of a specified length in which the end of the current string is padded with spaces or with a specified Unicode character. +func PadRight(str string, length int, pad byte) string { + slen := StringWidth(str) + if slen >= length { + return str + } + buf := bytes.NewBufferString(str) + for i := 0; i < length-slen; i++ { + buf.WriteByte(pad) + } + return buf.String() +} + +// PadLeft returns a new string of a specified length in which the beginning of the current string is padded with spaces or with a specified Unicode character. +func PadLeft(str string, length int, pad byte) string { + slen := StringWidth(str) + if slen >= length { + return str + } + var buf bytes.Buffer + for i := 0; i < length-slen; i++ { + buf.WriteByte(pad) + } + buf.WriteString(str) + return buf.String() +} + +// Resize resizes the string with the given length. It ellipses with '...' when the string's length exceeds +// the desired length or pads spaces to the right of the string when length is smaller than desired +func Resize(s string, length uint, rightAlign bool) string { + slen := StringWidth(s) + n := int(length) + if slen == n { + return s + } + // Pads only when length of the string smaller than len needed + if rightAlign { + s = PadLeft(s, n, ' ') + } else { + s = PadRight(s, n, ' ') + } + if slen > n { + rs := []rune(s) + var buf bytes.Buffer + w := 0 + for _, r := range rs { + buf.WriteRune(r) + rw := RuneWidth(r) + if w+rw >= n-3 { + break + } + w += rw + } + buf.WriteString("...") + s = buf.String() + } + return s +} + +// Join joins the list of the string with the delim provided. +// Returns an empty string for empty list +func Join(list []string, delim string) string { + if len(list) == 0 { + return "" + } + var buf bytes.Buffer + for i := 0; i < len(list)-1; i++ { + buf.WriteString(list[i] + delim) + } + buf.WriteString(list[len(list)-1]) + return buf.String() +} + +// Strip strips the string of all colors +func Strip(s string) string { + return re.ReplaceAllString(s, "") +} + +// StringWidth returns the actual width of the string without colors +func StringWidth(s string) int { + return runewidth.StringWidth(Strip(s)) +} + +// RuneWidth returns the actual width of the rune +func RuneWidth(s rune) int { + return runewidth.RuneWidth(s) +} diff --git a/vendor/github.com/gosuri/uitable/util/wordwrap/LICENSE.md b/vendor/github.com/gosuri/uitable/util/wordwrap/LICENSE.md new file mode 100644 index 00000000000..22985159044 --- /dev/null +++ b/vendor/github.com/gosuri/uitable/util/wordwrap/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Mitchell Hashimoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/gosuri/uitable/util/wordwrap/README.md b/vendor/github.com/gosuri/uitable/util/wordwrap/README.md new file mode 100644 index 00000000000..60ae3117008 --- /dev/null +++ b/vendor/github.com/gosuri/uitable/util/wordwrap/README.md @@ -0,0 +1,39 @@ +# go-wordwrap + +`go-wordwrap` (Golang package: `wordwrap`) is a package for Go that +automatically wraps words into multiple lines. The primary use case for this +is in formatting CLI output, but of course word wrapping is a generally useful +thing to do. + +## Installation and Usage + +Install using `go get github.com/mitchellh/go-wordwrap`. + +Full documentation is available at +http://godoc.org/github.com/mitchellh/go-wordwrap + +Below is an example of its usage ignoring errors: + +```go +wrapped := wordwrap.WrapString("foo bar baz", 3) +fmt.Println(wrapped) +``` + +Would output: + +``` +foo +bar +baz +``` + +## Word Wrap Algorithm + +This library doesn't use any clever algorithm for word wrapping. The wrapping +is actually very naive: whenever there is whitespace or an explicit linebreak. +The goal of this library is for word wrapping CLI output, so the input is +typically pretty well controlled human language. Because of this, the naive +approach typically works just fine. + +In the future, we'd like to make the algorithm more advanced. We would do +so without breaking the API. diff --git a/vendor/github.com/gosuri/uitable/util/wordwrap/wordwrap.go b/vendor/github.com/gosuri/uitable/util/wordwrap/wordwrap.go new file mode 100644 index 00000000000..b2c63b87957 --- /dev/null +++ b/vendor/github.com/gosuri/uitable/util/wordwrap/wordwrap.go @@ -0,0 +1,85 @@ +// Package wordwrap provides methods for wrapping the contents of a string +package wordwrap + +import ( + "bytes" + "unicode" + + "github.com/gosuri/uitable/util/strutil" +) + +// WrapString wraps the given string within lim width in characters. +// +// Wrapping is currently naive and only happens at white-space. A future +// version of the library will implement smarter wrapping. This means that +// pathological cases can dramatically reach past the limit, such as a very +// long word. +func WrapString(s string, lim uint) string { + // Initialize a buffer with a slightly larger size to account for breaks + init := make([]byte, 0, len(s)) + buf := bytes.NewBuffer(init) + + var current uint + var wordBuf, spaceBuf bytes.Buffer + var wordWidth, spaceWidth int + + for _, char := range s { + if char == '\n' { + if wordBuf.Len() == 0 { + if current+uint(spaceWidth) > lim { + current = 0 + } else { + current += uint(spaceWidth) + spaceBuf.WriteTo(buf) + spaceWidth += strutil.StringWidth(buf.String()) + } + spaceBuf.Reset() + spaceWidth = 0 + } else { + current += uint(spaceWidth + wordWidth) + spaceBuf.WriteTo(buf) + spaceBuf.Reset() + wordBuf.WriteTo(buf) + wordBuf.Reset() + spaceWidth = 0 + wordWidth = 0 + } + buf.WriteRune(char) + current = 0 + } else if unicode.IsSpace(char) { + if spaceBuf.Len() == 0 || wordBuf.Len() > 0 { + current += uint(spaceWidth + wordWidth) + spaceBuf.WriteTo(buf) + spaceBuf.Reset() + wordBuf.WriteTo(buf) + wordBuf.Reset() + spaceWidth = 0 + wordWidth = 0 + } + + spaceBuf.WriteRune(char) + spaceWidth += strutil.RuneWidth(char) + } else { + wordBuf.WriteRune(char) + wordWidth += strutil.RuneWidth(char) + + if current+uint(spaceWidth+wordWidth) > lim && uint(wordWidth) < lim { + buf.WriteRune('\n') + current = 0 + spaceBuf.Reset() + spaceWidth = 0 + } + } + } + + if wordBuf.Len() == 0 { + if current+uint(spaceWidth) <= lim { + spaceBuf.WriteTo(buf) + } + } else { + spaceBuf.WriteTo(buf) + wordBuf.WriteTo(buf) + } + + return buf.String() +} diff --git a/vendor/github.com/mattn/go-colorable/LICENSE b/vendor/github.com/mattn/go-colorable/LICENSE new file mode 100644 index 00000000000..91b5cef30eb --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mattn/go-colorable/README.md b/vendor/github.com/mattn/go-colorable/README.md new file mode 100644 index 00000000000..ca0483711c9 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/README.md @@ -0,0 +1,48 @@ +# go-colorable + +[![Build Status](https://github.com/mattn/go-colorable/workflows/test/badge.svg)](https://github.com/mattn/go-colorable/actions?query=workflow%3Atest) +[![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable) +[![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) + +Colorable writer for windows. + +For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) +This package is possible to handle escape sequence for ansi color on windows. + +## Too Bad! + +![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) + + +## So Good! + +![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) + +## Usage + +```go +logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) +logrus.SetOutput(colorable.NewColorableStdout()) + +logrus.Info("succeeded") +logrus.Warn("not correct") +logrus.Error("something error") +logrus.Fatal("panic") +``` + +You can compile above code on non-windows OSs. + +## Installation + +``` +$ go get github.com/mattn/go-colorable +``` + +# License + +MIT + +# Author + +Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/mattn/go-colorable/colorable_appengine.go b/vendor/github.com/mattn/go-colorable/colorable_appengine.go new file mode 100644 index 00000000000..416d1bbbf83 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_appengine.go @@ -0,0 +1,38 @@ +//go:build appengine +// +build appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable returns new instance of Writer which handles escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} + +// EnableColorsStdout enable colors if possible. +func EnableColorsStdout(enabled *bool) func() { + if enabled != nil { + *enabled = true + } + return func() {} +} diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go new file mode 100644 index 00000000000..766d94603ac --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_others.go @@ -0,0 +1,38 @@ +//go:build !windows && !appengine +// +build !windows,!appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable returns new instance of Writer which handles escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} + +// EnableColorsStdout enable colors if possible. +func EnableColorsStdout(enabled *bool) func() { + if enabled != nil { + *enabled = true + } + return func() {} +} diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go new file mode 100644 index 00000000000..1846ad5ab41 --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go @@ -0,0 +1,1047 @@ +//go:build windows && !appengine +// +build windows,!appengine + +package colorable + +import ( + "bytes" + "io" + "math" + "os" + "strconv" + "strings" + "sync" + "syscall" + "unsafe" + + "github.com/mattn/go-isatty" +) + +const ( + foregroundBlue = 0x1 + foregroundGreen = 0x2 + foregroundRed = 0x4 + foregroundIntensity = 0x8 + foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) + backgroundBlue = 0x10 + backgroundGreen = 0x20 + backgroundRed = 0x40 + backgroundIntensity = 0x80 + backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) + commonLvbUnderscore = 0x8000 + + cENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4 +) + +const ( + genericRead = 0x80000000 + genericWrite = 0x40000000 +) + +const ( + consoleTextmodeBuffer = 0x1 +) + +type wchar uint16 +type short int16 +type dword uint32 +type word uint16 + +type coord struct { + x short + y short +} + +type smallRect struct { + left short + top short + right short + bottom short +} + +type consoleScreenBufferInfo struct { + size coord + cursorPosition coord + attributes word + window smallRect + maximumWindowSize coord +} + +type consoleCursorInfo struct { + size dword + visible int32 +} + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") + procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") + procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") + procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") + procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") + procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") + procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW") + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + procSetConsoleMode = kernel32.NewProc("SetConsoleMode") + procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer") +) + +// Writer provides colorable Writer to the console +type Writer struct { + out io.Writer + handle syscall.Handle + althandle syscall.Handle + oldattr word + oldpos coord + rest bytes.Buffer + mutex sync.Mutex +} + +// NewColorable returns new instance of Writer which handles escape sequence from File. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + if isatty.IsTerminal(file.Fd()) { + var mode uint32 + if r, _, _ := procGetConsoleMode.Call(file.Fd(), uintptr(unsafe.Pointer(&mode))); r != 0 && mode&cENABLE_VIRTUAL_TERMINAL_PROCESSING != 0 { + return file + } + var csbi consoleScreenBufferInfo + handle := syscall.Handle(file.Fd()) + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} + } + return file +} + +// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. +func NewColorableStdout() io.Writer { + return NewColorable(os.Stdout) +} + +// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. +func NewColorableStderr() io.Writer { + return NewColorable(os.Stderr) +} + +var color256 = map[int]int{ + 0: 0x000000, + 1: 0x800000, + 2: 0x008000, + 3: 0x808000, + 4: 0x000080, + 5: 0x800080, + 6: 0x008080, + 7: 0xc0c0c0, + 8: 0x808080, + 9: 0xff0000, + 10: 0x00ff00, + 11: 0xffff00, + 12: 0x0000ff, + 13: 0xff00ff, + 14: 0x00ffff, + 15: 0xffffff, + 16: 0x000000, + 17: 0x00005f, + 18: 0x000087, + 19: 0x0000af, + 20: 0x0000d7, + 21: 0x0000ff, + 22: 0x005f00, + 23: 0x005f5f, + 24: 0x005f87, + 25: 0x005faf, + 26: 0x005fd7, + 27: 0x005fff, + 28: 0x008700, + 29: 0x00875f, + 30: 0x008787, + 31: 0x0087af, + 32: 0x0087d7, + 33: 0x0087ff, + 34: 0x00af00, + 35: 0x00af5f, + 36: 0x00af87, + 37: 0x00afaf, + 38: 0x00afd7, + 39: 0x00afff, + 40: 0x00d700, + 41: 0x00d75f, + 42: 0x00d787, + 43: 0x00d7af, + 44: 0x00d7d7, + 45: 0x00d7ff, + 46: 0x00ff00, + 47: 0x00ff5f, + 48: 0x00ff87, + 49: 0x00ffaf, + 50: 0x00ffd7, + 51: 0x00ffff, + 52: 0x5f0000, + 53: 0x5f005f, + 54: 0x5f0087, + 55: 0x5f00af, + 56: 0x5f00d7, + 57: 0x5f00ff, + 58: 0x5f5f00, + 59: 0x5f5f5f, + 60: 0x5f5f87, + 61: 0x5f5faf, + 62: 0x5f5fd7, + 63: 0x5f5fff, + 64: 0x5f8700, + 65: 0x5f875f, + 66: 0x5f8787, + 67: 0x5f87af, + 68: 0x5f87d7, + 69: 0x5f87ff, + 70: 0x5faf00, + 71: 0x5faf5f, + 72: 0x5faf87, + 73: 0x5fafaf, + 74: 0x5fafd7, + 75: 0x5fafff, + 76: 0x5fd700, + 77: 0x5fd75f, + 78: 0x5fd787, + 79: 0x5fd7af, + 80: 0x5fd7d7, + 81: 0x5fd7ff, + 82: 0x5fff00, + 83: 0x5fff5f, + 84: 0x5fff87, + 85: 0x5fffaf, + 86: 0x5fffd7, + 87: 0x5fffff, + 88: 0x870000, + 89: 0x87005f, + 90: 0x870087, + 91: 0x8700af, + 92: 0x8700d7, + 93: 0x8700ff, + 94: 0x875f00, + 95: 0x875f5f, + 96: 0x875f87, + 97: 0x875faf, + 98: 0x875fd7, + 99: 0x875fff, + 100: 0x878700, + 101: 0x87875f, + 102: 0x878787, + 103: 0x8787af, + 104: 0x8787d7, + 105: 0x8787ff, + 106: 0x87af00, + 107: 0x87af5f, + 108: 0x87af87, + 109: 0x87afaf, + 110: 0x87afd7, + 111: 0x87afff, + 112: 0x87d700, + 113: 0x87d75f, + 114: 0x87d787, + 115: 0x87d7af, + 116: 0x87d7d7, + 117: 0x87d7ff, + 118: 0x87ff00, + 119: 0x87ff5f, + 120: 0x87ff87, + 121: 0x87ffaf, + 122: 0x87ffd7, + 123: 0x87ffff, + 124: 0xaf0000, + 125: 0xaf005f, + 126: 0xaf0087, + 127: 0xaf00af, + 128: 0xaf00d7, + 129: 0xaf00ff, + 130: 0xaf5f00, + 131: 0xaf5f5f, + 132: 0xaf5f87, + 133: 0xaf5faf, + 134: 0xaf5fd7, + 135: 0xaf5fff, + 136: 0xaf8700, + 137: 0xaf875f, + 138: 0xaf8787, + 139: 0xaf87af, + 140: 0xaf87d7, + 141: 0xaf87ff, + 142: 0xafaf00, + 143: 0xafaf5f, + 144: 0xafaf87, + 145: 0xafafaf, + 146: 0xafafd7, + 147: 0xafafff, + 148: 0xafd700, + 149: 0xafd75f, + 150: 0xafd787, + 151: 0xafd7af, + 152: 0xafd7d7, + 153: 0xafd7ff, + 154: 0xafff00, + 155: 0xafff5f, + 156: 0xafff87, + 157: 0xafffaf, + 158: 0xafffd7, + 159: 0xafffff, + 160: 0xd70000, + 161: 0xd7005f, + 162: 0xd70087, + 163: 0xd700af, + 164: 0xd700d7, + 165: 0xd700ff, + 166: 0xd75f00, + 167: 0xd75f5f, + 168: 0xd75f87, + 169: 0xd75faf, + 170: 0xd75fd7, + 171: 0xd75fff, + 172: 0xd78700, + 173: 0xd7875f, + 174: 0xd78787, + 175: 0xd787af, + 176: 0xd787d7, + 177: 0xd787ff, + 178: 0xd7af00, + 179: 0xd7af5f, + 180: 0xd7af87, + 181: 0xd7afaf, + 182: 0xd7afd7, + 183: 0xd7afff, + 184: 0xd7d700, + 185: 0xd7d75f, + 186: 0xd7d787, + 187: 0xd7d7af, + 188: 0xd7d7d7, + 189: 0xd7d7ff, + 190: 0xd7ff00, + 191: 0xd7ff5f, + 192: 0xd7ff87, + 193: 0xd7ffaf, + 194: 0xd7ffd7, + 195: 0xd7ffff, + 196: 0xff0000, + 197: 0xff005f, + 198: 0xff0087, + 199: 0xff00af, + 200: 0xff00d7, + 201: 0xff00ff, + 202: 0xff5f00, + 203: 0xff5f5f, + 204: 0xff5f87, + 205: 0xff5faf, + 206: 0xff5fd7, + 207: 0xff5fff, + 208: 0xff8700, + 209: 0xff875f, + 210: 0xff8787, + 211: 0xff87af, + 212: 0xff87d7, + 213: 0xff87ff, + 214: 0xffaf00, + 215: 0xffaf5f, + 216: 0xffaf87, + 217: 0xffafaf, + 218: 0xffafd7, + 219: 0xffafff, + 220: 0xffd700, + 221: 0xffd75f, + 222: 0xffd787, + 223: 0xffd7af, + 224: 0xffd7d7, + 225: 0xffd7ff, + 226: 0xffff00, + 227: 0xffff5f, + 228: 0xffff87, + 229: 0xffffaf, + 230: 0xffffd7, + 231: 0xffffff, + 232: 0x080808, + 233: 0x121212, + 234: 0x1c1c1c, + 235: 0x262626, + 236: 0x303030, + 237: 0x3a3a3a, + 238: 0x444444, + 239: 0x4e4e4e, + 240: 0x585858, + 241: 0x626262, + 242: 0x6c6c6c, + 243: 0x767676, + 244: 0x808080, + 245: 0x8a8a8a, + 246: 0x949494, + 247: 0x9e9e9e, + 248: 0xa8a8a8, + 249: 0xb2b2b2, + 250: 0xbcbcbc, + 251: 0xc6c6c6, + 252: 0xd0d0d0, + 253: 0xdadada, + 254: 0xe4e4e4, + 255: 0xeeeeee, +} + +// `\033]0;TITLESTR\007` +func doTitleSequence(er *bytes.Reader) error { + var c byte + var err error + + c, err = er.ReadByte() + if err != nil { + return err + } + if c != '0' && c != '2' { + return nil + } + c, err = er.ReadByte() + if err != nil { + return err + } + if c != ';' { + return nil + } + title := make([]byte, 0, 80) + for { + c, err = er.ReadByte() + if err != nil { + return err + } + if c == 0x07 || c == '\n' { + break + } + title = append(title, c) + } + if len(title) > 0 { + title8, err := syscall.UTF16PtrFromString(string(title)) + if err == nil { + procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8))) + } + } + return nil +} + +// returns Atoi(s) unless s == "" in which case it returns def +func atoiWithDefault(s string, def int) (int, error) { + if s == "" { + return def, nil + } + return strconv.Atoi(s) +} + +// Write writes data on console +func (w *Writer) Write(data []byte) (n int, err error) { + w.mutex.Lock() + defer w.mutex.Unlock() + var csbi consoleScreenBufferInfo + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + + handle := w.handle + + var er *bytes.Reader + if w.rest.Len() > 0 { + var rest bytes.Buffer + w.rest.WriteTo(&rest) + w.rest.Reset() + rest.Write(data) + er = bytes.NewReader(rest.Bytes()) + } else { + er = bytes.NewReader(data) + } + var plaintext bytes.Buffer +loop: + for { + c1, err := er.ReadByte() + if err != nil { + plaintext.WriteTo(w.out) + break loop + } + if c1 != 0x1b { + plaintext.WriteByte(c1) + continue + } + _, err = plaintext.WriteTo(w.out) + if err != nil { + break loop + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + + switch c2 { + case '>': + continue + case ']': + w.rest.WriteByte(c1) + w.rest.WriteByte(c2) + er.WriteTo(&w.rest) + if bytes.IndexByte(w.rest.Bytes(), 0x07) == -1 { + break loop + } + er = bytes.NewReader(w.rest.Bytes()[2:]) + err := doTitleSequence(er) + if err != nil { + break loop + } + w.rest.Reset() + continue + // https://github.com/mattn/go-colorable/issues/27 + case '7': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + w.oldpos = csbi.cursorPosition + continue + case '8': + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) + continue + case 0x5b: + // execute part after switch + default: + continue + } + + w.rest.WriteByte(c1) + w.rest.WriteByte(c2) + er.WriteTo(&w.rest) + + var buf bytes.Buffer + var m byte + for i, c := range w.rest.Bytes()[2:] { + if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + m = c + er = bytes.NewReader(w.rest.Bytes()[2+i+1:]) + w.rest.Reset() + break + } + buf.Write([]byte(string(c))) + } + if m == 0 { + break loop + } + + switch m { + case 'A': + n, err = atoiWithDefault(buf.String(), 1) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.y -= short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'B': + n, err = atoiWithDefault(buf.String(), 1) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.y += short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'C': + n, err = atoiWithDefault(buf.String(), 1) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x += short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'D': + n, err = atoiWithDefault(buf.String(), 1) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x -= short(n) + if csbi.cursorPosition.x < 0 { + csbi.cursorPosition.x = 0 + } + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'E': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = 0 + csbi.cursorPosition.y += short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'F': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = 0 + csbi.cursorPosition.y -= short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'G': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + if n < 1 { + n = 1 + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = short(n - 1) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'H', 'f': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + if buf.Len() > 0 { + token := strings.Split(buf.String(), ";") + switch len(token) { + case 1: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + csbi.cursorPosition.y = short(n1 - 1) + case 2: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + n2, err := strconv.Atoi(token[1]) + if err != nil { + continue + } + csbi.cursorPosition.x = short(n2 - 1) + csbi.cursorPosition.y = short(n1 - 1) + } + } else { + csbi.cursorPosition.y = 0 + } + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'J': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + var count, written dword + var cursor coord + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + switch n { + case 0: + cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x) + case 1: + cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.window.top-csbi.cursorPosition.y)*dword(csbi.size.x) + case 2: + cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x) + } + procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'K': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + var cursor coord + var count, written dword + switch n { + case 0: + cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x) + case 1: + cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x) + case 2: + cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y} + count = dword(csbi.size.x) + } + procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'X': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + var cursor coord + var written dword + cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'm': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + attr := csbi.attributes + cs := buf.String() + if cs == "" { + procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr)) + continue + } + token := strings.Split(cs, ";") + for i := 0; i < len(token); i++ { + ns := token[i] + if n, err = strconv.Atoi(ns); err == nil { + switch { + case n == 0 || n == 100: + attr = w.oldattr + case n == 4: + attr |= commonLvbUnderscore + case (1 <= n && n <= 3) || n == 5: + attr |= foregroundIntensity + case n == 7 || n == 27: + attr = + (attr &^ (foregroundMask | backgroundMask)) | + ((attr & foregroundMask) << 4) | + ((attr & backgroundMask) >> 4) + case n == 22: + attr &^= foregroundIntensity + case n == 24: + attr &^= commonLvbUnderscore + case 30 <= n && n <= 37: + attr &= backgroundMask + if (n-30)&1 != 0 { + attr |= foregroundRed + } + if (n-30)&2 != 0 { + attr |= foregroundGreen + } + if (n-30)&4 != 0 { + attr |= foregroundBlue + } + case n == 38: // set foreground color. + if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { + if n256, err := strconv.Atoi(token[i+2]); err == nil { + if n256foreAttr == nil { + n256setup() + } + attr &= backgroundMask + attr |= n256foreAttr[n256%len(n256foreAttr)] + i += 2 + } + } else if len(token) == 5 && token[i+1] == "2" { + var r, g, b int + r, _ = strconv.Atoi(token[i+2]) + g, _ = strconv.Atoi(token[i+3]) + b, _ = strconv.Atoi(token[i+4]) + i += 4 + if r > 127 { + attr |= foregroundRed + } + if g > 127 { + attr |= foregroundGreen + } + if b > 127 { + attr |= foregroundBlue + } + } else { + attr = attr & (w.oldattr & backgroundMask) + } + case n == 39: // reset foreground color. + attr &= backgroundMask + attr |= w.oldattr & foregroundMask + case 40 <= n && n <= 47: + attr &= foregroundMask + if (n-40)&1 != 0 { + attr |= backgroundRed + } + if (n-40)&2 != 0 { + attr |= backgroundGreen + } + if (n-40)&4 != 0 { + attr |= backgroundBlue + } + case n == 48: // set background color. + if i < len(token)-2 && token[i+1] == "5" { + if n256, err := strconv.Atoi(token[i+2]); err == nil { + if n256backAttr == nil { + n256setup() + } + attr &= foregroundMask + attr |= n256backAttr[n256%len(n256backAttr)] + i += 2 + } + } else if len(token) == 5 && token[i+1] == "2" { + var r, g, b int + r, _ = strconv.Atoi(token[i+2]) + g, _ = strconv.Atoi(token[i+3]) + b, _ = strconv.Atoi(token[i+4]) + i += 4 + if r > 127 { + attr |= backgroundRed + } + if g > 127 { + attr |= backgroundGreen + } + if b > 127 { + attr |= backgroundBlue + } + } else { + attr = attr & (w.oldattr & foregroundMask) + } + case n == 49: // reset foreground color. + attr &= foregroundMask + attr |= w.oldattr & backgroundMask + case 90 <= n && n <= 97: + attr = (attr & backgroundMask) + attr |= foregroundIntensity + if (n-90)&1 != 0 { + attr |= foregroundRed + } + if (n-90)&2 != 0 { + attr |= foregroundGreen + } + if (n-90)&4 != 0 { + attr |= foregroundBlue + } + case 100 <= n && n <= 107: + attr = (attr & foregroundMask) + attr |= backgroundIntensity + if (n-100)&1 != 0 { + attr |= backgroundRed + } + if (n-100)&2 != 0 { + attr |= backgroundGreen + } + if (n-100)&4 != 0 { + attr |= backgroundBlue + } + } + procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr)) + } + } + case 'h': + var ci consoleCursorInfo + cs := buf.String() + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?1049" { + if w.althandle == 0 { + h, _, _ := procCreateConsoleScreenBuffer.Call(uintptr(genericRead|genericWrite), 0, 0, uintptr(consoleTextmodeBuffer), 0, 0) + w.althandle = syscall.Handle(h) + if w.althandle != 0 { + handle = w.althandle + } + } + } + case 'l': + var ci consoleCursorInfo + cs := buf.String() + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?1049" { + if w.althandle != 0 { + syscall.CloseHandle(w.althandle) + w.althandle = 0 + handle = w.handle + } + } + case 's': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + w.oldpos = csbi.cursorPosition + case 'u': + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) + } + } + + return len(data), nil +} + +type consoleColor struct { + rgb int + red bool + green bool + blue bool + intensity bool +} + +func (c consoleColor) foregroundAttr() (attr word) { + if c.red { + attr |= foregroundRed + } + if c.green { + attr |= foregroundGreen + } + if c.blue { + attr |= foregroundBlue + } + if c.intensity { + attr |= foregroundIntensity + } + return +} + +func (c consoleColor) backgroundAttr() (attr word) { + if c.red { + attr |= backgroundRed + } + if c.green { + attr |= backgroundGreen + } + if c.blue { + attr |= backgroundBlue + } + if c.intensity { + attr |= backgroundIntensity + } + return +} + +var color16 = []consoleColor{ + {0x000000, false, false, false, false}, + {0x000080, false, false, true, false}, + {0x008000, false, true, false, false}, + {0x008080, false, true, true, false}, + {0x800000, true, false, false, false}, + {0x800080, true, false, true, false}, + {0x808000, true, true, false, false}, + {0xc0c0c0, true, true, true, false}, + {0x808080, false, false, false, true}, + {0x0000ff, false, false, true, true}, + {0x00ff00, false, true, false, true}, + {0x00ffff, false, true, true, true}, + {0xff0000, true, false, false, true}, + {0xff00ff, true, false, true, true}, + {0xffff00, true, true, false, true}, + {0xffffff, true, true, true, true}, +} + +type hsv struct { + h, s, v float32 +} + +func (a hsv) dist(b hsv) float32 { + dh := a.h - b.h + switch { + case dh > 0.5: + dh = 1 - dh + case dh < -0.5: + dh = -1 - dh + } + ds := a.s - b.s + dv := a.v - b.v + return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) +} + +func toHSV(rgb int) hsv { + r, g, b := float32((rgb&0xFF0000)>>16)/256.0, + float32((rgb&0x00FF00)>>8)/256.0, + float32(rgb&0x0000FF)/256.0 + min, max := minmax3f(r, g, b) + h := max - min + if h > 0 { + if max == r { + h = (g - b) / h + if h < 0 { + h += 6 + } + } else if max == g { + h = 2 + (b-r)/h + } else { + h = 4 + (r-g)/h + } + } + h /= 6.0 + s := max - min + if max != 0 { + s /= max + } + v := max + return hsv{h: h, s: s, v: v} +} + +type hsvTable []hsv + +func toHSVTable(rgbTable []consoleColor) hsvTable { + t := make(hsvTable, len(rgbTable)) + for i, c := range rgbTable { + t[i] = toHSV(c.rgb) + } + return t +} + +func (t hsvTable) find(rgb int) consoleColor { + hsv := toHSV(rgb) + n := 7 + l := float32(5.0) + for i, p := range t { + d := hsv.dist(p) + if d < l { + l, n = d, i + } + } + return color16[n] +} + +func minmax3f(a, b, c float32) (min, max float32) { + if a < b { + if b < c { + return a, c + } else if a < c { + return a, b + } else { + return c, b + } + } else { + if a < c { + return b, c + } else if b < c { + return b, a + } else { + return c, a + } + } +} + +var n256foreAttr []word +var n256backAttr []word + +func n256setup() { + n256foreAttr = make([]word, 256) + n256backAttr = make([]word, 256) + t := toHSVTable(color16) + for i, rgb := range color256 { + c := t.find(rgb) + n256foreAttr[i] = c.foregroundAttr() + n256backAttr[i] = c.backgroundAttr() + } +} + +// EnableColorsStdout enable colors if possible. +func EnableColorsStdout(enabled *bool) func() { + var mode uint32 + h := os.Stdout.Fd() + if r, _, _ := procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&mode))); r != 0 { + if r, _, _ = procSetConsoleMode.Call(h, uintptr(mode|cENABLE_VIRTUAL_TERMINAL_PROCESSING)); r != 0 { + if enabled != nil { + *enabled = true + } + return func() { + procSetConsoleMode.Call(h, uintptr(mode)) + } + } + } + if enabled != nil { + *enabled = true + } + return func() {} +} diff --git a/vendor/github.com/mattn/go-colorable/go.test.sh b/vendor/github.com/mattn/go-colorable/go.test.sh new file mode 100644 index 00000000000..012162b077c --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/go.test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -e +echo "" > coverage.txt + +for d in $(go list ./... | grep -v vendor); do + go test -race -coverprofile=profile.out -covermode=atomic "$d" + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go new file mode 100644 index 00000000000..05d6f74bf6b --- /dev/null +++ b/vendor/github.com/mattn/go-colorable/noncolorable.go @@ -0,0 +1,57 @@ +package colorable + +import ( + "bytes" + "io" +) + +// NonColorable holds writer but removes escape sequence. +type NonColorable struct { + out io.Writer +} + +// NewNonColorable returns new instance of Writer which removes escape sequence from Writer. +func NewNonColorable(w io.Writer) io.Writer { + return &NonColorable{out: w} +} + +// Write writes data on console +func (w *NonColorable) Write(data []byte) (n int, err error) { + er := bytes.NewReader(data) + var plaintext bytes.Buffer +loop: + for { + c1, err := er.ReadByte() + if err != nil { + plaintext.WriteTo(w.out) + break loop + } + if c1 != 0x1b { + plaintext.WriteByte(c1) + continue + } + _, err = plaintext.WriteTo(w.out) + if err != nil { + break loop + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + if c2 != 0x5b { + continue + } + + for { + c, err := er.ReadByte() + if err != nil { + break loop + } + if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + break + } + } + } + + return len(data), nil +} diff --git a/vendor/github.com/mattn/go-isatty/LICENSE b/vendor/github.com/mattn/go-isatty/LICENSE new file mode 100644 index 00000000000..65dc692b6b1 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) Yasuhiro MATSUMOTO + +MIT License (Expat) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/mattn/go-isatty/README.md b/vendor/github.com/mattn/go-isatty/README.md new file mode 100644 index 00000000000..38418353e31 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/README.md @@ -0,0 +1,50 @@ +# go-isatty + +[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty) +[![Codecov](https://codecov.io/gh/mattn/go-isatty/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-isatty) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty) + +isatty for golang + +## Usage + +```go +package main + +import ( + "fmt" + "github.com/mattn/go-isatty" + "os" +) + +func main() { + if isatty.IsTerminal(os.Stdout.Fd()) { + fmt.Println("Is Terminal") + } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { + fmt.Println("Is Cygwin/MSYS2 Terminal") + } else { + fmt.Println("Is Not Terminal") + } +} +``` + +## Installation + +``` +$ go get github.com/mattn/go-isatty +``` + +## License + +MIT + +## Author + +Yasuhiro Matsumoto (a.k.a mattn) + +## Thanks + +* k-takata: base idea for IsCygwinTerminal + + https://github.com/k-takata/go-iscygpty diff --git a/vendor/github.com/mattn/go-isatty/doc.go b/vendor/github.com/mattn/go-isatty/doc.go new file mode 100644 index 00000000000..17d4f90ebcc --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/doc.go @@ -0,0 +1,2 @@ +// Package isatty implements interface to isatty +package isatty diff --git a/vendor/github.com/mattn/go-isatty/go.test.sh b/vendor/github.com/mattn/go-isatty/go.test.sh new file mode 100644 index 00000000000..012162b077c --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/go.test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -e +echo "" > coverage.txt + +for d in $(go list ./... | grep -v vendor); do + go test -race -coverprofile=profile.out -covermode=atomic "$d" + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go new file mode 100644 index 00000000000..d569c0c9499 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -0,0 +1,19 @@ +//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine +// +build darwin freebsd openbsd netbsd dragonfly hurd +// +build !appengine + +package isatty + +import "golang.org/x/sys/unix" + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + _, err := unix.IoctlGetTermios(int(fd), unix.TIOCGETA) + return err == nil +} + +// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go new file mode 100644 index 00000000000..31503226f6c --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -0,0 +1,16 @@ +//go:build appengine || js || nacl || wasm +// +build appengine js nacl wasm + +package isatty + +// IsTerminal returns true if the file descriptor is terminal which +// is always false on js and appengine classic which is a sandboxed PaaS. +func IsTerminal(fd uintptr) bool { + return false +} + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_plan9.go b/vendor/github.com/mattn/go-isatty/isatty_plan9.go new file mode 100644 index 00000000000..bae7f9bb3dc --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_plan9.go @@ -0,0 +1,23 @@ +//go:build plan9 +// +build plan9 + +package isatty + +import ( + "syscall" +) + +// IsTerminal returns true if the given file descriptor is a terminal. +func IsTerminal(fd uintptr) bool { + path, err := syscall.Fd2path(int(fd)) + if err != nil { + return false + } + return path == "/dev/cons" || path == "/mnt/term/dev/cons" +} + +// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_solaris.go b/vendor/github.com/mattn/go-isatty/isatty_solaris.go new file mode 100644 index 00000000000..0c3acf2dc28 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_solaris.go @@ -0,0 +1,21 @@ +//go:build solaris && !appengine +// +build solaris,!appengine + +package isatty + +import ( + "golang.org/x/sys/unix" +) + +// IsTerminal returns true if the given file descriptor is a terminal. +// see: https://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/isatty.c +func IsTerminal(fd uintptr) bool { + _, err := unix.IoctlGetTermio(int(fd), unix.TCGETA) + return err == nil +} + +// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go new file mode 100644 index 00000000000..67787657fb2 --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go @@ -0,0 +1,19 @@ +//go:build (linux || aix || zos) && !appengine +// +build linux aix zos +// +build !appengine + +package isatty + +import "golang.org/x/sys/unix" + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + _, err := unix.IoctlGetTermios(int(fd), unix.TCGETS) + return err == nil +} + +// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/github.com/mattn/go-isatty/isatty_windows.go b/vendor/github.com/mattn/go-isatty/isatty_windows.go new file mode 100644 index 00000000000..8e3c99171bf --- /dev/null +++ b/vendor/github.com/mattn/go-isatty/isatty_windows.go @@ -0,0 +1,125 @@ +//go:build windows && !appengine +// +build windows,!appengine + +package isatty + +import ( + "errors" + "strings" + "syscall" + "unicode/utf16" + "unsafe" +) + +const ( + objectNameInfo uintptr = 1 + fileNameInfo = 2 + fileTypePipe = 3 +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + ntdll = syscall.NewLazyDLL("ntdll.dll") + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx") + procGetFileType = kernel32.NewProc("GetFileType") + procNtQueryObject = ntdll.NewProc("NtQueryObject") +) + +func init() { + // Check if GetFileInformationByHandleEx is available. + if procGetFileInformationByHandleEx.Find() != nil { + procGetFileInformationByHandleEx = nil + } +} + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 +} + +// Check pipe name is used for cygwin/msys2 pty. +// Cygwin/MSYS2 PTY has a name like: +// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master +func isCygwinPipeName(name string) bool { + token := strings.Split(name, "-") + if len(token) < 5 { + return false + } + + if token[0] != `\msys` && + token[0] != `\cygwin` && + token[0] != `\Device\NamedPipe\msys` && + token[0] != `\Device\NamedPipe\cygwin` { + return false + } + + if token[1] == "" { + return false + } + + if !strings.HasPrefix(token[2], "pty") { + return false + } + + if token[3] != `from` && token[3] != `to` { + return false + } + + if token[4] != "master" { + return false + } + + return true +} + +// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler +// since GetFileInformationByHandleEx is not available under windows Vista and still some old fashion +// guys are using Windows XP, this is a workaround for those guys, it will also work on system from +// Windows vista to 10 +// see https://stackoverflow.com/a/18792477 for details +func getFileNameByHandle(fd uintptr) (string, error) { + if procNtQueryObject == nil { + return "", errors.New("ntdll.dll: NtQueryObject not supported") + } + + var buf [4 + syscall.MAX_PATH]uint16 + var result int + r, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5, + fd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0) + if r != 0 { + return "", e + } + return string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil +} + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. +func IsCygwinTerminal(fd uintptr) bool { + if procGetFileInformationByHandleEx == nil { + name, err := getFileNameByHandle(fd) + if err != nil { + return false + } + return isCygwinPipeName(name) + } + + // Cygwin/msys's pty is a pipe. + ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0) + if ft != fileTypePipe || e != 0 { + return false + } + + var buf [2 + syscall.MAX_PATH]uint16 + r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), + 4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)), + uintptr(len(buf)*2), 0, 0) + if r == 0 || e != 0 { + return false + } + + l := *(*uint32)(unsafe.Pointer(&buf)) + return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2]))) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 32ae77cecb1..80324c7f55a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -423,6 +423,9 @@ github.com/emicklei/go-restful/v3/log # github.com/evanphx/json-patch v4.12.0+incompatible ## explicit github.com/evanphx/json-patch +# github.com/fatih/color v1.13.0 +## explicit; go 1.13 +github.com/fatih/color # github.com/fsnotify/fsnotify v1.5.4 ## explicit; go 1.16 github.com/fsnotify/fsnotify @@ -510,6 +513,11 @@ github.com/google/uuid # github.com/gorilla/mux v1.8.0 ## explicit; go 1.12 github.com/gorilla/mux +# github.com/gosuri/uitable v0.0.4 +## explicit +github.com/gosuri/uitable +github.com/gosuri/uitable/util/strutil +github.com/gosuri/uitable/util/wordwrap # github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 ## explicit github.com/gregjones/httpcache @@ -617,6 +625,12 @@ github.com/mailru/easyjson/jwriter github.com/manifoldco/promptui github.com/manifoldco/promptui/list github.com/manifoldco/promptui/screenbuf +# github.com/mattn/go-colorable v0.1.12 +## explicit; go 1.13 +github.com/mattn/go-colorable +# github.com/mattn/go-isatty v0.0.17 +## explicit; go 1.15 +github.com/mattn/go-isatty # github.com/mattn/go-runewidth v0.0.14 ## explicit; go 1.9 github.com/mattn/go-runewidth From d093afcc06a82778f48acfdf20f205a6e4212adc Mon Sep 17 00:00:00 2001 From: "Xinwei Xiong(cubxxw)" <3293172751nss@gmail.com> Date: Sun, 7 May 2023 19:57:27 +0800 Subject: [PATCH 12/12] feat: release Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com> --- pkg/version/types.go | 6 +++--- scripts/make-rules/golang.mk | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/version/types.go b/pkg/version/types.go index e442856faf8..f8985f24bc9 100644 --- a/pkg/version/types.go +++ b/pkg/version/types.go @@ -34,9 +34,9 @@ type Info struct { } type Output struct { - SealerVersion Info `json:"Version,omitempty" yaml:"SealerVersion,omitempty"` - CriRuntimeVersion *CriRuntimeVersion `json:"CriVersionInfo,omitempty" yaml:"CriVersionInfo,omitempty"` - KubernetesVersion *KubernetesVersion `json:"KubernetesVersionInfo,omitempty" yaml:"KubernetesVersionInfo,omitempty"` + SealerVersion Info `json:"sealerVersion,omitempty" yaml:"sealerVersion,omitempty"` + CriRuntimeVersion *CriRuntimeVersion `json:"criVersionInfo,omitempty" yaml:"criVersionInfo,omitempty"` + KubernetesVersion *KubernetesVersion `json:"kubernetesVersionInfo,omitempty" yaml:"kubernetesVersionInfo,omitempty"` K0sVersion *k0sVersion `json:"k0sVersionInfo,omitempty" yaml:"k0sVersionInfo,omitempty"` K3sVersion *k3sVersion `json:"k3sVersionInfo,omitempty" yaml:"k3sVersionInfo,omitempty"` } diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index f92a9fc70e1..1b1462a2311 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -116,7 +116,7 @@ go.build.%: CGO_ENABLED=1; \ CC=x86_64-linux-gnu-gcc; \ if [ "$(ARCH)" == "arm64" ]; then \ - CC=aarch64-linux-gnu-gcc; \ + CC=aarch-linux-gnu-gcc; \ fi; \ CGO_ENABLED=$$CGO_ENABLED CC=$$CC GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o $(BIN_DIR)/$(COMMAND)/$(PLATFORM) $(ROOT_PACKAGE)/cmd/$(COMMAND); \ else \