Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,5 @@ Thumbs.db
# Snyk Security Extension - AI Rules (auto-generated)
.dccache
.github/instructions/snyk_rules.instructions.md

tmp/*
41 changes: 36 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,25 @@ export PACKAGE PROJECT VERSION BRANCH COMMIT BUILD REVISION

# Files
GOTESTS := $(call rwildcard,,*_test.go)
GOFILES := $(filter-out $(GOTESTS), $(call rwildcard,,*.go))
GOFILES := $(filter-out $(GOTESTS) $(call rwildcard,tools/,*.go), $(call rwildcard,,*.go))
ASSETS :=

# Testing
TEST_TIMEOUT ?= 30
COVERAGE_MODE ?= count
COVERAGE_OUT := $(COV_DIR)/coverage.out
COVERAGE_HTML := $(COV_DIR)/index.html
COVERAGE_XML := $(COV_DIR)/coverage.xml

# Tools
GO ?= go
GOOS != $(GO) env GOOS
LOGGER = bunyan -L -o short
GOBIN = $(BIN_DIR)
GOLINT ?= golangci-lint
YOLO = $(BIN_DIR)/yolo
GOCOV = $(BIN_DIR)/gocov
GOCOVXML = $(BIN_DIR)/gocov-xml
NFPM = nfpm
GOMPLATE = gomplate
PANDOC ?= pandoc
Expand Down Expand Up @@ -108,7 +112,7 @@ else
endif

# Main Recipes
.PHONY: all archive build changelog dep fmt gendoc help install lint logview publish run start stop test version vet watch
.PHONY: all archive build changelog coverage-report dep fmt gendoc help install lint logview publish run start stop test version vet watch

help: Makefile; ## Display this help
@$P "$(PROJECT) version $(VERSION) build " $(BUILD) " in $(BRANCH) branch"
Expand Down Expand Up @@ -188,7 +192,24 @@ test-failfast: ARGS=-failfast ## Run the Unit Tests and stop aft
test-race: ARGS=-race ## Run the Unit Tests with race detector
$(TEST_TARGETS): NAME=$(MAKECMDGOALS:test-%=%)
$(TEST_TARGETS): test
test: $(COVERAGE_HTML); $(info $(M) Running $(NAME:%=% )tests...) @ ## Run the Unit Tests (make test what='TestSuite/TestMe')
test tests: ; $(info $(M) Running $(NAME:%=% )tests...) @ ## Run the Unit Tests (make test what='TestSuite/TestMe')
$Q mkdir -p $(COV_DIR)
$Q $(GO) test \
-timeout $(TEST_TIMEOUT)s \
-covermode=$(COVERAGE_MODE) \
-coverprofile=$(COVERAGE_OUT) \
-v $(ARGS) $(TEST_ARG) ./...
$Q $(GO) tool cover -html=$(COVERAGE_OUT) -o $(COVERAGE_HTML)
$Q if [ -x "$(GOCOV)" ] && [ -x "$(GOCOVXML)" ]; then \
$(GOCOV) convert $(COVERAGE_OUT) | $(GOCOVXML) > $(COVERAGE_XML); \
fi

coverage-report: $(COVERAGE_OUT) | coverage-tools; @ ## Generate XML coverage report (requires gocov/gocov-xml)
$Q if [ -x "$(GOCOV)" ] && [ -x "$(GOCOVXML)" ]; then \
$(GOCOV) convert $(COVERAGE_OUT) | $(GOCOVXML) > $(COVERAGE_XML); \
else \
printf "$(M) coverage tools not installed; run: make coverage-tools\n"; \
fi

test-ci:; @ ## Run the unit tests continuously
$Q $(MAKE) --no-print-directory watch run="make test"
Expand Down Expand Up @@ -378,6 +399,16 @@ watch: $(TMP_DIR); @ ## Run a command continuously: make watch run="go test"
--exec "$(run) || exit 1"

# Download recipes
.PHONY: watch-tools coverage-tools
$(BIN_DIR)/chglog: PACKAGE=github.com/goreleaser/chglog/cmd/chglog@latest
$(BIN_DIR)/yolo: PACKAGE=github.com/azer/yolo@latest
$(BIN_DIR)/gocov: PACKAGE=github.com/axw/gocov/gocov@latest
$(BIN_DIR)/gocov-xml: PACKAGE=github.com/AlekSi/gocov-xml@latest
$(BIN_DIR)/nfpm: PACKAGE=github.com/goreleaser/nfpm/v2/cmd/nfpm@latest
$(BIN_DIR)/gomplate: PACKAGE=github.com/hairyhenderson/gomplate/v4/cmd/gomplate@latest

watch-tools: | $(YOLO)
coverage-tools: | $(GOCOV) $(GOCOVXML)

$(BIN_DIR)/%: | $(BIN_DIR) ; $(info $(M) installing $(PACKAGE)...)
$Q env GOBIN=$(BIN_DIR) $(GO) install $(PACKAGE) || status=$$? ; \
exit $$status
$Q env GOBIN=$(BIN_DIR) $(GO) install $(PACKAGE)
29 changes: 24 additions & 5 deletions cmd/commit/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,34 @@ func (commit Commit) String() string {
// MarshalJSON implements the json.Marshaler interface.
func (commit Commit) MarshalJSON() (data []byte, err error) {
type surrogate Commit
var author *user.Author
var repo *repository.Repository
var date string

if !commit.Author.IsEmpty() {
author = &commit.Author
}
if !commit.Repository.ID.IsNil() || len(commit.Repository.FullName) > 0 {
repo = &commit.Repository
}
if !commit.Date.IsZero() {
date = commit.Date.Format("2006-01-02T15:04:05.999999999-07:00")
}

data, err = json.Marshal(struct {
Type string `json:"type"`
Type string `json:"type"`
surrogate
Date string `json:"date"`
Author *user.Author `json:"author,omitempty"`
Date string `json:"date,omitempty"`
Message string `json:"message,omitempty"`
Repository *repository.Repository `json:"repository,omitempty"`
}{
Type: commit.GetType(),
surrogate: surrogate(commit),
Date: commit.Date.Format("2006-01-02T15:04:05.999999999-07:00"),
Type: commit.GetType(),
surrogate: surrogate(commit),
Author: author,
Date: date,
Message: commit.Message,
Repository: repo,
})
return data, errors.JSONMarshalError.Wrap(err)
}
19 changes: 19 additions & 0 deletions cmd/commit/commit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,25 @@ func (suite *CommitSuite) TestCanUnmarshal() {
suite.Assert().JSONEq(string(payload), string(data))
}

func (suite *CommitSuite) TestCanMarshalRawOnlyAuthor() {
c := commit.Commit{
Hash: "abc123def456abc123def456abc123def456abc1",
Message: "Commit from an external contributor",
}
c.Author.Raw = "John Doe <john@example.com>"

data, err := json.Marshal(c)
suite.Require().NoError(err)

var result map[string]any
err = json.Unmarshal(data, &result)
suite.Require().NoError(err)

author, ok := result["author"].(map[string]any)
suite.Assert().True(ok, "author key must be present when only Raw is set")
suite.Assert().Equal("John Doe <john@example.com>", author["raw"])
}

func (suite *CommitSuite) TestCanMarshalCommitReference() {
expected := `{"type": "commit", "hash": "026560720168aa12820a01e8262f6bb60f0639d1"}`
reference := commit.CommitReference{Hash: "026560720168aa12820a01e8262f6bb60f0639d1"}
Expand Down
3 changes: 1 addition & 2 deletions cmd/pullrequest/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,7 @@ func createProcess(cmd *cobra.Command, args []string) (err error) {
&pullrequest,
)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create pullrequest: %s\n", err)
os.Exit(1)
return err
}
return profile.Print(cmd.Context(), cmd, pullrequest)
}
6 changes: 3 additions & 3 deletions cmd/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ type Repository struct {
Owner user.User `json:"owner,omitempty" mapstructure:"owner"`
Workspace *workspace.Workspace `json:"workspace,omitempty" mapstructure:"workspace"`
Project project.Project `json:"project,omitempty" mapstructure:"project"`
HasIssues bool `json:"has_issues" mapstructure:"has_issues"`
HasWiki bool `json:"has_wiki" mapstructure:"has_wiki"`
IsPrivate bool `json:"is_private" mapstructure:"is_private"`
HasIssues bool `json:"has_issues,omitempty" mapstructure:"has_issues"`
HasWiki bool `json:"has_wiki,omitempty" mapstructure:"has_wiki"`
IsPrivate bool `json:"is_private,omitempty" mapstructure:"is_private"`
ForkPolicy string `json:"fork_policy,omitempty" mapstructure:"fork_policy"`
Size int64 `json:"size,omitempty" mapstructure:"size"`
Language string `json:"language,omitempty" mapstructure:"language"`
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module github.com/gildas/bitbucket-cli
go 1.26

require (
github.com/AlekSi/gocov-xml v1.2.0
github.com/axw/gocov v1.2.1
github.com/briandowns/spinner v1.23.2
github.com/gildas/go-cache v0.2.2
github.com/gildas/go-core v0.6.4
Expand Down
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ cloud.google.com/go/longrunning v1.0.0 h1:lwzWEYD8+NkYV7dhexOz6kmlvajZA70+bW/xMh
cloud.google.com/go/longrunning v1.0.0/go.mod h1:8nqFBPOO1U/XkhWl0I19AMZEphrHi73VNABIpKYaTwM=
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
github.com/AlekSi/gocov-xml v1.2.0 h1:TGx+qVSgBn655Ejv8b2mgPIGvIa8ZxGFSPXuWf0J3Vw=
github.com/AlekSi/gocov-xml v1.2.0/go.mod h1:g1dRVOCHjKkMtlPfW6BokJ/qxoeZ1uPNAK7A/ii3CUo=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
Expand All @@ -23,6 +25,9 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/axw/gocov v1.1.0/go.mod h1:H9G4tivgdN3pYSSVrTFBr6kGDCmAkgbJhtxFzAvgcdw=
github.com/axw/gocov v1.2.1 h1:bqtQDBC2tQWcPzTYIVxK0EDCfNRLwsk4NZ0+GB4hX8Q=
github.com/axw/gocov v1.2.1/go.mod h1:l11/vZBBKfQEE+42jF47myjDrRZHM+hR+XgGjI6FopU=
github.com/briandowns/spinner v1.23.2 h1:Zc6ecUnI+YzLmJniCfDNaMbW0Wid1d5+qcTq4L2FW8w=
github.com/briandowns/spinner v1.23.2/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
Expand Down Expand Up @@ -209,18 +214,22 @@ go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
golang.org/x/exp v0.0.0-20260603202125-055de637280b h1:v1uXiEBHo8QA0LiGCo7UgHMzHT4Kdfpl2zmtH5vaP1Q=
golang.org/x/exp v0.0.0-20260603202125-055de637280b/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -232,12 +241,14 @@ golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/api v0.283.0 h1:0lkp8u0MPwJVHqRL+nJlMAoZVVzbmiXmFHXMOTmSPik=
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

func main() {
_ = godotenv.Load()
_ = godotenv.Load() // .env is optional; error is expected when the file is absent
if len(os.Getenv("LOG_DESTINATION")) == 0 {
os.Setenv("LOG_DESTINATION", "nil")
}
Expand Down
Loading