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

UiPath / uipathcli / 12904430648

22 Jan 2025 08:41AM UTC coverage: 90.366% (-0.01%) from 90.377%
12904430648

Pull #139

github

thschmitt
Update readme and add examples for most common use-cases

Extended the README.md with Quick-Start Guide which includes snippets
for common uipathcli scenarios.

All existing examples that could not be executed have been replaced with
real-world commands.

Added invoice.jpg which is used by the example commands to showcase the
Document Understanding features.
Pull Request #139: Update readme and add examples for most common use-cases

4934 of 5460 relevant lines covered (90.37%)

1.01 hits per line

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

89.22
/plugin/studio/package_pack_command.go
1
package studio
2

3
import (
4
        "bufio"
5
        "bytes"
6
        "encoding/json"
7
        "errors"
8
        "fmt"
9
        "io"
10
        "os"
11
        "path/filepath"
12
        "strings"
13
        "sync"
14
        "time"
15

16
        "github.com/UiPath/uipathcli/log"
17
        "github.com/UiPath/uipathcli/output"
18
        "github.com/UiPath/uipathcli/plugin"
19
        "github.com/UiPath/uipathcli/utils"
20
)
21

22
const defaultProjectJson = "project.json"
23

24
// The PackagePackCommand packs a project into a single NuGet package
25
type PackagePackCommand struct {
26
        Exec utils.ExecProcess
27
}
28

29
func (c PackagePackCommand) Command() plugin.Command {
1✔
30
        return *plugin.NewCommand("studio").
1✔
31
                WithCategory("package", "Package", "UiPath Studio package-related actions").
1✔
32
                WithOperation("pack", "Package Project", "Packs a project into a single package").
1✔
33
                WithParameter("source", plugin.ParameterTypeString, "Path to a project.json file or a folder containing project.json file", true).
1✔
34
                WithParameter("destination", plugin.ParameterTypeString, "The output folder", true).
1✔
35
                WithParameter("package-version", plugin.ParameterTypeString, "The package version", false).
1✔
36
                WithParameter("auto-version", plugin.ParameterTypeBoolean, "Auto-generate package version", false).
1✔
37
                WithParameter("output-type", plugin.ParameterTypeString, "Force the output to a specific type", false).
1✔
38
                WithParameter("split-output", plugin.ParameterTypeBoolean, "Enables the output split to runtime and design libraries", false).
1✔
39
                WithParameter("release-notes", plugin.ParameterTypeString, "Add release notes", false)
1✔
40
}
1✔
41

42
func (c PackagePackCommand) Execute(context plugin.ExecutionContext, writer output.OutputWriter, logger log.Logger) error {
1✔
43
        source, err := c.getSource(context)
1✔
44
        if err != nil {
2✔
45
                return err
1✔
46
        }
1✔
47
        destination, err := c.getDestination(context)
1✔
48
        if err != nil {
1✔
49
                return err
×
50
        }
×
51
        packageVersion := c.getParameter("package-version", context.Parameters)
1✔
52
        autoVersion := c.getBoolParameter("auto-version", context.Parameters)
1✔
53
        outputType := c.getParameter("output-type", context.Parameters)
1✔
54
        splitOutput := c.getBoolParameter("split-output", context.Parameters)
1✔
55
        releaseNotes := c.getParameter("release-notes", context.Parameters)
1✔
56
        params := newPackagePackParams(source, destination, packageVersion, autoVersion, outputType, splitOutput, releaseNotes)
1✔
57

1✔
58
        result, err := c.execute(*params, context.Debug, logger)
1✔
59
        if err != nil {
1✔
60
                return err
×
61
        }
×
62

63
        json, err := json.Marshal(result)
1✔
64
        if err != nil {
1✔
65
                return fmt.Errorf("pack command failed: %v", err)
×
66
        }
×
67
        return writer.WriteResponse(*output.NewResponseInfo(200, "200 OK", "HTTP/1.1", map[string][]string{}, bytes.NewReader(json)))
1✔
68
}
69

