Skip to content

Commit

Permalink
Merge pull request #135 from UiPath/feature/studio
Browse files Browse the repository at this point in the history
Add support to analyze and package studio projects
  • Loading branch information
thschmitt authored Jan 9, 2025
2 parents 1315e06 + 3687fc9 commit ee6bc13
Show file tree
Hide file tree
Showing 49 changed files with 2,341 additions and 182 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI
on: [push]

env:
UIPATHCLI_BASE_VERSION: "v1.1"
UIPATHCLI_BASE_VERSION: "v2.0"
GO_VERSION: "1.22.2"

jobs:
Expand Down
36 changes: 33 additions & 3 deletions auth/browser_launcher.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
package auth

// BrowserLauncher interface for opening browser windows.
type BrowserLauncher interface {
Open(url string) error
import (
"fmt"
"time"

"github.com/UiPath/uipathcli/utils"
)

// BrowserLauncher tries to open the default browser on the local system.
type BrowserLauncher struct {
Exec utils.ExecProcess
}

func (l BrowserLauncher) Open(url string) error {
cmd := l.openBrowser(url)
err := cmd.Start()
if err != nil {
return err
}
done := make(chan error)
go func() {
done <- cmd.Wait()
}()

select {
case err := <-done:
return err
case <-time.After(5 * time.Second):
return fmt.Errorf("Timed out waiting for browser to start")
}
}

func NewBrowserLauncher() *BrowserLauncher {
return &BrowserLauncher{utils.NewExecProcess()}
}
11 changes: 11 additions & 0 deletions auth/browser_launcher_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build darwin

package auth

import (
"github.com/UiPath/uipathcli/utils"
)

func (l BrowserLauncher) openBrowser(url string) utils.ExecCmd {
return l.Exec.Command("open", url)
}
11 changes: 11 additions & 0 deletions auth/browser_launcher_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build linux

package auth

import (
"github.com/UiPath/uipathcli/utils"
)

func (l BrowserLauncher) openBrowser(url string) utils.ExecCmd {
return l.Exec.Command("xdg-open", url)
}
11 changes: 11 additions & 0 deletions auth/browser_launcher_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build windows

package auth

import (
"github.com/UiPath/uipathcli/utils"
)

func (l BrowserLauncher) openBrowser(url string) utils.ExecCmd {
return l.Exec.Command("rundll32", "url.dll,FileProtocolHandler", url)
}
47 changes: 0 additions & 47 deletions auth/exec_browser_launcher.go

This file was deleted.

30 changes: 15 additions & 15 deletions auth/oauth_authenticator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"runtime"
"strings"
"testing"

"github.com/UiPath/uipathcli/cache"
"github.com/UiPath/uipathcli/utils"
)

