Skip to content
Merged
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
./git-team
target/
mocks/
.idea/
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
VERSION := $(shell grep -E "version\s+=" `pwd`/main.go | awk -F '"' '{print $$2}')

GOOS :=
GOARCH :=
prefix :=
UNAME_S := $(shell uname -s)
UNAME_M := $(shell uname -m)
ifeq ($(UNAME_S),Darwin)
GOOS=darwin
prefix:=/usr/local
endif
ifeq ($(UNAME_M),arm64)
GOARCH=arm64
endif
ifeq ($(UNAME_S),Linux)
GOOS=linux
prefix:=/usr
endif
ifeq ($(UNAME_M),x86_64)
GOARCH=amd64
endif

exec_prefix := $(prefix)
bindir := $(exec_prefix)/bin
Expand Down Expand Up @@ -47,7 +55,7 @@ test: go-test hookscript-tests
verify: test acceptance-tests

mocks:
docker run --rm --user "$(shell id -u):$(shell id -g)" -v "$(CURR_DIR):/src" -w /src vektra/mockery:v2.14.0 --dir=src/ --all --keeptree
docker run --rm --user "$(shell id -u):$(shell id -g)" -v "$(CURR_DIR):/src" -w /src vektra/mockery:v2.15.0 --dir=src/ --all --keeptree

go-test: mocks deps
go test -cover ./src/...
Expand All @@ -61,7 +69,7 @@ ifndef GOPATH
$(error GOPATH is not set)
endif
mkdir -p $(CURR_DIR)/target/bin
CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=amd64 go build -o $(CURR_DIR)/target/bin ./...
CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(CURR_DIR)/target/bin ./...
@echo "[INFO] Successfully built git-team version v$(VERSION)"

man-page: deps
Expand Down
2 changes: 1 addition & 1 deletion acceptance-tests.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ RUN go mod download
COPY src ./src
COPY main.go .

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install ./...
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go install ./...

# ----------------------------------------------------------------- #

Expand Down
2 changes: 1 addition & 1 deletion acceptance-tests/disable_global.bats
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ teardown() {
assert_line "ls: /home/git-team-acceptance-test/.git-team/commit-templates/global/COMMIT_TEMPLATE: No such file or directory"
}

