11package apply
22
33import (
4+ "errors"
5+ "fmt"
6+ "os"
7+ "strings"
8+
9+ "github.com/apiqube/cli/internal/core/io"
410 "github.com/apiqube/cli/internal/core/manifests"
5- "github.com/apiqube/cli/internal/core/manifests/loader"
611 "github.com/apiqube/cli/internal/core/store"
12+ "github.com/apiqube/cli/internal/validate"
713 "github.com/apiqube/cli/ui/cli"
814 "github.com/spf13/cobra"
15+ "gopkg.in/yaml.v3"
916)
1017
1118func init () {
@@ -14,43 +21,103 @@ func init() {
1421
1522var Cmd = & cobra.Command {
1623 Use : "apply" ,
17- Short : "Apply resources from manifest file" ,
24+ Short : "Apply resources from manifest files" ,
25+ Long : "Apply configuration from YAML manifests with validation and version control" ,
1826 SilenceErrors : true ,
1927 SilenceUsage : true ,
2028 Run : func (cmd * cobra.Command , args []string ) {
2129 file , err := cmd .Flags ().GetString ("file" )
2230 if err != nil {
23- cli .Errorf ("Failed to parse -- file: %s " , err . Error () )
31+ cli .Errorf ("Failed to parse input file flag : %v " , err )
2432 return
2533 }
2634
2735 cli .Infof ("Loading manifests from: %s" , file )
28-
29- loadedMans , cachedMans , err := loader .LoadManifests (file )
36+ loadedMans , cachedMans , err := io .LoadManifests (file )
3037 if err != nil {
31- cli .Errorf ("Failed to load manifests: %s" , err .Error ())
38+ cli .Errorf ("Critical load error:\n %s" , formatLoadError (err , file ))
39+ return
40+ }
41+
42+ cli .Info ("Validating manifests..." )
43+ validator := validate .NewManifestValidator (validate .NewValidator (), cli .Instance ())
44+
45+ validator .Validate (loadedMans ... )
46+
47+ validMans := validator .Valid ()
48+ if len (validMans ) == 0 {
49+ cli .Warning ("No valid manifests to apply" )
3250 return
3351 }
3452
35- printManifestsLoadResult (loadedMans , cachedMans )
53+ printManifestsLoadResult (validMans , cachedMans )
3654
37- if err := store .Save (loadedMans ... ); err != nil {
38- cli .Infof ("Failed to save manifests: %s" , err .Error ())
55+ cli .Infof ("Saving %d manifests to storage..." , len (validMans ))
56+ if err := store .Save (validMans ... ); err != nil {
57+ cli .Errorf ("Storage error: -\n %s" , err .Error ())
3958 return
4059 }
4160
42- cli .Success ("Manifests applied successfully" )
61+ printPostApplySummary (validMans )
62+ cli .Successf ("Successfully applied %d manifests" , len (validMans ))
4363 },
4464}
4565
66+ func formatLoadError (err error , file string ) string {
67+ if os .IsNotExist (err ) {
68+ return fmt .Sprintf ("File not found: \n %s- Please check the path and try again" , file )
69+ }
70+ var yamlErr * yaml.TypeError
71+ if errors .As (err , & yamlErr ) {
72+ return fmt .Sprintf ("YAML syntax error:\n %s" , indentYAMLError (yamlErr ))
73+ }
74+
75+ return err .Error ()
76+ }
77+
4678func printManifestsLoadResult (newMans , cachedMans []manifests.Manifest ) {
47- for _ , m := range newMans {
48- cli .Infof ("New manifest added: %s (h: %s...)" , m .GetID (), cli .ShortHash (m .GetMeta ().GetHash ()))
79+ if len (newMans ) > 0 {
80+ var builder strings.Builder
81+
82+ for _ , m := range newMans {
83+ builder .WriteString (fmt .Sprintf ("\n - %s %s" ,
84+ m .GetID (),
85+ fmt .Sprintf ("(h: %s)" , cli .ShortHash (m .GetMeta ().GetHash ())),
86+ ))
87+ }
88+
89+ cli .Infof ("New manifests detected: %s" , builder .String ())
4990 }
5091
51- for _ , m := range cachedMans {
52- cli .Infof ("Manifest %s unchanged (h: %s...) - using cached version" , m .GetID (), cli .ShortHash (m .GetMeta ().GetHash ()))
92+ if len (cachedMans ) > 0 {
93+ var builder strings.Builder
94+
95+ for _ , m := range cachedMans {
96+ builder .WriteString (fmt .Sprintf ("\n - %s %s" ,
97+ m .GetID (),
98+ fmt .Sprintf ("(h: %s)" , cli .ShortHash (m .GetMeta ().GetHash ())),
99+ ))
100+
101+ cli .Infof ("Using cached manifest: %s" , builder .String ())
102+ }
53103 }
104+ }
105+
106+ func printPostApplySummary (mans []manifests.Manifest ) {
107+ stats := make (map [string ]int )
108+ for _ , m := range mans {
109+ stats [m .GetKind ()]++
110+ }
111+
112+ var builder strings.Builder
113+
114+ for kind , count := range stats {
115+ builder .WriteString (fmt .Sprintf ("\n - %s: %d" , kind , count ))
116+ }
117+
118+ cli .Infof ("Applied manifests by kind: %s" , builder .String ())
119+ }
54120
55- cli .Infof ("Loaded new manifests\n New: %d\n Cached: %d" , len (newMans ), len (cachedMans ))
121+ func indentYAMLError (err * yaml.TypeError ) string {
122+ return " " + strings .Join (err .Errors , "\n " )
56123}
0 commit comments