func TestOAuthAuthenticatorNotEnabled(t *testing.T) {
Expand All @@ -25,7 +27,7 @@ func TestOAuthAuthenticatorNotEnabled(t *testing.T) {
request := NewAuthenticatorRequest("http:/localhost", map[string]string{})
context := NewAuthenticatorContext("login", config, createIdentityUrl(""), false, false, *request)

authenticator := NewOAuthAuthenticator(cache.NewFileCache(), nil)
authenticator := NewOAuthAuthenticator(cache.NewFileCache(), *NewBrowserLauncher())
result := authenticator.Auth(*context)
if result.Error != "" {
t.Errorf("Expected no error when oauth flow is skipped, but got: %v", result.Error)
Expand All @@ -46,7 +48,7 @@ func TestOAuthAuthenticatorPreservesExistingHeaders(t *testing.T) {
request := NewAuthenticatorRequest("http:/localhost", headers)
context := NewAuthenticatorContext("login", config, createIdentityUrl(""), false, false, *request)

authenticator := NewOAuthAuthenticator(cache.NewFileCache(), nil)
authenticator := NewOAuthAuthenticator(cache.NewFileCache(), *NewBrowserLauncher())
result := authenticator.Auth(*context)
if result.Error != "" {
t.Errorf("Expected no error when oauth flow is skipped, but got: %v", result.Error)
Expand All @@ -65,7 +67,7 @@ func TestOAuthAuthenticatorInvalidConfig(t *testing.T) {
request := NewAuthenticatorRequest("http:/localhost", map[string]string{})
context := NewAuthenticatorContext("login", config, createIdentityUrl(""), false, false, *request)

authenticator := NewOAuthAuthenticator(cache.NewFileCache(), nil)
authenticator := NewOAuthAuthenticator(cache.NewFileCache(), *NewBrowserLauncher())
result := authenticator.Auth(*context)
if result.Error != "Invalid oauth authenticator configuration: Invalid value for clientId: '1'" {
t.Errorf("Expected error with invalid config, but got: %v", result.Error)
Expand Down Expand Up @@ -122,7 +124,7 @@ func TestOAuthFlowIsCached(t *testing.T) {
performLogin(loginUrl, t)
<-resultChannel

authenticator := NewOAuthAuthenticator(cache.NewFileCache(), nil)
authenticator := NewOAuthAuthenticator(cache.NewFileCache(), *NewBrowserLauncher())
result := authenticator.Auth(context)

if result.Error != "" {
Expand Down Expand Up @@ -208,8 +210,15 @@ func TestMissingCodeShowsErrorMessage(t *testing.T) {

func callAuthenticator(context AuthenticatorContext) (url.URL, chan AuthenticatorResult) {
loginChan := make(chan string)
authenticator := NewOAuthAuthenticator(cache.NewFileCache(), NoOpBrowserLauncher{
loginUrlChannel: loginChan,
authenticator := NewOAuthAuthenticator(cache.NewFileCache(), BrowserLauncher{
Exec: utils.NewExecCustomProcess(0, "", "", func(name string, args []string) {
switch runtime.GOOS {
case "windows":
loginChan <- args[1]
default:
loginChan <- args[0]
}
}),
})

resultChannel := make(chan AuthenticatorResult)
Expand Down Expand Up @@ -323,12 +332,3 @@ func (i identityServerFake) writeValidationErrorResponse(response http.ResponseW
response.WriteHeader(400)
_, _ = response.Write([]byte(message))
}

type NoOpBrowserLauncher struct {
loginUrlChannel chan string
}

func (l NoOpBrowserLauncher) Open(url string) error {
l.loginUrlChannel <- url
return nil
}
11 changes: 4 additions & 7 deletions cache/file_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
"strconv"
"strings"
"time"

"github.com/UiPath/uipathcli/utils"
)

const cacheFilePermissions = 0600
const cacheDirectoryPermissions = 0700
const cacheDirectory = "uipath"
const separator = "|"

// The FileCache stores data on disk in order to preserve them across
Expand Down Expand Up @@ -63,15 +63,12 @@ func (c FileCache) readValue(key string) (int64, string, error) {
}

func (c FileCache) cacheFilePath(key string) (string, error) {
userCacheDirectory, err := os.UserCacheDir()
cacheDirectory, err := utils.Directories{}.Cache()
if err != nil {
return "", err
}
cacheDirectory := filepath.Join(userCacheDirectory, cacheDirectory)
_ = os.MkdirAll(cacheDirectory, cacheDirectoryPermissions)

hash := sha256.Sum256([]byte(key))
fileName := fmt.Sprintf("%x.cache", hash)
fileName := fmt.Sprintf("%x", hash)
return filepath.Join(cacheDirectory, fileName), nil
}

Expand Down
14 changes: 14 additions & 0 deletions definitions/studio.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
openapi: 3.0.1
info:
title: UiPath Studio
description: UiPath Studio
version: v1
servers:
- url: https://cloud.uipath.com/{organization}/studio_/backend
description: The production url
variables:
organization:
description: The organization name (or id)
default: my-org
paths:
{}
2 changes: 1 addition & 1 deletion executor/http_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func (e HttpExecutor) progressReader(text string, completedText string, reader i
if progress.Completed {
displayText = completedText
}
progressBar.Update(displayText, progress.BytesRead, length, progress.BytesPerSecond)
progressBar.UpdateProgress(displayText, progress.BytesRead, length, progress.BytesPerSecond)
})
return progressReader
}
Expand Down
4 changes: 4 additions & 0 deletions log/debug_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ func (l DebugLogger) LogResponse(response ResponseInfo) {
fmt.Fprint(l.writer, "\n\n\n")
}

func (l DebugLogger) Log(message string) {
fmt.Fprint(l.writer, message)
}

func (l DebugLogger) LogError(message string) {
fmt.Fprint(l.writer, message)
}
Expand Down
3 changes: 3 additions & 0 deletions log/default_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ func (l *DefaultLogger) LogRequest(request RequestInfo) {
func (l DefaultLogger) LogResponse(response ResponseInfo) {
}

func (l DefaultLogger) Log(message string) {
}

func (l DefaultLogger) LogError(message string) {
fmt.Fprint(l.writer, message)
}
Expand Down
1 change: 1 addition & 0 deletions log/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package log
// The Logger interface which is used to provide additional information to the
// user about what operations the CLI is performing.
type Logger interface {
Log(message string)
LogError(message string)
LogRequest(request RequestInfo)
LogResponse(response ResponseInfo)
Expand Down
11 changes: 7 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/UiPath/uipathcli/plugin"
plugin_digitizer "github.com/UiPath/uipathcli/plugin/digitizer"
plugin_orchestrator "github.com/UiPath/uipathcli/plugin/orchestrator"
plugin_studio "github.com/UiPath/uipathcli/plugin/studio"
"github.com/UiPath/uipathcli/utils"
)

Expand All @@ -27,7 +28,7 @@ var embedded embed.FS
func authenticators() []auth.Authenticator {
return []auth.Authenticator{
auth.NewPatAuthenticator(),
auth.NewOAuthAuthenticator(cache.NewFileCache(), auth.NewExecBrowserLauncher()),
auth.NewOAuthAuthenticator(cache.NewFileCache(), *auth.NewBrowserLauncher()),
auth.NewBearerAuthenticator(cache.NewFileCache()),
}
}
Expand Down Expand Up @@ -63,9 +64,11 @@ func main() {
commandline.NewDefinitionFileStore(os.Getenv("UIPATH_DEFINITIONS_PATH"), embedded),
parser.NewOpenApiParser(),
[]plugin.CommandPlugin{
plugin_digitizer.DigitizeCommand{},
plugin_orchestrator.UploadCommand{},
plugin_orchestrator.DownloadCommand{},
plugin_digitizer.NewDigitizeCommand(),
plugin_orchestrator.NewUploadCommand(),
plugin_orchestrator.NewDownloadCommand(),
plugin_studio.NewPackagePackCommand(),
plugin_studio.NewPackageAnalyzeCommand(),
},
),
*configProvider,
Expand Down
Loading

0 comments on commit ee6bc13

Please sign in to comment.