Skip to content
Merged
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
35 changes: 32 additions & 3 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,38 @@
name: Request review

on:
pull_request_target:
types: [opened, reopened, ready_for_review]

permissions:
pull-requests: write

concurrency:
group: request-review-${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true

env:
REVIEWER: 'IdanKoblik'

jobs:
request-review:
uses: GoScouter/.github/.github/workflows/request-review.yml@main
permissions:
pull-requests: write
name: Request review
runs-on: ubuntu-latest
# Drafts get a reviewer once they're marked ready, not before.
if: github.event.pull_request.draft == false
steps:
- name: Request review
env:
GH_TOKEN: ${{ github.token }}
PR_URL: ${{ github.event.pull_request.html_url }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
run: |
# GitHub rejects a review request naming the pull request's own
# author, so IdanKoblik's own pull requests are left alone.
if [ "$PR_AUTHOR" = "$REVIEWER" ]; then
echo "::notice::$PR_AUTHOR authored this pull request — no review requested."
exit 0
fi

gh pr edit "$PR_URL" --add-reviewer "$REVIEWER"
echo "::notice::Requested review from $REVIEWER."
79 changes: 35 additions & 44 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"flag"
"fmt"
"io"
"log/slog"
"os"
"os/signal"
"strings"
Expand All @@ -16,7 +15,6 @@ import (

"goscouter/internal"
"goscouter/internal/cmd"
"goscouter/internal/logger"
"goscouter/internal/module"
"goscouter/internal/style"
"goscouter/internal/terminal"
Expand All @@ -37,70 +35,61 @@ func main() {
flag.Parse()

if *version {
fmt.Println("Version:", VERSION)
os.Exit(0)
fmt.Println(versionString())
return
}

if *targetSite == "" {
fmt.Println("Usage: gs --target <example.com>")
fmt.Fprintln(os.Stderr, "Usage: gs --target <example.com>")
os.Exit(1)
}

if err := run(*targetSite); err != nil {
fmt.Fprintf(os.Stderr, "%s\r\n", style.Error(err.Error()))
os.Exit(1)
}
}

func run(target string) error {
printBanner()

err := logger.SetupLogger(logger.LoggerConfig{
Console: false,
Level: slog.LevelInfo,
})
if err != nil {
panic(err)
if err := versions.SuggestUpdate(VERSION); err != nil {
return fmt.Errorf("update check: %w", err)
}

if err = versions.SuggestUpdate(VERSION); err != nil {
logger.Log.Warn("Update check failed", "error", err)
fmt.Printf("%s\n\n", style.Error("Update: "+err.Error()))
return
}
fmt.Printf("%s %s\n\n", style.Gray("Target:"), style.Bold(target))

fmt.Printf("%s %s\n\n", style.Gray("Target:"), style.Bold(*targetSite))
logger.Log.Info("Entering terminal raw mode")
state, err := terminal.NewShellState()
if err != nil {
panic(err)
return err
}
defer state.Restore()

logger.Log.Info("Loading modules")
moduleManager := module.NewManager()

if err = moduleManager.LoadExternals(context.Background()); err != nil {
panic(err)
if err := moduleManager.LoadExternals(context.Background()); err != nil {
return err
}

logger.Log.Info("Building module dependency graph")
graph, err := moduleManager.Build()
if err != nil {
logger.Log.Warn("Module dependency graph is incomplete", "error", err)
fmt.Printf("%s\n", style.Error("Modules: "+err.Error()))
}
if order, err := graph.Order(); err == nil {
logger.Log.Info("Module run order resolved", "order", strings.Join(order, " -> "))
// An incomplete graph only disables the modules that depend on what is
// missing, so report it and keep going.
if _, err := moduleManager.Build(); err != nil {
fmt.Printf("%s\r\n", style.Alertf("modules: %v", err))
}

runner, err := module.CreateRunner()
if err != nil {
panic(err)
return err
}

go func() {
if err := runner.Start(context.Background()); err != nil {
panic(err)
fmt.Fprintf(os.Stderr, "%s\r\n", style.Errorf("runner: %v", err))
}
}()

logger.Log.Info("Starting command manager")
commandManager, err := cmd.NewManager(*targetSite, moduleManager)
commandManager, err := cmd.NewManager(target, moduleManager)
if err != nil {
panic(err)
return err
}

sigChan := make(chan os.Signal, 1)
Expand Down Expand Up @@ -155,8 +144,15 @@ func main() {
runner.CleanupState()
}

logger.Log.Info("Exiting terminal raw mode, restoring old state")
defer state.Restore()
return nil
}

// versionString falls back to "dev" for builds made without the release ldflags.
func versionString() string {
if VERSION == "" {
return "dev"
}
return VERSION
}

func printBanner() {
Expand All @@ -165,12 +161,7 @@ func printBanner() {
buildTime = "unknown"
}
internal.BuildTime = buildTime

version := VERSION
if version == "" {
version = "dev"
}
internal.Version = version
internal.Version = versionString()

utils.PrintBanner(internal.Version, internal.BuildTime)
}
8 changes: 0 additions & 8 deletions internal/cmd/clear_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,11 @@ package cmd

import (
"io"
"log/slog"
"os"
"strings"
"testing"

"goscouter/internal/logger"
)

func TestMain(m *testing.M) {
logger.Log = slog.New(slog.NewTextHandler(io.Discard, nil))
os.Exit(m.Run())
}

func captureStdout(t *testing.T, fn func()) string {
t.Helper()

Expand Down
6 changes: 1 addition & 5 deletions internal/cmd/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package cmd

import (
"fmt"
"goscouter/internal/module"
"maps"
"regexp"
"slices"
"strings"

"goscouter/internal/logger"
"goscouter/internal/module"
)

type Command interface {
Expand All @@ -32,15 +31,12 @@ func NewManager(target string, manager *module.Manager) (*CommandManager, error)
Target: target,
}

logger.Log.Info("Loading built-in commands")
cm.addCommand(&InfoCommand{})
cm.addCommand(&ExitCommand{})
cm.addCommand(&ClearCommand{})
cm.addCommand(&HelpCommand{Manager: cm})
cm.addCommand(&TargetCommand{Manager: cm})

logger.Log.Info("Loaded built-in commands.")

if manager == nil {
return cm, nil
}
Expand Down
13 changes: 3 additions & 10 deletions internal/cmd/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package cmd

import (
"fmt"
"regexp"
"runtime"
"strings"

Expand Down Expand Up @@ -47,12 +46,6 @@ var logo = []string{
style.Yellow(" .-==- ") + style.Cyan(".--=======--- ") + style.Yellow(".==-"),
}

var ansiRE = regexp.MustCompile("\x1b\\[[0-9;]*m")

func visibleWidth(s string) int {
return len([]rune(ansiRE.ReplaceAllString(s, "")))
}

func field(key, value string) string {
return style.Bold(style.White(key)) + style.Gray(" : ") + value
}
Expand All @@ -65,7 +58,7 @@ func colorSwatch() string {

func infoLines() []string {
title := style.Bold(style.Cyan("GoScouter"))
rule := style.Gray(strings.Repeat("─", visibleWidth(title)+9))
rule := style.Gray(strings.Repeat("─", style.Width(title)+9))

return []string{
title,
Expand Down Expand Up @@ -94,7 +87,7 @@ func (cmd *InfoCommand) Exec(args []string) error {

logoWidth := 0
for _, line := range logo {
if w := visibleWidth(line); w > logoWidth {
if w := style.Width(line); w > logoWidth {
logoWidth = w
}
}
Expand All @@ -113,7 +106,7 @@ func (cmd *InfoCommand) Exec(args []string) error {
logoLine = style.BoldAll(logo[i])
}

padding := logoWidth + gap - visibleWidth(logoLine)
padding := logoWidth + gap - style.Width(logoLine)
if padding < 0 {
padding = 0
}
Expand Down
10 changes: 0 additions & 10 deletions internal/cmd/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,3 @@ func TestInfoCommandExec(t *testing.T) {
}
}
}

func TestVisibleWidthStripsANSI(t *testing.T) {
styled := "\x1b[31mabc\x1b[0m"
if got := visibleWidth(styled); got != 3 {
t.Fatalf("expected visible width 3, got %d", got)
}
if got := visibleWidth("héllo"); got != 5 {
t.Fatalf("expected visible width 5 for multibyte string, got %d", got)
}
}
3 changes: 1 addition & 2 deletions internal/cmd/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package cmd

import (
"fmt"
"goscouter/internal/logger"

"goscouter/internal/style"
)

Expand Down Expand Up @@ -35,7 +35,6 @@ func (cmd *TargetCommand) Exec(args []string) error {

cmd.Manager.SetTarget(target)

logger.Log.Info(fmt.Sprintf("Target set to %q", target))
fmt.Printf("%s\r\n", style.Successf("Target set to %s", style.Bold(target)))
return nil
}
76 changes: 0 additions & 76 deletions internal/logger/log.go

This file was deleted.

Loading
Loading