Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement handling of command-line interrupts #1

Merged
merged 2 commits into from
Mar 10, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
main: handle SIGINT signals
  • Loading branch information
atosatto committed Mar 10, 2020
commit 9b411aa03777c5b978372a56f011506086fb0886
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ before:
builds:
- env:
- CGO_ENABLED=0
main: .
main: ./cmd/ansible-requirements-lint/main.go
binary: ansible-requirements-lint
ldflags:
- -s -w
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ all: clean fmt lint test staticcheck vet build ## Lints, tests and builds the co
build: $(NAME) ## Builds a dynamic executable or package.

$(NAME): $(shell find . -type f -name '*.go') Makefile
$(GO) build -ldflags $(LDFLAGS) -o $(BUILDDIR)/$(NAME) .
$(GO) build -ldflags $(LDFLAGS) -o $(BUILDDIR)/$(NAME) ./cmd/$(NAME)

.PHONY: fmt
fmt: ## Verifies that all files are `gofmt`ed.
Expand Down Expand Up @@ -65,7 +65,7 @@ coverage: ## Runs the go test and builds a coverage report.

.PHONY: install
install: ## Installs the binaries.
$(GO) install -a -ldflags $(LDFLAGS) .
$(GO) install -a -ldflags $(LDFLAGS) ./cmd/$(NAME)

.PHONY: vendor
vendor: ## Updates the vendors directory.
Expand Down
50 changes: 23 additions & 27 deletions main.go → cmd/ansible-requirements-lint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"flag"
"fmt"
"os"
"os/signal"

"github.com/atosatto/ansible-requirements-lint/linter"
"github.com/atosatto/ansible-requirements-lint/provider"
Expand Down Expand Up @@ -58,6 +59,25 @@ func main() {
usageAndExit("")
}

// handle Ctrl+C
ctx, cancel := context.WithCancel(context.Background())
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)

// call cancel on the context
defer func() {
signal.Stop(c)
cancel()
}()
go func() {
select {
case <-c:
cancel()
case <-ctx.Done():
}
}()

// parse the requirements file
r, err := requirements.UnmarshalFromFile(requirementsFile)
if err != nil {
switch {
Expand All @@ -70,37 +90,13 @@ func main() {
}
}

ctx := context.Background()
rolesChan := make(chan requirements.Role)
resultsChan := make(chan linter.Result)

// run the updates linter
updatesLinterOpts := linter.UpdatesLinterOptions{
AnsibleGalaxyURL: *galaxyURL,
}
updatesLinter := linter.NewUpdatesLinter(updatesLinterOpts)
go updatesLinter.RunWithContext(ctx, rolesChan, resultsChan)

var errOrWarn = false
for _, role := range r.Roles {
rolesChan <- role
result := <-resultsChan

switch {
case result.Level == linter.LevelInfo && *verbose:
color.New(color.Bold, color.FgHiCyan).Printf("INFO: ")
fmt.Printf("%s.\n", result.Msg)
case result.Level == linter.LevelWarning:
color.New(color.Bold, color.FgHiYellow).Printf("WARN: ")
fmt.Printf("%s.\n", result.Msg)
errOrWarn = true
case result.Level == linter.LevelError:
color.New(color.Bold, color.FgHiRed).Printf("ERR: ")
fmt.Printf("%v.\n", result.Err)
errOrWarn = true
}
}
numUpdatesOrErrs := runUpdatesLinter(ctx, r, updatesLinterOpts)

if errOrWarn {
if numUpdatesOrErrs > 0 {
os.Exit(1)
}
}
Expand Down
42 changes: 42 additions & 0 deletions cmd/ansible-requirements-lint/updates.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"context"
"fmt"

"github.com/atosatto/ansible-requirements-lint/linter"
"github.com/atosatto/ansible-requirements-lint/requirements"
"github.com/fatih/color"
)

// runUpdatesLinter updates the Roles defined in the Requirements r.
// The total number of updates and errors detected by the updatesLinter is returned as result of the function execution.
func runUpdatesLinter(ctx context.Context, r *requirements.Requirements, updatesLinterOpts linter.UpdatesLinterOptions) int {
rolesChan := make(chan requirements.Role)
resultsChan := make(chan linter.Result)

updatesLinter := linter.NewUpdatesLinter(updatesLinterOpts)
go updatesLinter.RunWithContext(ctx, rolesChan, resultsChan)

var numUpdatesOrErr = 0
for _, role := range r.Roles {
rolesChan <- *role
result := <-resultsChan

switch {
case result.Level == linter.LevelInfo && *verbose:
color.New(color.Bold, color.FgHiCyan).Printf("INFO: ")
fmt.Printf("%s.\n", result.Msg)
case result.Level == linter.LevelWarning:
color.New(color.Bold, color.FgHiYellow).Printf("WARN: ")
fmt.Printf("%s.\n", result.Msg)
numUpdatesOrErr++
case result.Level == linter.LevelError:
color.New(color.Bold, color.FgHiRed).Printf("ERR: ")
fmt.Printf("%v.\n", result.Err)
numUpdatesOrErr++
}
}

return numUpdatesOrErr
}
6 changes: 3 additions & 3 deletions requirements/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ func Unmarshal(data []byte) (*Requirements, error) {
return &requirements, nil
}

func parseRolesFromNodesList(nodes []*yaml.Node) ([]Role, error) {
var res []Role
func parseRolesFromNodesList(nodes []*yaml.Node) ([]*Role, error) {
var res []*Role

for _, n := range nodes {
var role Role
Expand All @@ -96,7 +96,7 @@ func parseRolesFromNodesList(nodes []*yaml.Node) ([]Role, error) {
return nil, fmt.Errorf("decoding line %d as role: %w", n.Line, err)
}
role.node = n
res = append(res, role)
res = append(res, &role)
}

return res, nil
Expand Down
2 changes: 1 addition & 1 deletion requirements/requirements.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type Requirements struct {

// Roles is the list of roles defined
// in the Requirements file.
Roles []Role `yaml:",inline"`
Roles []*Role `yaml:",inline"`

// Children is the list of requirements
// files included by the Requirement file.
Expand Down