70
func (c PackagePackCommand) execute(params packagePackParams, debug bool, logger log.Logger) (*packagePackResult, error) {
1✔
71
        if !debug {
2✔
72
                bar := c.newPackagingProgressBar(logger)
1✔
73
                defer close(bar)
1✔
74
        }
1✔
75

76
        args := []string{"package", "pack", params.Source, "--output", params.Destination}
1✔
77
        if params.PackageVersion != "" {
1✔
78
                args = append(args, "--version", params.PackageVersion)
×
79
        }
×
80
        if params.AutoVersion {
2✔
81
                args = append(args, "--autoVersion")
1✔
82
        }
1✔
83
        if params.OutputType != "" {
2✔
84
                args = append(args, "--outputType", params.OutputType)
1✔
85
        }
1✔
86
        if params.SplitOutput {
2✔
87
                args = append(args, "--splitOutput")
1✔
88
        }
1✔
89
        if params.ReleaseNotes != "" {
2✔
90
                args = append(args, "--releaseNotes", params.ReleaseNotes)
1✔
91
        }
1✔
92

93
        projectReader := newStudioProjectReader(params.Source)
1✔
94

1✔
95
        uipcli := newUipcli(c.Exec, logger)
1✔
96
        cmd, err := uipcli.Execute(projectReader.GetTargetFramework(), args...)
1✔
97
        if err != nil {
1✔
98
                return nil, err
×
99
        }
×
100
        stdout, err := cmd.StdoutPipe()
1✔
101
        if err != nil {
1✔
102
                return nil, fmt.Errorf("Could not run pack command: %v", err)
×
103
        }
×
104
        defer stdout.Close()
1✔
105
        stderr, err := cmd.StderrPipe()
1✔
106
        if err != nil {
1✔
107
                return nil, fmt.Errorf("Could not run pack command: %v", err)
×
108
        }
×
109
        defer stderr.Close()
1✔
110
        err = cmd.Start()
1✔
111
        if err != nil {
1✔
112
                return nil, fmt.Errorf("Could not run pack command: %v", err)
×
113
        }
×
114

115
        stderrOutputBuilder := new(strings.Builder)
1✔
116
        stderrReader := io.TeeReader(stderr, stderrOutputBuilder)
1✔
117

1✔
118
        var wg sync.WaitGroup
1✔
119
        wg.Add(3)
1✔
120
        go c.readOutput(stdout, logger, &wg)
1✔
121
        go c.readOutput(stderrReader, logger, &wg)
1✔
122
        go c.wait(cmd, &wg)
1✔
123
        wg.Wait()
1✔
124

1✔
125
        project, err := projectReader.ReadMetadata()
1✔
126
        if err != nil {
1✔
127
                return nil, err
×
128
        }
×
129

130
        exitCode := cmd.ExitCode()
1✔
131
        var result *packagePackResult
1✔
132
        if exitCode == 0 {
2✔
133
                nupkgFile := c.findNupkg(params.Destination)
1✔
134
                version := c.extractVersion(nupkgFile)
1✔
135
                result = newSucceededPackagePackResult(
1✔
136
                        filepath.Join(params.Destination, nupkgFile),
1✔
137
                        project.Name,
1✔
138
                        project.Description,
1✔
139
                        project.ProjectId,
1✔
140
                        version)
1✔
141
        } else {
2✔
142
                result = newFailedPackagePackResult(
1✔
143
                        stderrOutputBuilder.String(),
1✔
144
                        &project.Name,
1✔
145
                        &project.Description,
1✔
146
                        &project.ProjectId)
1✔
147
        }
1✔
148
        return result, nil
1✔
149
}
150

151
func (c PackagePackCommand) findNupkg(destination string) string {
1✔
152
        newestFile := ""
1✔
153
        newestTime := time.Time{}
1✔
154

1✔
155
        files, _ := os.ReadDir(destination)
1✔
156
        for _, file := range files {
2✔
157
                extension := filepath.Ext(file.Name())
1✔
158
                if strings.EqualFold(extension, ".nupkg") {
2✔
159
                        fileInfo, _ := file.Info()
1✔
160
                        time := fileInfo.ModTime()
1✔
161
                        if time.After(newestTime) {
2✔
162
                                newestTime = time
1✔
163
                                newestFile = file.Name()
1✔
164
                        }
1✔
165
                }
166
        }
167
        return newestFile
1✔
168
}
169

