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
23 changes: 12 additions & 11 deletions cmd/sin-code/internal/ast_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ func init() { registerProvider(goASTProvider{}, false) }

func (goASTProvider) languages() []string { return []string{"go"} }

func sigOf(lines []string, start int) string {
if start-1 >= 0 && start-1 < len(lines) {
return strings.TrimSpace(lines[start-1])
}
return ""
}

func (goASTProvider) parse(path string, src []byte) (*FileOutline, error) {
out := &FileOutline{Engine: "go/ast"}
if len(src) == 0 {
Expand All @@ -30,12 +37,6 @@ func (goASTProvider) parse(path string, src []byte) (*FileOutline, error) {
return nil, err
}
lines := strings.Split(string(src), "\n")
sigOf := func(start int) string {
if start-1 >= 0 && start-1 < len(lines) {
return strings.TrimSpace(lines[start-1])
}
return ""
}
lineRange := func(n ast.Node) (int, int) {
return fset.Position(n.Pos()).Line, fset.Position(n.End()).Line
}
Expand All @@ -48,7 +49,7 @@ func (goASTProvider) parse(path string, src []byte) (*FileOutline, error) {
switch d := decl.(type) {
case *ast.FuncDecl:
start, end := lineRange(d)
sym := SymbolInfo{Kind: "func", Name: d.Name.Name, StartLine: start, EndLine: end, Signature: sigOf(start)}
sym := SymbolInfo{Kind: "func", Name: d.Name.Name, StartLine: start, EndLine: end, Signature: sigOf(lines, start)}
if d.Recv != nil && len(d.Recv.List) > 0 {
sym.Kind = "method"
sym.Name = recvTypeName(d.Recv.List[0].Type) + "." + d.Name.Name
Expand All @@ -59,7 +60,7 @@ func (goASTProvider) parse(path string, src []byte) (*FileOutline, error) {
switch s := spec.(type) {
case *ast.TypeSpec:
start, end := lineRange(s)
sym := SymbolInfo{Name: s.Name.Name, StartLine: start, EndLine: end, Signature: sigOf(start)}
sym := SymbolInfo{Name: s.Name.Name, StartLine: start, EndLine: end, Signature: sigOf(lines, start)}
switch t := s.Type.(type) {
case *ast.StructType:
sym.Kind = "struct"
Expand All @@ -68,7 +69,7 @@ func (goASTProvider) parse(path string, src []byte) (*FileOutline, error) {
fs, fe := lineRange(f)
for _, n := range f.Names {
sym.Children = append(sym.Children, SymbolInfo{
Kind: "field", Name: n.Name, StartLine: fs, EndLine: fe, Signature: sigOf(fs),
Kind: "field", Name: n.Name, StartLine: fs, EndLine: fe, Signature: sigOf(lines, fs),
})
}
}
Expand All @@ -80,7 +81,7 @@ func (goASTProvider) parse(path string, src []byte) (*FileOutline, error) {
ms, me := lineRange(m)
for _, n := range m.Names {
sym.Children = append(sym.Children, SymbolInfo{
Kind: "method", Name: n.Name, StartLine: ms, EndLine: me, Signature: sigOf(ms),
Kind: "method", Name: n.Name, StartLine: ms, EndLine: me, Signature: sigOf(lines, ms),
})
}
}
Expand All @@ -100,7 +101,7 @@ func (goASTProvider) parse(path string, src []byte) (*FileOutline, error) {
continue
}
out.Symbols = append(out.Symbols, SymbolInfo{
Kind: kind, Name: n.Name, StartLine: start, EndLine: end, Signature: sigOf(start),
Kind: kind, Name: n.Name, StartLine: start, EndLine: end, Signature: sigOf(lines, start),
})
}
}
Expand Down
9 changes: 7 additions & 2 deletions cmd/sin-code/internal/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ var (
discoverLimit int
)

var (
discoverAbsPath = filepath.Abs
discoverWalk = filepath.Walk
)

var DiscoverCmd = &cobra.Command{
Use: "discover [path]",
Short: "Discover files with relevance scoring and pattern matching",
Expand All @@ -41,7 +46,7 @@ Example:
if len(args) > 0 {
path = args[0]
}
absPath, err := filepath.Abs(path)
absPath, err := discoverAbsPath(path)
if err != nil {
return fmt.Errorf("invalid path: %w", err)
}
Expand Down Expand Up @@ -86,7 +91,7 @@ func discoverFiles(root, pattern string, limit int) ([]fileResult, error) {

var results []fileResult
walked := 0
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
err = discoverWalk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil // skip errors
}
Expand Down
13 changes: 10 additions & 3 deletions cmd/sin-code/internal/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
execStream bool
)

var (
execIsWindows = func() bool { return runtime.GOOS == "windows" }

Check failure on line 28 in cmd/sin-code/internal/execute.go

View workflow job for this annotation

GitHub Actions / golangci-lint

File is not properly formatted (gofmt)
execNewContext = func(ctx context.Context, timeout time.Duration) (context.Context, context.CancelFunc) { return context.WithTimeout(ctx, timeout) }
execTimeoutDuration = func(timeout int) time.Duration { return time.Duration(timeout) * time.Second }
execRunCommand = func(c *exec.Cmd) error { return c.Run() }
)

var ExecuteCmd = &cobra.Command{
Use: "execute",
Short: "Execute shell commands safely with secret redaction and timeout",
Expand Down Expand Up @@ -59,7 +66,7 @@

// Use shell to execute the command
var shell, shellArg string
if runtime.GOOS == "windows" {
if execIsWindows() {
shell, shellArg = "cmd", "/c"
} else {
shell, shellArg = "/bin/sh", "-c"
Expand All @@ -68,7 +75,7 @@
ctx := context.Background()
if timeout > 0 {
var cancel context.CancelFunc
ctx, cancel = context.WithTimeout(ctx, time.Duration(timeout)*time.Second)
ctx, cancel = execNewContext(ctx, execTimeoutDuration(timeout))
defer cancel()
}

Expand All @@ -84,7 +91,7 @@
c.Stderr = &stderr
}

err := c.Run()
err := execRunCommand(c)
duration := time.Since(start)

// Collect output
Expand Down
12 changes: 8 additions & 4 deletions cmd/sin-code/internal/harvest.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ var (
harvestTimeout int
)

var harvestHTTPClient = func(timeout int) *http.Client {
return &http.Client{
Timeout: time.Duration(timeout) * time.Second,
Transport: circuitbreaker.RoundTripper(http.DefaultTransport, harvestBreaker),
}
}

var HarvestCmd = &cobra.Command{
Use: "harvest",
Short: "Fetch URLs with caching, structure extraction, and change detection",
Expand Down Expand Up @@ -99,10 +106,7 @@ func harvestURLFetch(url, method string, timeout int, format string) error {
}
}

client := &http.Client{
Timeout: time.Duration(timeout) * time.Second,
Transport: circuitbreaker.RoundTripper(http.DefaultTransport, harvestBreaker),
}
client := harvestHTTPClient(timeout)
req, err := http.NewRequest(method, url, nil)
if err != nil {
return fmt.Errorf("invalid request: %w", err)
Expand Down
4 changes: 2 additions & 2 deletions cmd/sin-code/internal/ibd.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,15 @@ func evaluateIntent(intent string, added, removed, modified []symbolInfo, diff [
if len(added) > 0 {
score += 30
} else {
score -= 20
score -= 40
}
}

if intentKeywords["remove"] || intentKeywords["delete"] {
if len(removed) > 0 {
score += 30
} else {
score -= 20
score -= 40
}
}

Expand Down
13 changes: 10 additions & 3 deletions cmd/sin-code/internal/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ var (
mapFormat string
)

var (
mapAbsPath = filepath.Abs
mapWalk = filepath.Walk
)

var MapCmd = &cobra.Command{
Use: "map [path]",
Short: "Map code architecture with dependency graphs and hot-path analysis",
Expand All @@ -34,7 +39,7 @@ Example:
if len(args) > 0 {
path = args[0]
}
absPath, err := filepath.Abs(path)
absPath, err := mapAbsPath(path)
if err != nil {
return fmt.Errorf("invalid path: %w", err)
}
Expand Down Expand Up @@ -107,7 +112,7 @@ func mapArchitecture(root, action string) (*mapResult, error) {
configFiles := 0
docs := 0

err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
err := mapWalk(root, func(path string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() {
if info != nil && info.IsDir() {
base := filepath.Base(path)
Expand Down Expand Up @@ -258,8 +263,10 @@ type fileInfo struct {
dir string
}

var isGoEntryPointParseOutline = parseOutline

func isGoEntryPoint(path string, data []byte) bool {
outline := parseOutline(path, data)
outline := isGoEntryPointParseOutline(path, data)
if outline == nil || outline.Engine == "none" {
return false
}
Expand Down
8 changes: 6 additions & 2 deletions cmd/sin-code/internal/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
"github.com/spf13/cobra"
)

var buildOutlineMarshal = func(v any) ([]byte, error) { return json.MarshalIndent(v, "", " ") }

var (
readMode string
readOffset int
Expand All @@ -24,6 +26,8 @@ var (
readFormat string
)

var readAbsPath = filepath.Abs

const readDefaultLimit = 2000
const readDefaultMaxBytes int64 = 1 << 20

Expand All @@ -44,7 +48,7 @@ Examples:
sin-code read pkg/x.go --format json`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
absPath, err := filepath.Abs(args[0])
absPath, err := readAbsPath(args[0])
if err != nil {
return fmt.Errorf("invalid path: %w", err)
}
Expand Down Expand Up @@ -165,7 +169,7 @@ func buildOutlineResult(res *readResult, content, lang string) *readResult {
"exports": exports,
"dependencies": deps,
}
b, err := json.MarshalIndent(outlineMap, "", " ")
b, err := buildOutlineMarshal(outlineMap)
if err != nil {
b = []byte(fmt.Sprintf(`{"error":"%v"}`, err))
}
Expand Down
Loading
Loading