Skip to content

Commit

Permalink
Merge branch 'main' into allow_direct_task_calls
Browse files Browse the repository at this point in the history
  • Loading branch information
zachariahmiller authored Sep 20, 2024
2 parents 5862fde + 5062dc5 commit 31bd434
Show file tree
Hide file tree
Showing 19 changed files with 243 additions and 38 deletions.
10 changes: 2 additions & 8 deletions .github/actions/install-tools/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,5 @@ description: "Install pipeline tools"
runs:
using: composite
steps:
- uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3.5.0

- uses: anchore/sbom-action/download-syft@95b086ac308035dc0850b3853be5b7ab108236a8 # v0.16.1

- run: "curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin"
shell: bash

- uses: docker/setup-buildx-action@4fd812986e6c8c2a69e18311145f9371337f27d4 # v3.4.0
# used by goreleaser to create SBOMs
- uses: anchore/sbom-action/download-syft@61119d458adab75f756bc0b9e4bde25725f86a7a # v0.17.2
2 changes: 1 addition & 1 deletion .github/actions/save-logs/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: "Save debug logs"
runs:
using: composite
steps:
- uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: debug-log
path: /tmp/maru-*.log
2 changes: 1 addition & 1 deletion .github/actions/zarf/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ runs:
- uses: defenseunicorns/setup-zarf@main
with:
# renovate: datasource=github-tags depName=zarf-dev/zarf
version: v0.39.0
version: v0.40.1
2 changes: 1 addition & 1 deletion .github/workflows/commitlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4

