@@ -10,47 +10,139 @@ import (
1010
1111// UpdateMetadataField updates one field under metadata: by in-place line replacement to preserve templating and comments.
1212func UpdateMetadataField (appDir string , field string , value string ) error {
13- appCfgPath := filepath .Join (appDir , constants .AppCfgFileName )
14- data , err := os .ReadFile (appCfgPath )
15- if err != nil {
16- return err
17- }
18- content := string (data )
19- lines := strings .Split (content , "\n " )
20- inMetadata := false
21- for i := 0 ; i < len (lines ); i ++ {
22- line := lines [i ]
23- if ! inMetadata {
24- if strings .TrimSpace (line ) == "metadata:" {
25- inMetadata = true
26- }
27- continue
28- }
29- if len (line ) > 0 && (line [0 ] != ' ' && line [0 ] != '\t' ) {
30- break
31- }
32- trimmed := strings .TrimSpace (line )
33- if strings .HasPrefix (trimmed , field + ":" ) {
34- colonIdx := strings .Index (line , ":" )
35- if colonIdx == - 1 {
36- continue
37- }
38- prefix := line [:colonIdx + 1 ]
39- after := line [colonIdx + 1 :]
40- commentIdx := strings .Index (after , "#" )
41- var comment string
42- if commentIdx >= 0 {
43- comment = after [commentIdx :]
44- }
45- lines [i ] = strings .TrimRight (prefix , " " ) + " " + value
46- if commentIdx >= 0 {
47- lines [i ] += " " + strings .TrimRight (comment , "\r \n " )
48- }
49- break
50- }
51- }
52- newContent := strings .Join (lines , "\n " )
53- return os .WriteFile (appCfgPath , []byte (newContent ), 0644 )
13+ appCfgPath := filepath .Join (appDir , constants .AppCfgFileName )
14+ data , err := os .ReadFile (appCfgPath )
15+ if err != nil {
16+ return err
17+ }
18+ content := string (data )
19+ lines := strings .Split (content , "\n " )
20+ inMetadata := false
21+ for i := 0 ; i < len (lines ); i ++ {
22+ line := lines [i ]
23+ if ! inMetadata {
24+ if strings .TrimSpace (line ) == "metadata:" {
25+ inMetadata = true
26+ }
27+ continue
28+ }
29+ if len (line ) > 0 && (line [0 ] != ' ' && line [0 ] != '\t' ) {
30+ break
31+ }
32+ trimmed := strings .TrimSpace (line )
33+ if strings .HasPrefix (trimmed , field + ":" ) {
34+ colonIdx := strings .Index (line , ":" )
35+ if colonIdx == - 1 {
36+ continue
37+ }
38+ prefix := line [:colonIdx + 1 ]
39+ after := line [colonIdx + 1 :]
40+ commentIdx := strings .Index (after , "#" )
41+ var comment string
42+ if commentIdx >= 0 {
43+ comment = after [commentIdx :]
44+ }
45+ lines [i ] = strings .TrimRight (prefix , " " ) + " " + value
46+ if commentIdx >= 0 {
47+ lines [i ] += " " + strings .TrimRight (comment , "\r \n " )
48+ }
49+ break
50+ }
51+ }
52+ newContent := strings .Join (lines , "\n " )
53+ return os .WriteFile (appCfgPath , []byte (newContent ), 0644 )
5454}
5555
56+ // UpdateEntrancesTitleAddDev appends "-dev" to every title under entrances list
57+ // It performs in-place line updates to preserve existing comments and templating.
58+ func UpdateEntrancesTitleAddDev (appDir string ) error {
59+ appCfgPath := filepath .Join (appDir , constants .AppCfgFileName )
60+ data , err := os .ReadFile (appCfgPath )
61+ if err != nil {
62+ return err
63+ }
5664
65+ lines := strings .Split (string (data ), "\n " )
66+ inEntrances := false
67+ entrancesIndent := ""
68+
69+ // get leading whitespace (spaces/tabs) of a line
70+ leadingWS := func (s string ) string {
71+ for i := 0 ; i < len (s ); i ++ {
72+ if s [i ] != ' ' && s [i ] != '\t' {
73+ return s [:i ]
74+ }
75+ }
76+ return s
77+ }
78+
79+ for i := 0 ; i < len (lines ); i ++ {
80+ line := lines [i ]
81+ trimmed := strings .TrimSpace (line )
82+
83+ if ! inEntrances {
84+ if trimmed == "entrances:" {
85+ inEntrances = true
86+ entrancesIndent = leadingWS (line )
87+ }
88+ continue
89+ }
90+
91+ // leave entrances block when indentation returns, but ignore helm template lines like {{- end }}
92+ if len (line ) > 0 {
93+ ws := leadingWS (line )
94+ if len (ws ) <= len (entrancesIndent ) && strings .TrimSpace (line ) != "" && ! strings .HasPrefix (trimmed , "#" ) && ! strings .HasPrefix (trimmed , "{{" ) && ! strings .HasPrefix (trimmed , "-" ) {
95+ inEntrances = false
96+ i -- // re-process this line outside entrances
97+ continue
98+ }
99+ }
100+
101+ if strings .HasPrefix (trimmed , "title:" ) {
102+ colonIdx := strings .Index (line , ":" )
103+ if colonIdx == - 1 {
104+ continue
105+ }
106+ prefix := line [:colonIdx + 1 ]
107+ after := line [colonIdx + 1 :]
108+ commentIdx := strings .Index (after , "#" )
109+ var valuePart string
110+ var comment string
111+ if commentIdx >= 0 {
112+ valuePart = after [:commentIdx ]
113+ comment = after [commentIdx :]
114+ } else {
115+ valuePart = after
116+ }
117+
118+ v := strings .TrimSpace (valuePart )
119+ newV := v
120+ if len (v ) >= 2 && ((v [0 ] == '"' && v [len (v )- 1 ] == '"' ) || (v [0 ] == '\'' && v [len (v )- 1 ] == '\'' )) {
121+ quote := v [0 ]
122+ content := v [1 : len (v )- 1 ]
123+ if strings .HasSuffix (content , "-dev" ) {
124+ newV = v
125+ } else {
126+ newV = string (quote ) + content + "-dev" + string (quote )
127+ }
128+ } else if v != "" {
129+ if strings .HasSuffix (v , "-dev" ) {
130+ newV = v
131+ } else {
132+ newV = v + "-dev"
133+ }
134+ } else {
135+ newV = "-dev"
136+ }
137+
138+ newLine := strings .TrimRight (prefix , " " ) + " " + newV
139+ if commentIdx >= 0 {
140+ newLine += " " + strings .TrimRight (comment , "\r \n " )
141+ }
142+ lines [i ] = newLine
143+ }
144+ }
145+
146+ newContent := strings .Join (lines , "\n " )
147+ return os .WriteFile (appCfgPath , []byte (newContent ), 0644 )
148+ }
0 commit comments