• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender-artifact / 1395629354

31 Jul 2024 03:15PM UTC coverage: 77.353% (+0.1%) from 77.239%
1395629354

Pull #624

gitlab-ci

mzedel
chore: debug

Signed-off-by: Manuel Zedel <manuel.zedel@northern.tech>
Pull Request #624: Feat/output yaml

149 of 159 new or added lines in 1 file covered. (93.71%)

5 existing lines in 1 file now uncovered.

5786 of 7480 relevant lines covered (77.35%)

134.28 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.93
/cli/read.go
1
// Copyright 2024 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
package cli
16

17
import (
18
        "bytes"
19
        "encoding/json"
20
        "fmt"
21
        "io"
22
        "os"
23
        "reflect"
24
        "sort"
25
        "strings"
26

27
        "github.com/pkg/errors"
28
        "github.com/urfave/cli"
29

30
        "github.com/mendersoftware/mender-artifact/areader"
31
        "github.com/mendersoftware/mender-artifact/artifact"
32
        "github.com/mendersoftware/mender-artifact/handlers"
33
        "github.com/mendersoftware/mender-artifact/utils"
34
)
35

36
var defaultIndentation = "  "
37

38
func sortedKeys(mapWithKeys interface{}) sort.StringSlice {
94✔
39
        var keys sort.StringSlice
94✔
40
        mapVal := reflect.ValueOf(mapWithKeys)
94✔
41
        if mapVal.Kind() != reflect.Map {
94✔
NEW
42
                return nil
×
NEW
43
        }
×
44
        keys = make([]string, mapVal.Len())
94✔
45
        keysVal := mapVal.MapKeys()
94✔
46
        for i, keyVal := range keysVal {
378✔
47
                keys[i] = keyVal.String()
284✔
48
        }
284✔
49
        keys.Sort()
94✔
50
        return keys
94✔
51
}
52

53
func printList(title string, iterable []string, err string, shouldFlow bool, indentationLevel int) {
134✔
54
        fmt.Printf("%s%s:", strings.Repeat(defaultIndentation, indentationLevel), title)
134✔
55
        if err != "" {
134✔
NEW
56
                fmt.Printf("%s\n", err)
×
57
        } else if len(iterable) == 0 {
186✔
58
                fmt.Printf(" []\n")
52✔
59
        } else if shouldFlow {
212✔
60
                fmt.Printf(" [%s]\n", strings.Join(iterable, ", "))
76✔
61
        } else {
84✔
62
                fmt.Printf("\n")
8✔
63
                for _, value := range iterable {
32✔
64
                        fmt.Printf("%s- %s\n", strings.Repeat(defaultIndentation, indentationLevel+1), value)
24✔
65
                }
24✔
66
        }
67
}
68

69
func printObject(
70
        title string,
71
        someObject map[string]interface{},
72
        err string,
73
        indentationLevel int,
74
) {
136✔
75
        fmt.Printf("%s%s:", strings.Repeat(defaultIndentation, indentationLevel), title)
136✔
76
        if err != "" {
136✔
NEW
77
                fmt.Printf("%s\n", err)
×
78
        } else if len(someObject) == 0 {
180✔
79
                fmt.Printf(" {}\n")
44✔
80
        } else {
138✔
81
                fmt.Printf("\n")
94✔
82
                keys := sortedKeys(someObject)
94✔
83
                for _, key := range keys {
378✔
84
                        fmt.Printf("%s%s: %s\n",
284✔
85
                                strings.Repeat(defaultIndentation, indentationLevel+1),
284✔
86
                                key,
284✔
87
                                (someObject)[key])
284✔
88
                }
284✔
89
        }
90
}
91

92
func printHeader(ar *areader.Reader, sigInfo string, indentationLevel int) {
46✔
93
        info := ar.GetInfo()
46✔
94
        fmt.Printf("%sMender artifact:\n", strings.Repeat(defaultIndentation, indentationLevel))
46✔
95
        fmt.Printf(
46✔
96
                "%sName: %s\n",
46✔
97
                strings.Repeat(defaultIndentation, indentationLevel+1),
46✔
98
                ar.GetArtifactName(),
46✔
99
        )
46✔
100
        fmt.Printf(
46✔
101
                "%sFormat: %s\n",
46✔
102
                strings.Repeat(defaultIndentation, indentationLevel+1),
46✔
103
                info.Format,
46✔
104
        )
46✔
105
        fmt.Printf(
46✔
106
                "%sVersion: %d\n",
46✔
107
                strings.Repeat(defaultIndentation, indentationLevel+1),
46✔
108
                info.Version,
46✔
109
        )
46✔
110
        fmt.Printf("%sSignature: %s\n", strings.Repeat(defaultIndentation, indentationLevel+1), sigInfo)
46✔
111
        printList("Compatible devices", ar.GetCompatibleDevices(), "", true, indentationLevel+1)
46✔
112
}
46✔
113

