Skip to content

Commit d92cff4

Browse files
Rebasing and fixing.
1 parent ad9dad0 commit d92cff4

File tree

3 files changed

+500
-4
lines changed

3 files changed

+500
-4
lines changed

go.sum

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs
1212
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
1313
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
1414
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
15-
github.com/urfave/cli/v2 v2.11.1 h1:UKK6SP7fV3eKOefbS87iT9YHefv7iB/53ih6e+GNAsE=
16-
github.com/urfave/cli/v2 v2.11.1/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
17-
github.com/urfave/cli/v2 v2.23.5 h1:xbrU7tAYviSpqeR3X4nEFWUdB/uDZ6DE+HxmRU7Xtyw=
18-
github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
1915
github.com/urfave/cli/v2 v2.23.6 h1:iWmtKD+prGo1nKUtLO0Wg4z9esfBM4rAV4QRLQiEmJ4=
2016
github.com/urfave/cli/v2 v2.23.6/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
2117
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=

harness/variables.go

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
package harness
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
"strings"
9+
)
10+
11+
const (
12+
// ErrorMessageKey is the key used to retrieve or store the error message content.
13+
ErrorMessageKey = "ERROR_MESSAGE"
14+
15+
// ErrorCodeKey is the key used to identify the specific error code associated with an error.
16+
ErrorCodeKey = "ERROR_CODE"
17+
18+
// ErrorCategoryKey is the key used to classify the category of the error, which can help in grouping similar types of errors.
19+
ErrorCategoryKey = "ERROR_CATEGORY"
20+
21+
// MetadataFile is the key for the file that stores metadata associated with an error, such as details about the error's source or context.
22+
MetadataFile = "ERROR_METADATA_FILE"
23+
24+
// DroneOutputFile is the key for the file where outputs can be exported and utilized in the subsequent steps in Harness CI pipeline.
25+
DroneOutputFile = "DRONE_OUTPUT"
26+
27+
// HarnessOutputSecretFile is the key for the file where secrets can be exported and utilized in the subsequent steps in Harness CI pipeline.
28+
HarnessOutputSecretFile = "HARNESS_OUTPUT_SECRET_FILE"
29+
)
30+
31+
// SetSecret sets a new secret by adding it to the HARNESS_OUTPUT_SECRET_FILE file
32+
func SetSecret(name, value string) error {
33+
return UpdateOrRemoveKeyValue(HarnessOutputSecretFile, name, value, false)
34+
}
35+
36+
// UpdateSecret overwrites the value of an existing secret.
37+
func UpdateSecret(name, value string) error {
38+
return UpdateOrRemoveKeyValue(HarnessOutputSecretFile, name, value, false)
39+
}
40+
41+
// DeleteSecret removes a secret from the file entirely.
42+
func DeleteSecret(name string) error {
43+
return UpdateOrRemoveKeyValue(HarnessOutputSecretFile, name, "", true)
44+
}
45+
46+
// SetOutput sets a new secret by adding it to the DRONE_OUTPUT file
47+
func SetOutput(name, value string) error {
48+
return UpdateOrRemoveKeyValue(DroneOutputFile, name, value, false)
49+
}
50+
51+
// UpdateOutput overwrites the value of an existing output.
52+
func UpdateOutput(name, value string) error {
53+
return UpdateOrRemoveKeyValue(DroneOutputFile, name, value, false)
54+
}
55+
56+
// DeleteOutput removes an output from the file entirely.
57+
func DeleteOutput(name string) error {
58+
return UpdateOrRemoveKeyValue(DroneOutputFile, name, "", true)
59+
}
60+
61+
// SetErrorMetadata sets the error message, error code, and error category, writing them to the CI_ERROR_METADATA file
62+
func SetErrorMetadata(message, code, category string) error {
63+
// Write the error message
64+
if err := UpdateOrRemoveKeyValue(MetadataFile, ErrorMessageKey, message, false); err != nil {
65+
return err
66+
}
67+
68+
// Write the error code
69+
if err := UpdateOrRemoveKeyValue(MetadataFile, ErrorCodeKey, code, false); err != nil {
70+
return err
71+
}
72+
73+
// Write the error category
74+
if err := UpdateOrRemoveKeyValue(MetadataFile, ErrorCategoryKey, category, false); err != nil {
75+
return err
76+
}
77+
78+
return nil
79+
}
80+
81+
// UpdateOrRemoveKeyValue updates or deletes a key-value pair in the specified file.
82+
func UpdateOrRemoveKeyValue(envVar, key, newValue string, delete bool) error {
83+
// Get the file path from the environment variable
84+
filePath := os.Getenv(envVar)
85+
if filePath == "" {
86+
return fmt.Errorf("environment variable %s is not set", envVar)
87+
}
88+
89+
// Ensure the file exists before reading
90+
if _, err := os.Stat(filePath); os.IsNotExist(err) {
91+
// Create the file if it does not exist
92+
_, err := os.OpenFile(filePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
93+
if err != nil {
94+
return fmt.Errorf("failed to create file: %w", err)
95+
}
96+
}
97+
98+
// Determine the file extension to handle formats
99+
ext := strings.ToLower(filepath.Ext(filePath))
100+
101+
// Read the file contents into memory
102+
lines, err := ReadLines(filePath)
103+
if err != nil {
104+
return fmt.Errorf("failed to read file: %w", err)
105+
}
106+
107+
// Process lines
108+
var updatedLines []string
109+
found := false
110+
for _, line := range lines {
111+
k, v := ParseKeyValue(line, ext)
112+
if k == key {
113+
found = true
114+
if delete {
115+
continue // Skip the line to delete it
116+
}
117+
updatedLines = append(updatedLines, FormatKeyValue(k, newValue, ext))
118+
} else {
119+
updatedLines = append(updatedLines, FormatKeyValue(k, v, ext))
120+
}
121+
}
122+
123+
// Append new key-value if not found and not deleting
124+
if !found && !delete {
125+
updatedLines = append(updatedLines, FormatKeyValue(key, newValue, ext))
126+
}
127+
128+
// Write updated lines back to the file
129+
return WriteLines(filePath, updatedLines)
130+
}
131+
132+
// ReadLines reads lines from a file and returns them as a slice of strings.
133+
func ReadLines(filename string) ([]string, error) {
134+
file, err := os.Open(filename)
135+
if err != nil {
136+
return nil, err
137+
}
138+
defer file.Close()
139+
140+
var lines []string
141+
scanner := bufio.NewScanner(file)
142+
for scanner.Scan() {
143+
lines = append(lines, scanner.Text())
144+
}
145+
return lines, scanner.Err()
146+
}
147+
148+
// WriteLines writes a slice of strings to a file, each string being written to a new line.
149+
func WriteLines(filename string, lines []string) error {
150+
file, err := os.Create(filename)
151+
if err != nil {
152+
return fmt.Errorf("failed to create file: %w", err)
153+
}
154+
defer file.Close()
155+
156+
for _, line := range lines {
157+
_, err := file.WriteString(line + "\n")
158+
if err != nil {
159+
return fmt.Errorf("failed to write to file: %w", err)
160+
}
161+
}
162+
return nil
163+
}
164+
165+
// ParseKeyValue parses a key-value pair from a string and returns the key and value.
166+
func ParseKeyValue(line, ext string) (string, string) {
167+
if ext == ".env" {
168+
parts := strings.SplitN(line, "=", 2)
169+
if len(parts) == 2 {
170+
return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])
171+
}
172+
return strings.TrimSpace(parts[0]), ""
173+
} else if ext == ".out" {
174+
parts := strings.Fields(line)
175+
if len(parts) == 2 {
176+
return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])
177+
}
178+
return strings.TrimSpace(parts[0]), ""
179+
}
180+
return "", ""
181+
}
182+
183+
// FormatKeyValue formats a key-value pair into a string.
184+
func FormatKeyValue(key, value, ext string) string {
185+
if ext == ".env" {
186+
return fmt.Sprintf("%s=%s", key, value)
187+
} else if ext == ".out" {
188+
return fmt.Sprintf("%s %s", key, value)
189+
}
190+
return ""
191+
}

0 commit comments

Comments
 (0)