170
func (c PackagePackCommand) extractVersion(nupkgFile string) string {
1✔
171
        parts := strings.Split(nupkgFile, ".")
1✔
172
        len := len(parts)
1✔
173
        if len < 4 {
2✔
174
                return ""
1✔
175
        }
1✔
176
        return fmt.Sprintf("%s.%s.%s", parts[len-4], parts[len-3], parts[len-2])
1✔
177
}
178

179
func (c PackagePackCommand) wait(cmd utils.ExecCmd, wg *sync.WaitGroup) {
1✔
180
        defer wg.Done()
1✔
181
        _ = cmd.Wait()
1✔
182
}
1✔
183

184
func (c PackagePackCommand) newPackagingProgressBar(logger log.Logger) chan struct{} {
1✔
185
        progressBar := utils.NewProgressBar(logger)
1✔
186
        ticker := time.NewTicker(10 * time.Millisecond)
1✔
187
        cancel := make(chan struct{})
1✔
188
        var percent float64 = 0
1✔
189
        go func() {
2✔
190
                for {
2✔
191
                        select {
1✔
192
                        case <-ticker.C:
1✔
193
                                progressBar.UpdatePercentage("packaging...  ", percent)
1✔
194
                                percent = percent + 1
1✔
195
                                if percent > 100 {
2✔
196
                                        percent = 0
1✔
197
                                }
1✔
198
                        case <-cancel:
1✔
199
                                ticker.Stop()
1✔
200
                                progressBar.Remove()
1✔
201
                                return
1✔
202
                        }
203
                }
204
        }()
205
        return cancel
1✔
206
}
207

208
func (c PackagePackCommand) getSource(context plugin.ExecutionContext) (string, error) {
1✔
209
        source := c.getParameter("source", context.Parameters)
1✔
210
        if source == "" {
1✔
211
                return "", errors.New("source is not set")
×
212
        }
×
213
        source, _ = filepath.Abs(source)
1✔
214
        fileInfo, err := os.Stat(source)
1✔
215
        if err != nil {
2✔
216
                return "", fmt.Errorf("%s not found", defaultProjectJson)
1✔
217
        }
1✔
218
        if fileInfo.IsDir() {
2✔
219
                source = filepath.Join(source, defaultProjectJson)
1✔
220
        }
1✔
221
        return source, nil
1✔
222
}
223

224
func (c PackagePackCommand) getDestination(context plugin.ExecutionContext) (string, error) {
1✔
225
        destination := c.getParameter("destination", context.Parameters)
1✔
226
        if destination == "" {
1✔
227
                return "", errors.New("destination is not set")
×
228
        }
×
229
        destination, _ = filepath.Abs(destination)
1✔
230
        return destination, nil
1✔
231
}
232

233
func (c PackagePackCommand) readOutput(output io.Reader, logger log.Logger, wg *sync.WaitGroup) {
1✔
234
        defer wg.Done()
1✔
235
        scanner := bufio.NewScanner(output)
1✔
236
        scanner.Split(bufio.ScanRunes)
1✔
237
        for scanner.Scan() {
2✔
238
                logger.Log(scanner.Text())
1✔
239
        }
1✔
240
}
241

242
func (c PackagePackCommand) getParameter(name string, parameters []plugin.ExecutionParameter) string {
1✔
243
        result := ""
1✔
244
        for _, p := range parameters {
2✔
245
                if p.Name == name {
2✔
246
                        if data, ok := p.Value.(string); ok {
2✔
247
                                result = data
1✔
248
                                break
1✔
249
                        }
250
                }
251
        }
252
        return result
1✔
253
}
254

255
func (c PackagePackCommand) getBoolParameter(name string, parameters []plugin.ExecutionParameter) bool {
1✔
256
        result := false
1✔
257
        for _, p := range parameters {
2✔
258
                if p.Name == name {
2✔
259
                        if data, ok := p.Value.(bool); ok {
2✔
260
                                result = data
1✔
261
                                break
1✔
262
                        }
263
                }
264
        }
265
        return result
1✔
266
}
267

268
func NewPackagePackCommand() *PackagePackCommand {
1✔
269
        return &PackagePackCommand{utils.NewExecProcess()}
1✔
270
}
1✔
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