114
func printStateScripts(scripts []string, indentationLevel int) {
46✔
115
        printList("State scripts", scripts, "", false, indentationLevel)
46✔
116
}
46✔
117

118
func printFiles(files []*handlers.DataFile, indentationLevel int) {
46✔
119
        if len(files) == 0 {
54✔
120
                fmt.Printf("%sFiles: []\n", strings.Repeat(defaultIndentation, indentationLevel))
8✔
121
        } else {
46✔
122
                fmt.Printf("%sFiles:\n", strings.Repeat(defaultIndentation, indentationLevel))
38✔
123
                for fileIndex, f := range files {
84✔
124
                        data := map[string]interface{}{
46✔
125
                                "name":     f.Name,
46✔
126
                                "size":     fmt.Sprintf("%d", f.Size),
46✔
127
                                "modified": f.Date,
46✔
128
                                "checksum": f.Checksum,
46✔
129
                        }
46✔
130
                        printObject(fmt.Sprintf("File-%d", fileIndex), data, "", indentationLevel+1)
46✔
131
                }
46✔
132
        }
133
}
134

135
func printProvides(p handlers.Installer, indentationLevel int) {
46✔
136
        provides, err := p.GetUpdateProvides()
46✔
137
        error := ""
46✔
138
        if err != nil {
46✔
NEW
139
                error = fmt.Sprintf(" Invalid provides section: %s", err.Error())
×
NEW
140
        }
×
141
        providesWorkaround := make(map[string]interface{}, len(provides))
46✔
142
        for k, v := range provides {
122✔
143
                providesWorkaround[k] = v
76✔
144
        }
76✔
145
        printObject("Provides", providesWorkaround, error, indentationLevel)
46✔
146
}
147

148
func printDepends(p handlers.Installer, indentationLevel int) {
46✔
149
        depends, err := p.GetUpdateDepends()
46✔
150
        error := ""
46✔
151
        if err != nil {
46✔
NEW
152
                error = fmt.Sprintf(" Invalid depends section: %s", err.Error())
×
NEW
153
        }
×
154
        printObject("Depends", depends, error, indentationLevel)
46✔
155
}
156

157
func printClearsProvides(p handlers.Installer, indentationLevel int) {
46✔
158
        caps := p.GetUpdateClearsProvides()
46✔
159
        printList("Clears Provides", caps, "", true, indentationLevel)
46✔
160
}
46✔
161

162
func printUpdateMetadata(p handlers.Installer, indentationLevel int) {
46✔
163
        metaData, err := p.GetUpdateMetaData()
46✔
164
        fmt.Printf("%sMetadata:", strings.Repeat(defaultIndentation, indentationLevel))
46✔
165
        if err != nil {
46✔
NEW
166
                fmt.Printf(" Invalid metadata section: %s\n", err.Error())
×
167
        } else if len(metaData) == 0 {
82✔
168
                fmt.Printf(" {}\n")
36✔
169
        } else {
46✔
170
                var metaDataSlice []byte
10✔
171
                if err == nil {
20✔
172
                        metaDataSlice, err = json.Marshal(metaData)
10✔
173
                }
10✔
174
                var metaDataBuf bytes.Buffer
10✔
175
                if err == nil {
20✔
176
                        err = json.Indent(
10✔
177
                                &metaDataBuf,
10✔
178
                                metaDataSlice,
10✔
179
                                strings.Repeat(defaultIndentation, indentationLevel+1),
10✔
180
                                defaultIndentation)
10✔
181
                }
10✔
182
                if err != nil {
10✔
NEW
183
                        fmt.Printf(" Invalid metadata section: %s\n", err.Error())
×
184
                } else {
10✔
185
                        fmt.Printf("\n")
10✔
186
                        fmt.Printf(
10✔
187
                                "%s%s\n",
10✔
188
                                strings.Repeat(defaultIndentation, indentationLevel+1),
10✔
189
                                metaDataBuf.String())
10✔
190
                }
10✔
191
        }
192
}
193

194
func printPayload(p handlers.Installer, indentationLevel int) {
46✔
195
        updateType := p.GetUpdateType()
46✔
196
        if updateType == nil {
48✔
197
                emptyType := "Empty type"
2✔
198
                updateType = &emptyType
2✔
199
        }
2✔
200
        fmt.Printf("%sType: %v\n", strings.Repeat(defaultIndentation, indentationLevel), *updateType)
46✔
201

46✔
202
        printProvides(p, indentationLevel)
46✔
203
        printDepends(p, indentationLevel)
46✔
204
        printClearsProvides(p, indentationLevel)
46✔
205
        printUpdateMetadata(p, indentationLevel)
46✔
206
        printFiles(p.GetUpdateAllFiles(), indentationLevel)
46✔
207
}
208