- name: Install commitlint
run: npm install --save-dev @commitlint/{config-conventional,cli}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
# Upload the contents of the build directory for later stages to use
- name: Upload build artifacts
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: build-artifacts
path: build/
Expand Down Expand Up @@ -104,7 +104,7 @@ jobs:
- name: Get Brew tap repo token
id: brew-tap-token
uses: actions/create-github-app-token@31c86eb3b33c9b601a1f60f98dcbfd1d70f379b4 # v1.10.3
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
with:
app-id: ${{ secrets.HOMEBREW_TAP_WORKFLOW_GITHUB_APP_ID }}
private-key: ${{ secrets.HOMEBREW_TAP_WORKFLOW_GITHUB_APP_SECRET }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/scan-codeql.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
run: make build-cli-linux-amd

- name: Initialize CodeQL
uses: github/codeql-action/init@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12
uses: github/codeql-action/init@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
env:
CODEQL_EXTRACTOR_GO_BUILD_TRACING: on
with:
Expand All @@ -54,6 +54,6 @@ jobs:


- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12
uses: github/codeql-action/analyze@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
with:
category: "/language:${{matrix.language}}"
2 changes: 1 addition & 1 deletion .github/workflows/scan-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
extra_args: --all-files --verbose # pre-commit run --all-files --verbose

- name: Run Revive Action by pulling pre-built image
uses: docker://morphy/revive-action:v2@sha256:087d4e61077087755711ab7e9fae3cc899b7bb07ff8f6a30c3dfb240b1620ae8
uses: docker://morphy/revive-action:v2@sha256:540bffd78895d1525b034b861d29edcb96577bcb3b187a5199342dc8656034ee
with:
config: revive.toml
# Exclude patterns, separated by semicolons (optional)
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/scorecard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
persist-credentials: false

- name: "Run analysis"
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
with:
results_file: results.sarif
results_format: sarif
Expand All @@ -37,14 +37,14 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: SARIF file
path: results.sarif
retention-days: 5

# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12
uses: github/codeql-action/upload-sarif@294a9d92911152fe08befb9ec03e240add280cb3 # v3.26.8
with:
sarif_file: results.sarif
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.21.8
require (
github.com/defenseunicorns/pkg/exec v0.0.1
github.com/defenseunicorns/pkg/helpers/v2 v2.0.1
github.com/goccy/go-yaml v1.11.3
github.com/goccy/go-yaml v1.12.0
github.com/invopop/jsonschema v0.12.0
github.com/pterm/pterm v0.12.79
github.com/spf13/cobra v1.8.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.18.0 h1:BvolUXjp4zuvkZ5YN5t7ebzbhlUtPsPm2S9NAZ5nl9U=
github.com/go-playground/validator/v10 v10.18.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I=
github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM=
github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
Expand Down
1 change: 1 addition & 0 deletions src/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func cliSetup() {
"info": message.InfoLevel,
"debug": message.DebugLevel,
"trace": message.TraceLevel,
"error": message.ErrorLevel,
}

printViperConfigUsed()
Expand Down
4 changes: 2 additions & 2 deletions src/config/lang/english.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ const (
const (
RootCmdShort = "CLI for the maru runner"
RootCmdFlagSkipLogFile = "Disable log file creation"
RootCmdFlagLogLevel = "Log level for the runner. Valid options are: warn, info, debug, trace"
RootCmdFlagLogLevel = "Log level for the runner. Valid options are: error, warn, info, debug, trace"
RootCmdFlagNoProgress = "Disable fancy UI progress bars, spinners, logos, etc"
RootCmdErrInvalidLogLevel = "Invalid log level. Valid options are: warn, info, debug, trace."
RootCmdErrInvalidLogLevel = "Invalid log level. Valid options are: error, warn, info, debug, trace."
RootCmdFlagArch = "Architecture for the runner"
RootCmdFlagTempDir = "Specify the temporary directory to use for intermediate files"
)
Expand Down
32 changes: 23 additions & 9 deletions src/message/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,31 @@ import (
type LogLevel int

const (
// WarnLevel level. Non-critical entries that deserve eyes.
WarnLevel LogLevel = iota
// Supported log levels. These are in order of increasing severity, and
// match the constants in the log/slog package.

// TraceLevel level. Effectively the same as Debug but with line numbers.
//
// NOTE: There currently is no Trace() function in the log/slog package. In
// order to use this level, you must use message.SLog.Log() and specify the
// level. Maru currently uses the Trace level specifically for adding line
// numbers to logs from calls to message.SLog.Debug(). Because of this,
// Trace is effectively the same as Debug but with line numbers.
TraceLevel LogLevel = -8
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
DebugLevel LogLevel = -4
// InfoLevel level. General operational entries about what's going on inside the
// application.
InfoLevel
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
DebugLevel
// TraceLevel level. Designates finer-grained informational events than the Debug.
TraceLevel
InfoLevel LogLevel = 0
// WarnLevel level. Non-critical entries that deserve eyes.
WarnLevel LogLevel = 4
// ErrorLevel level. Errors only.
ErrorLevel LogLevel = 8
)

// logLevel is the log level for the runner
// logLevel is the log level for the runner. When set, log messages with a level
// greater than or equal to this level will be logged. Log messages with a level
// lower than this level will be ignored.
var logLevel = InfoLevel

// logFile acts as a buffer for logFile generation
Expand Down Expand Up @@ -59,7 +72,8 @@ func LogFileLocation() string {
// SetLogLevel sets the log level.
func SetLogLevel(lvl LogLevel) {
logLevel = lvl
if logLevel >= DebugLevel {
// Enable pterm debug messages if the log level is Trace or Debug
if logLevel <= DebugLevel {
pterm.EnableDebugMessages()
}
}
Expand Down
158 changes: 158 additions & 0 deletions src/message/logging_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023-Present the Maru Authors

// Package message provides a rich set of functions for displaying messages to the user.
package message

import (
"bytes"
"log/slog"
"slices"
"strings"

"testing"

"github.com/pterm/pterm"
)

func Test_LogLevel_Diff(t *testing.T) {
maruLogger := slog.New(MaruHandler{})

cases := map[string]struct {
// the level we're set to log at with SetLogLevel(). We expect logs with
// a lower level to be ignored.
setLevel LogLevel
// the level which we will log, e.g. SLog.Debug(), SLog.Info(), etc.
logLevel LogLevel
// the expected output of the log. We special case DebugLevel as it
// should contain a timestamp.
expected string
}{
"DebugLevel": {
setLevel: DebugLevel,
logLevel: DebugLevel,
expected: "DEBUG test",
},
"InfoInfoLevel": {
setLevel: InfoLevel,
logLevel: InfoLevel,
expected: "INFO test",
},
"InfoWarnLevel": {
setLevel: InfoLevel,
logLevel: WarnLevel,
expected: "WARNING test",
},
"WarnInfoLevel": {
setLevel: WarnLevel,
logLevel: InfoLevel,
expected: "",
},
"InfoErrorLevel": {
setLevel: InfoLevel,
logLevel: ErrorLevel,
expected: "ERROR test",
},
"TraceInfoLevel": {
setLevel: TraceLevel,
logLevel: InfoLevel,
expected: "INFO test",
},
"TraceDebugLevel": {
setLevel: TraceLevel,
logLevel: DebugLevel,
expected: "DEBUG test",
},
"TraceErrorLevel": {
setLevel: TraceLevel,
logLevel: ErrorLevel,
expected: "ERROR test",
},
"ErrorWarnLevel": {
setLevel: ErrorLevel,
logLevel: WarnLevel,
expected: "",
},
"ErrorErrorLevel": {
setLevel: ErrorLevel,
logLevel: ErrorLevel,
expected: "ERROR test",
},
"ErrorInfoLevel": {
setLevel: ErrorLevel,
logLevel: InfoLevel,
expected: "",
},
}

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
SetLogLevel(tc.setLevel)

// set the underlying writer, like we do in utils/utils.go
var outBuf bytes.Buffer
pterm.SetDefaultOutput(&outBuf)

switch tc.logLevel {
case DebugLevel:
maruLogger.Debug("test")
case InfoLevel:
maruLogger.Info("test")
case WarnLevel:
maruLogger.Warn("test")
case ErrorLevel:
maruLogger.Error("test")
}
content := outBuf.String()
// remove color codes
content = pterm.RemoveColorFromString(content)
// remove extra whitespace from the output
content = strings.TrimSpace(content)
parts := strings.Split(tc.expected, " ")
for _, part := range parts {
if !strings.Contains(content, part) {
t.Errorf("Expected debug message to contain '%s', but it didn't: (%s)", part, content)
}
}
// if the set level is Trace and the log level is Debug, then we
// expect extra debug lines to be printed. Conversely, if it's trace
// but not Debug, then we expect no extra debug lines to be printed.
partsOutput := strings.Split(content, " ")
// when debugging with TraceLevel, spliting on spaces will result in a slice
// like so:
// []string{
// "DEBUG",
// "",
// "",
// "2024-09-19T10:21:16-05:00",
// "",
// "-",
// "",
// "test\n└",
// "(/Users/clint/go/github.com/defenseunicorns/maru-runner/src/message/slog.go:56)",
// }
//
// here we sort the slice to move the timestamp to the front,
// then compact to remove them. The result should be a slice of
// 6 eleements.
//
// While debugging without trace level, we expect the same slice
// except there is no file name and line number, so it would have 5
// elements.
slices.Sort(partsOutput)
partsOutput = slices.Compact(partsOutput)
expectedLen := 3
if tc.logLevel == DebugLevel {
expectedLen = 5
}
if tc.setLevel == TraceLevel && tc.logLevel == DebugLevel {
expectedLen = 6
}

if len(partsOutput) > expectedLen {
t.Errorf("Expected debug message to contain timestamp, but it didn't: (%s)", content)
}
})
}

}
4 changes: 2 additions & 2 deletions src/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func paragraph(format string, a ...any) string {
}

func debugPrinter(offset int, a ...any) {
printer := pterm.Debug.WithShowLineNumber(logLevel > 2).WithLineNumberOffset(offset)
printer := pterm.Debug.WithShowLineNumber(logLevel <= TraceLevel).WithLineNumberOffset(offset)
now := time.Now().Format(time.RFC3339)
// prepend to a
a = append([]any{now, " - "}, a...)
Expand All @@ -86,5 +86,5 @@ func debugPrinter(offset int, a ...any) {
}

func errorPrinter(offset int) *pterm.PrefixPrinter {
return pterm.Error.WithShowLineNumber(logLevel > 2).WithLineNumberOffset(offset)
return pterm.Error.WithShowLineNumber(logLevel <= TraceLevel).WithLineNumberOffset(offset)
}
19 changes: 16 additions & 3 deletions src/message/slog.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,22 @@ var (
// MaruHandler is a simple handler that implements the slog.Handler interface
type MaruHandler struct{}

// Enabled is always set to true as Maru logging functions are already aware of if they are allowed to be called
func (z MaruHandler) Enabled(_ context.Context, _ slog.Level) bool {
return true
// Enabled determines if the handler is enabled for the given level. This
// function is called for every log message and will compare the level of the
// message to the log level set (default is info). Log levels are defined in
// src/message/logging.go and match the levels used in the underlying log/slog
// package. Logs with a level below the set log level will be ignored.
//
// Examples:
//
// SetLogLevel(TraceLevel) // show everything, with file names and line numbers
// SetLogLevel(DebugLevel) // show everything
// SetLogLevel(InfoLevel) // show info and above (does not show debug logs)
// SetLogLevel(WarnLevel) // show warn and above (does not show debug/info logs)
// SetLogLevel(ErrorLevel) // show only errors (does not show debug/info/warn logs)
func (z MaruHandler) Enabled(_ context.Context, level slog.Level) bool {
// only log if the log level is greater than or equal to the set log level
return int(level) >= int(logLevel)
}

// WithAttrs is not suppported
Expand Down
Loading

0 comments on commit 31bd434

Please sign in to comment.