-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support to package studio projects
- Loading branch information
Showing
27 changed files
with
977 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
openapi: 3.0.1 | ||
info: | ||
title: UiPath Studio | ||
description: UiPath Studio | ||
version: v1 | ||
servers: | ||
- url: https://cloud.uipath.com/identity_ | ||
paths: | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package plugin | ||
|
||
import ( | ||
"crypto/rand" | ||
"crypto/sha256" | ||
"fmt" | ||
"io" | ||
"math" | ||
"math/big" | ||
"net/http" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/UiPath/uipathcli/log" | ||
"github.com/UiPath/uipathcli/utils" | ||
) | ||
|
||
const pluginDirectoryPermissions = 0700 | ||
|
||
type ExternalPlugin struct { | ||
Logger log.Logger | ||
} | ||
|
||
func (p ExternalPlugin) GetTool(name string, url string, executable string) (string, error) { | ||
pluginDirectory, err := p.cacheFilePath(name, url) | ||
if err != nil { | ||
return "", fmt.Errorf("Could not download %s: %v", name, err) | ||
} | ||
path := filepath.Join(pluginDirectory, executable) | ||
if _, err := os.Stat(path); err == nil { | ||
return path, nil | ||
} | ||
|
||
tmpPluginDirectory := pluginDirectory + "-" + p.randomFolderName() | ||
_ = os.MkdirAll(tmpPluginDirectory, pluginDirectoryPermissions) | ||
|
||
progressBar := utils.NewProgressBar(p.Logger) | ||
defer progressBar.Remove() | ||
progressBar.Tick("downloading...") | ||
zipArchivePath := filepath.Join(tmpPluginDirectory, name) | ||
err = p.download(name, url, zipArchivePath, progressBar) | ||
if err != nil { | ||
return "", err | ||
} | ||
err = newZipArchive().Extract(zipArchivePath, tmpPluginDirectory, pluginDirectoryPermissions) | ||
if err != nil { | ||
return "", fmt.Errorf("Could not extract %s archive: %v", name, err) | ||
} | ||
os.Remove(zipArchivePath) | ||
err = os.Rename(tmpPluginDirectory, pluginDirectory) | ||
if err != nil { | ||
return "", fmt.Errorf("Could not install %s: %v", name, err) | ||
} | ||
return path, nil | ||
} | ||
|
||
func (p ExternalPlugin) download(name string, url string, destination string, progressBar *utils.ProgressBar) error { | ||
out, err := os.Create(destination) | ||
if err != nil { | ||
return fmt.Errorf("Could not download %s: %v", name, err) | ||
} | ||
defer out.Close() | ||
|
||
request, err := http.NewRequest(http.MethodGet, url, nil) | ||
if err != nil { | ||
return fmt.Errorf("Could not download %s: %v", name, err) | ||
} | ||
response, err := http.DefaultClient.Do(request) | ||
if err != nil { | ||
return fmt.Errorf("Could not download %s: %v", name, err) | ||
} | ||
downloadReader := p.progressReader("downloading...", "installing... ", response.Body, response.ContentLength, progressBar) | ||
_, err = io.Copy(out, downloadReader) | ||
if err != nil { | ||
return fmt.Errorf("Could not download %s: %v", name, err) | ||
} | ||
return nil | ||
} | ||
|
||
func (p ExternalPlugin) progressReader(text string, completedText string, reader io.Reader, length int64, progressBar *utils.ProgressBar) io.Reader { | ||
progressReader := utils.NewProgressReader(reader, func(progress utils.Progress) { | ||
displayText := text | ||
if progress.Completed { | ||
displayText = completedText | ||
} | ||
progressBar.Update(displayText, progress.BytesRead, length, progress.BytesPerSecond) | ||
}) | ||
return progressReader | ||
} | ||
|
||
func (p ExternalPlugin) cacheFilePath(name string, url string) (string, error) { | ||
cacheDirectory, err := utils.Directories{}.Cache() | ||
if err != nil { | ||
return "", err | ||
} | ||
hash := sha256.Sum256([]byte(url)) | ||
subdirectory := fmt.Sprintf("%s-%x", name, hash) | ||
pluginDirectory := filepath.Join(cacheDirectory, "plugins", subdirectory) | ||
return pluginDirectory, nil | ||
} | ||
|
||
func (p ExternalPlugin) randomFolderName() string { | ||
value, _ := rand.Int(rand.Reader, big.NewInt(math.MaxInt64)) | ||
return value.String() | ||
} | ||
|
||
func NewExternalPlugin(logger log.Logger) *ExternalPlugin { | ||
return &ExternalPlugin{logger} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.