@test "git-team: (scope: global) disable should treat a previously disabled git-team idempotently" {
@test "git-team: (scope: global) disable should treat a previously disabled git-team in an idempotent way" {
run /usr/local/bin/git-team disable
assert_success
assert_line "git-team disabled"
Expand Down
2 changes: 1 addition & 1 deletion acceptance-tests/disable_repo_local.bats
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ teardown() {
assert_line "ls: /home/git-team-acceptance-test/.git-team/commit-templates/repo-local/$REPO_CHECKSUM: No such file or directory"
}

@test "git-team: (scope: repo-local) disable should treat a previously disabled git-team idempotently" {
@test "git-team: (scope: repo-local) disable should treat a previously disabled git-team in an idempotent way" {
run /usr/local/bin/git-team disable
assert_success
assert_line "git-team disabled"
Expand Down
12 changes: 11 additions & 1 deletion acceptance-tests/status_global.bats
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ setup() {
assert_line 'git-team disabled'
}

@test 'git-team: (scope: global) status should properly disaplay the enabled status' {
@test 'git-team: (scope: global) status should properly display the enabled status' {
/usr/local/bin/git-team enable 'A <[email protected]>' 'B <[email protected]>' 'C <[email protected]>'

run /usr/local/bin/git-team status
Expand All @@ -27,3 +27,13 @@ setup() {
/usr/local/bin/git-team disable
}

@test 'git-team: (scope: global) status should properly display the enabled status in a json format' {
/usr/local/bin/git-team enable 'A <[email protected]>' 'B <[email protected]>' 'C <[email protected]>'

run /usr/local/bin/git-team status --json
assert_success
assert_line --index 0 '{"status":"enabled","coAuthors":["A <[email protected]>","B <[email protected]>","C <[email protected]>"],"previousHooksPath":""}'

/usr/local/bin/git-team disable
}

11 changes: 10 additions & 1 deletion acceptance-tests/status_repo_local.bats
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ teardown() {
assert_line 'git-team disabled'
}

@test 'git-team: (scope: repo-local) status should properly disaplay the enabled status' {
@test 'git-team: (scope: repo-local) status should properly display the enabled status' {
/usr/local/bin/git-team enable 'A <[email protected]>' 'B <[email protected]>' 'C <[email protected]>'

run /usr/local/bin/git-team status
Expand All @@ -44,6 +44,15 @@ teardown() {
/usr/local/bin/git-team disable
}

@test 'git-team: (scope: repo-local) status should properly display the enabled status' {
/usr/local/bin/git-team enable 'A <[email protected]>' 'B <[email protected]>' 'C <[email protected]>'

run /usr/local/bin/git-team status --json
assert_success
assert_line --index 0 '{"status":"enabled","coAuthors":["A <[email protected]>","B <[email protected]>","C <[email protected]>"],"previousHooksPath":""}'

/usr/local/bin/git-team disable
}

@test 'git-team: (scope: repo-local) status should fail when not inside a git repository' {
cd /tmp
Expand Down
2 changes: 1 addition & 1 deletion hookscript-tests.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ RUN go mod download
COPY src ./src
COPY main.go .

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install ./...
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go install ./...

# ----------------------------------------------------------------- #

Expand Down
2 changes: 1 addition & 1 deletion src/command/disable/cliadapter/cmd/cmd_mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func Command() *cli.Command {
Name: "disable",
Usage: "Use default commit template and remove prepare-commit-msg hook",
Action: func(c *cli.Context) error {
return commandadapter.Run(policy(), disableeventadapter.MapEventToEffectFactory(statuscmdmapper.Policy()))
return commandadapter.Run(policy(), disableeventadapter.MapEventToEffectFactory(statuscmdmapper.Policy(false)))
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/command/enable/cliadapter/cmd/cmd_mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func Command() *cli.Command {
Action: func(c *cli.Context) error {
coauthors := c.Args().Slice()
useAll := c.Bool("all")
return commandadapter.Run(policy(&coauthors, &useAll), enableeventadapter.MapEventToEffectFactory(statuscmdmapper.Policy()))
return commandadapter.Run(policy(&coauthors, &useAll), enableeventadapter.MapEventToEffectFactory(statuscmdmapper.Policy(false)))
},
BashComplete: func(c *cli.Context) {
remainingAliases := aliascompletion.NewAliasShellCompletion(gitconfig.NewDataSource()).Complete(c.Args().Slice())
Expand Down
10 changes: 8 additions & 2 deletions src/command/status/cliadapter/cmd/cmd_mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,25 @@ func Command() *cli.Command {
return &cli.Command{
Name: "status",
Usage: "Print the current status",
Flags: []cli.Flag{
&cli.BoolFlag{Name: "json", Value: false, Usage: "Display the current status as a JSON formatted struct"},
},
Action: func(c *cli.Context) error {
return commandadapter.Run(Policy(), statuseventadapter.MapEventToEffect)
stateAsJson := c.Bool("json")

return commandadapter.Run(Policy(stateAsJson), statuseventadapter.MapEventToEffect)
},
}
}

// Policy the status policy constructor
func Policy() status.Policy {
func Policy(stateAsJson bool) status.Policy {
return status.Policy{
Deps: status.Dependencies{
ConfigReader: config.NewGitconfigDataSource(gitconfig.NewDataSource()),
StateReader: state.NewGitConfigDataSource(gitconfig.NewDataSource()),
ActivationValidator: activation.NewGitConfigDataSource(gitconfig.NewDataSource()),
StateAsJson: stateAsJson,
},
}
}
15 changes: 15 additions & 0 deletions src/command/status/cliadapter/event/event_mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package statuseventadapter

import (
"bytes"
"encoding/json"
"fmt"
"sort"

Expand All @@ -17,6 +18,9 @@ import (
func MapEventToEffect(event events.Event) effects.Effect {
switch evt := event.(type) {
case status.StateRetrievalSucceeded:
if evt.StateAsJson {
return effects.NewExitOkMsg(toJson(evt.State))
}
return effects.NewExitOkMsg(toString(evt.State))
case status.StateRetrievalFailed:
return effects.NewExitErrMsg(evt.Reason)
Expand Down Expand Up @@ -44,3 +48,14 @@ func toString(theState state.State) string {

return buffer.String()
}

func toJson(theState state.State) string {
var buffer bytes.Buffer
encoder := json.NewEncoder(&buffer)
encoder.SetEscapeHTML(false)
err := encoder.Encode(theState)
if err != nil {
return buffer.String()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't we miss an encoding error this way?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are completely right. I'll think about a solution and will update the PR shortly

}
return buffer.String()
}
3 changes: 2 additions & 1 deletion src/command/status/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (

// StateRetrievalSucceeded successfully got the current state
type StateRetrievalSucceeded struct {
State state.State
State state.State
StateAsJson bool
}

// StateRetrievalFailed failed to get the current state
Expand Down
5 changes: 3 additions & 2 deletions src/command/status/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Dependencies struct {
StateReader state.Reader
ConfigReader config.Reader
ActivationValidator activation.Validator
StateAsJson bool
}

// Policy the policy to apply
Expand All @@ -37,10 +38,10 @@ func (policy Policy) Apply() events.Event {
return StateRetrievalFailed{Reason: fmt.Errorf("failed to get status with activation-scope=%s: not inside a git repository", activationScope)}
}

state, stateRepositoryQueryErr := deps.StateReader.Query(cfg.ActivationScope)
retState, stateRepositoryQueryErr := deps.StateReader.Query(cfg.ActivationScope)
if stateRepositoryQueryErr != nil {
return StateRetrievalFailed{Reason: fmt.Errorf("failed to query current state: %s", stateRepositoryQueryErr)}
}

return StateRetrievalSucceeded{State: state}
return StateRetrievalSucceeded{State: retState, StateAsJson: deps.StateAsJson}
}
6 changes: 3 additions & 3 deletions src/shared/state/entity/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const (

// State the state of git-team
type State struct {
Status teamStatus
Coauthors []string
PreviousHooksPath string
Status teamStatus `json:"status"`
Coauthors []string `json:"coAuthors"`
PreviousHooksPath string `json:"previousHooksPath"`
}

// NewStateEnabled the constructor for the enabled state
Expand Down