@@ -2,7 +2,10 @@ package cmd
22
33import (
44 "fmt"
5+ "os"
6+ "path/filepath"
57
8+ "github.com/Norgate-AV/spc/internal/cache"
69 "github.com/Norgate-AV/spc/internal/compiler"
710 "github.com/Norgate-AV/spc/internal/config"
811 "github.com/Norgate-AV/spc/internal/utils"
@@ -29,19 +32,96 @@ func runBuild(cmd *cobra.Command, args []string) error {
2932 return err
3033 }
3134
32- // Build compiler command arguments
35+ // Check if cache is disabled
36+ noCache , _ := cmd .Flags ().GetBool ("no-cache" )
37+
38+ // Initialize cache (unless disabled)
39+ var buildCache * cache.Cache
40+ if ! noCache {
41+ buildCache , err = cache .New ("" )
42+ if err != nil {
43+ fmt .Fprintf (os .Stderr , "Warning: Failed to initialize cache: %v\n " , err )
44+ // Continue without cache
45+ noCache = true
46+ } else {
47+ defer buildCache .Close ()
48+ }
49+ }
50+
51+ // Process each source file
52+ for _ , file := range args {
53+ absFile , err := filepath .Abs (file )
54+ if err != nil {
55+ return fmt .Errorf ("failed to resolve path for %s: %w" , file , err )
56+ }
57+
58+ // Check cache (if enabled)
59+ if ! noCache && buildCache != nil {
60+ entry , err := buildCache .Get (absFile , cfg )
61+ if err != nil {
62+ fmt .Fprintf (os .Stderr , "Warning: Cache lookup failed: %v\n " , err )
63+ } else if entry != nil && entry .Success {
64+ // Cache hit!
65+ outputDir := getOutputDir (absFile )
66+ if err := buildCache .Restore (entry , outputDir ); err != nil {
67+ fmt .Fprintf (os .Stderr , "Warning: Failed to restore from cache: %v\n " , err )
68+ } else {
69+ if cfg .Verbose {
70+ fmt .Printf ("✓ Using cached build for %s\n " , filepath .Base (file ))
71+ }
72+ continue // Skip compilation
73+ }
74+ }
75+ }
76+
77+ // Cache miss or disabled - compile
78+ if cfg .Verbose {
79+ fmt .Printf ("Compiling %s...\n " , filepath .Base (file ))
80+ }
81+
82+ success := true
83+ if err := compileSingle (cfg , absFile ); err != nil {
84+ success = false
85+ // Store failed build in cache too (so we don't retry immediately)
86+ if ! noCache && buildCache != nil {
87+ outputDir := getOutputDir (absFile )
88+ _ = buildCache .Store (absFile , cfg , outputDir , false )
89+ }
90+ return err
91+ }
92+
93+ // Store successful build in cache
94+ if ! noCache && buildCache != nil {
95+ outputDir := getOutputDir (absFile )
96+ if err := buildCache .Store (absFile , cfg , outputDir , success ); err != nil {
97+ fmt .Fprintf (os .Stderr , "Warning: Failed to cache build: %v\n " , err )
98+ }
99+ }
100+ }
101+
102+ return nil
103+ }
104+
105+ // compileSingle compiles a single source file
106+ func compileSingle (cfg * config.Config , sourceFile string ) error {
33107 builder := compiler .NewCommandBuilder ()
34- cmdArgs , err := builder .BuildCommandArgs (cfg , args )
108+ cmdArgs , err := builder .BuildCommandArgs (cfg , [] string { sourceFile } )
35109 if err != nil {
36110 return err
37111 }
38112
39113 // Print build info if verbose mode is enabled
40114 if cfg .Verbose {
41115 series := utils .ParseTarget (cfg .Target )
42- builder .PrintBuildInfo (cfg , series , args , cmdArgs )
116+ builder .PrintBuildInfo (cfg , series , [] string { sourceFile } , cmdArgs )
43117 }
44118
45119 // Execute the compiler command
46120 return builder .ExecuteCommand (cfg .CompilerPath , cmdArgs )
47121}
122+
123+ // getOutputDir returns the SPlsWork directory for a source file
124+ func getOutputDir (sourceFile string ) string {
125+ dir := filepath .Dir (sourceFile )
126+ return filepath .Join (dir , "SPlsWork" )
127+ }
0 commit comments