209
func printUpdates(updatePayloads map[int]handlers.Installer, indentationLevel int) {
46✔
210
        fmt.Printf("%sUpdates:\n", strings.Repeat(defaultIndentation, indentationLevel))
46✔
211
        for k, payload := range updatePayloads {
92✔
212
                fmt.Printf("%sUpdate-%d:\n", strings.Repeat(defaultIndentation, indentationLevel+1), k)
46✔
213
                printPayload(payload, indentationLevel+2)
46✔
214
        }
46✔
215
}
216

217
func readArtifact(c *cli.Context) error {
52✔
218
        if c.NArg() == 0 {
54✔
219
                return cli.NewExitError("Nothing specified, nothing read. \nMaybe you wanted"+
2✔
220
                        " to say 'artifacts read <pathspec>'?", errArtifactInvalidParameters)
2✔
221
        }
2✔
222

223
        f, err := os.Open(c.Args().First())
50✔
224
        if err != nil {
50✔
225
                return cli.NewExitError("Can not open artifact: "+c.Args().First(),
×
226
                        errArtifactOpen)
×
227
        }
×
228
        defer f.Close()
50✔
229

50✔
230
        var verifyCallback areader.SignatureVerifyFn
50✔
231

50✔
232
        key, err := getKey(c)
50✔
233
        if err != nil {
54✔
234
                return cli.NewExitError(err.Error(), errArtifactInvalidParameters)
4✔
235
        }
4✔
236
        if key != nil {
50✔
237
                verifyCallback = key.Verify
4✔
238
        }
4✔
239

240
        // if key is not provided just continue reading artifact returning
241
        // info that signature can not be verified
242
        sigInfo := "no signature"
46✔
243
        ver := func(message, sig []byte) error {
54✔
244
                sigInfo = "signed but no key for verification provided; " +
8✔
245
                        "please use `-k` option for providing verification key"
8✔
246
                if key != nil {
12✔
247
                        err = verifyCallback(message, sig)
4✔
248
                        if err != nil {
4✔
UNCOV
249
                                sigInfo = "signed; verification using provided key failed"
×
250
                        } else {
4✔
251
                                sigInfo = "signed and verified correctly"
4✔
252
                        }
4✔
253
                }
254
                return nil
8✔
255
        }
256

257
        var scripts []string
46✔
258
        readScripts := func(r io.Reader, info os.FileInfo) error {
70✔
259
                scripts = append(scripts, info.Name())
24✔
260
                return nil
24✔
261
        }
24✔
262

263
        ar := areader.NewReader(f)
46✔
264
        if !c.Bool("no-progress") {
92✔
265
                fmt.Fprintln(os.Stderr, "Reading Artifact...")
46✔
266
                ar.ProgressReader = utils.NewProgressReader()
46✔
267
        }
46✔
268
        ar.ScriptsReadCallback = readScripts
46✔
269
        ar.VerifySignatureCallback = ver
46✔
270
        err = ar.ReadArtifact()
46✔
271
        if err != nil {
46✔
UNCOV
272
                if errors.Cause(err) == artifact.ErrCompatibleDevices {
×
UNCOV
273
                        return cli.NewExitError("Invalid Artifact. No 'device-type' found.", 1)
×
UNCOV
274
                }
×
UNCOV
275
                return cli.NewExitError(err.Error(), 1)
×
276
        }
277

278
        printHeader(ar, sigInfo, 0)
46✔
279

46✔
280
        provides := ar.GetArtifactProvides()
46✔
281
        if provides != nil {
88✔
282
                fmt.Printf("%sProvides group: %s\n", defaultIndentation, provides.ArtifactGroup)
42✔
283
        }
42✔
284

285
        depends := ar.GetArtifactDepends()
46✔
286
        if depends != nil {
88✔
287
                fmt.Printf(
42✔
288
                        "%sDepends on one of artifact(s): [%s]\n",
42✔
289
                        defaultIndentation, strings.Join(depends.ArtifactName, ", "),
42✔
290
                )
42✔
291
                fmt.Printf(
42✔
292
                        "%sDepends on one of group(s): [%s]\n",
42✔
293
                        defaultIndentation, strings.Join(depends.ArtifactGroup, ", "),
42✔
294
                )
42✔
295
        }
42✔
296

297
        printStateScripts(scripts, 1)
46✔
298
        fmt.Println()
46✔
299
        updatePayloads := ar.GetHandlers()
46✔
300
        printUpdates(updatePayloads, 0)
46✔
301

46✔
302
        return nil
46✔
303
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc