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

mendersoftware / mender-artifact / 1398396163

02 Aug 2024 10:57AM UTC coverage: 77.353% (+0.1%) from 77.239%
1398396163

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%)

133.87 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 {
92✔
39
        var keys sort.StringSlice
92✔
40
        mapVal := reflect.ValueOf(mapWithKeys)
92✔
41
        if mapVal.Kind() != reflect.Map {
92✔
NEW
42
                return nil
×
NEW
43
        }
×
44
        keys = make([]string, mapVal.Len())
92✔
45
        keysVal := mapVal.MapKeys()
92✔
46
        for i, keyVal := range keysVal {
374✔
47
                keys[i] = keyVal.String()
282✔
48
        }
282✔
49
        keys.Sort()
92✔
50
        return keys
92✔
51
}
52

53
func printList(title string, iterable []string, err string, shouldFlow bool, indentationLevel int) {
132✔
54
        fmt.Printf("%s%s:", strings.Repeat(defaultIndentation, indentationLevel), title)
132✔
55
        if err != "" {
132✔
NEW
56
                fmt.Printf("%s\n", err)
×
57
        } else if len(iterable) == 0 {
182✔
58
                fmt.Printf(" []\n")
50✔
59
        } else if shouldFlow {
206✔
60
                fmt.Printf(" [%s]\n", strings.Join(iterable, ", "))
74✔
61
        } else {
82✔
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
) {
134✔
75
        fmt.Printf("%s%s:", strings.Repeat(defaultIndentation, indentationLevel), title)
134✔
76
        if err != "" {
134✔
NEW
77
                fmt.Printf("%s\n", err)
×
78
        } else if len(someObject) == 0 {
176✔
79
                fmt.Printf(" {}\n")
42✔
80
        } else {
134✔
81
                fmt.Printf("\n")
92✔
82
                keys := sortedKeys(someObject)
92✔
83
                for _, key := range keys {
374✔
84
                        fmt.Printf("%s%s: %s\n",
282✔
85
                                strings.Repeat(defaultIndentation, indentationLevel+1),
282✔
86
                                key,
282✔
87
                                (someObject)[key])
282✔
88
                }
282✔
89
        }
90
}
91

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

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

118
func printFiles(files []*handlers.DataFile, indentationLevel int) {
44✔
119
        if len(files) == 0 {
50✔
120
                fmt.Printf("%sFiles: []\n", strings.Repeat(defaultIndentation, indentationLevel))
6✔
121
        } else {
44✔
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) {
44✔
136
        provides, err := p.GetUpdateProvides()
44✔
137
        error := ""
44✔
138
        if err != nil {
44✔
NEW
139
                error = fmt.Sprintf(" Invalid provides section: %s", err.Error())
×
NEW
140
        }
×
141
        providesWorkaround := make(map[string]interface{}, len(provides))
44✔
142
        for k, v := range provides {
118✔
143
                providesWorkaround[k] = v
74✔
144
        }
74✔
145
        printObject("Provides", providesWorkaround, error, indentationLevel)
44✔
146
}
147

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

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

162
func printUpdateMetadata(p handlers.Installer, indentationLevel int) {
44✔
163
        metaData, err := p.GetUpdateMetaData()
44✔
164
        fmt.Printf("%sMetadata:", strings.Repeat(defaultIndentation, indentationLevel))
44✔
165
        if err != nil {
44✔
NEW
166
                fmt.Printf(" Invalid metadata section: %s\n", err.Error())
×
167
        } else if len(metaData) == 0 {
78✔
168
                fmt.Printf(" {}\n")
34✔
169
        } else {
44✔
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) {
44✔
195
        updateType := p.GetUpdateType()
44✔
196
        if updateType == nil {
46✔
197
                emptyType := "Empty type"
2✔
198
                updateType = &emptyType
2✔
199
        }
2✔
200
        fmt.Printf("%sType: %v\n", strings.Repeat(defaultIndentation, indentationLevel), *updateType)
44✔
201

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

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

217
func readArtifact(c *cli.Context) error {
50✔
218
        if c.NArg() == 0 {
52✔
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())
48✔
224
        if err != nil {
48✔
225
                return cli.NewExitError("Can not open artifact: "+c.Args().First(),
×
226
                        errArtifactOpen)
×
227
        }
×
228
        defer f.Close()
48✔
229

48✔
230
        var verifyCallback areader.SignatureVerifyFn
48✔
231

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

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

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

263
        ar := areader.NewReader(f)
44✔
264
        if !c.Bool("no-progress") {
88✔
265
                fmt.Fprintln(os.Stderr, "Reading Artifact...")
44✔
266
                ar.ProgressReader = utils.NewProgressReader()
44✔
267
        }
44✔
268
        ar.ScriptsReadCallback = readScripts
44✔
269
        ar.VerifySignatureCallback = ver
44✔
270
        err = ar.ReadArtifact()
44✔
271
        if err != nil {
44✔
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)
44✔
279

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

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

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

44✔
302
        return nil
44✔
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