uipath 2.0.26__py3-none-any.whl → 2.0.27__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of uipath might be problematic. Click here for more details.
- uipath/_cli/_auth/_auth_server.py +0 -1
- uipath/_cli/_auth/_portal_service.py +18 -10
- uipath/_cli/_utils/_console.py +215 -0
- uipath/_cli/_utils/_folders.py +5 -7
- uipath/_cli/_utils/_processes.py +10 -21
- uipath/_cli/cli_auth.py +45 -46
- uipath/_cli/cli_deploy.py +1 -0
- uipath/_cli/cli_init.py +63 -68
- uipath/_cli/cli_invoke.py +42 -49
- uipath/_cli/cli_new.py +23 -28
- uipath/_cli/cli_pack.py +61 -44
- uipath/_cli/cli_publish.py +64 -82
- uipath/_cli/cli_run.py +1 -1
- {uipath-2.0.26.dist-info → uipath-2.0.27.dist-info}/METADATA +1 -1
- {uipath-2.0.26.dist-info → uipath-2.0.27.dist-info}/RECORD +18 -17
- {uipath-2.0.26.dist-info → uipath-2.0.27.dist-info}/WHEEL +0 -0
- {uipath-2.0.26.dist-info → uipath-2.0.27.dist-info}/entry_points.txt +0 -0
- {uipath-2.0.26.dist-info → uipath-2.0.27.dist-info}/licenses/LICENSE +0 -0
uipath/_cli/cli_init.py
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
# type: ignore
|
|
2
2
|
import json
|
|
3
3
|
import os
|
|
4
|
-
import traceback
|
|
5
4
|
import uuid
|
|
6
5
|
from pathlib import Path
|
|
7
6
|
from typing import Optional
|
|
8
7
|
|
|
9
8
|
import click
|
|
10
9
|
|
|
10
|
+
from ._utils._console import ConsoleLogger
|
|
11
11
|
from ._utils._input_args import generate_args
|
|
12
12
|
from ._utils._parse_ast import generate_bindings_json
|
|
13
13
|
from .middlewares import Middlewares
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
console = ConsoleLogger()
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
def generate_env_file(target_directory):
|
|
@@ -19,7 +20,7 @@ def generate_env_file(target_directory):
|
|
|
19
20
|
|
|
20
21
|
if not os.path.exists(env_path):
|
|
21
22
|
relative_path = os.path.relpath(env_path, target_directory)
|
|
22
|
-
|
|
23
|
+
console.info(f"Created {relative_path} file.")
|
|
23
24
|
with open(env_path, "w") as f:
|
|
24
25
|
f.write("UIPATH_ACCESS_TOKEN=YOUR_TOKEN_HERE\n")
|
|
25
26
|
f.write("UIPATH_URL=https://cloud.uipath.com/ACCOUNT_NAME/TENANT_NAME\n")
|
|
@@ -30,20 +31,22 @@ def get_user_script(directory: str, entrypoint: Optional[str] = None) -> Optiona
|
|
|
30
31
|
if entrypoint:
|
|
31
32
|
script_path = os.path.join(directory, entrypoint)
|
|
32
33
|
if not os.path.isfile(script_path):
|
|
33
|
-
|
|
34
|
+
console.error(
|
|
35
|
+
f"The {entrypoint} file does not exist in the current directory."
|
|
36
|
+
)
|
|
34
37
|
return None
|
|
35
38
|
return script_path
|
|
36
39
|
|
|
37
40
|
python_files = [f for f in os.listdir(directory) if f.endswith(".py")]
|
|
38
41
|
|
|
39
42
|
if not python_files:
|
|
40
|
-
|
|
43
|
+
console.error("No python files found in the current directory.")
|
|
41
44
|
return None
|
|
42
45
|
elif len(python_files) == 1:
|
|
43
46
|
return os.path.join(directory, python_files[0])
|
|
44
47
|
else:
|
|
45
|
-
|
|
46
|
-
"Multiple
|
|
48
|
+
console.error(
|
|
49
|
+
"Multiple python files found in the current directory.\nPlease specify the entrypoint: `uipath init <entrypoint_path>`"
|
|
47
50
|
)
|
|
48
51
|
return None
|
|
49
52
|
|
|
@@ -51,67 +54,59 @@ def get_user_script(directory: str, entrypoint: Optional[str] = None) -> Optiona
|
|
|
51
54
|
@click.command()
|
|
52
55
|
@click.argument("entrypoint", required=False, default=None)
|
|
53
56
|
def init(entrypoint: str) -> None:
|
|
54
|
-
"""
|
|
55
|
-
spinner
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
result = Middlewares.next("init", entrypoint)
|
|
60
|
-
|
|
61
|
-
if result.error_message:
|
|
62
|
-
click.echo(result.error_message)
|
|
63
|
-
if result.should_include_stacktrace:
|
|
64
|
-
click.echo(traceback.format_exc())
|
|
65
|
-
click.get_current_context().exit(1)
|
|
66
|
-
|
|
67
|
-
if result.info_message:
|
|
68
|
-
click.echo(result.info_message)
|
|
69
|
-
|
|
70
|
-
if not result.should_continue:
|
|
71
|
-
return
|
|
72
|
-
script_path = get_user_script(current_directory, entrypoint=entrypoint)
|
|
73
|
-
|
|
74
|
-
if not script_path:
|
|
75
|
-
click.get_current_context().exit(1)
|
|
76
|
-
spinner.start()
|
|
77
|
-
try:
|
|
78
|
-
args = generate_args(script_path)
|
|
79
|
-
|
|
80
|
-
relative_path = Path(script_path).relative_to(current_directory).as_posix()
|
|
81
|
-
|
|
82
|
-
config_data = {
|
|
83
|
-
"entryPoints": [
|
|
84
|
-
{
|
|
85
|
-
"filePath": relative_path,
|
|
86
|
-
"uniqueId": str(uuid.uuid4()),
|
|
87
|
-
# "type": "process", OR BE doesn't offer json schema support for type: Process
|
|
88
|
-
"type": "agent",
|
|
89
|
-
"input": args["input"],
|
|
90
|
-
"output": args["output"],
|
|
91
|
-
}
|
|
92
|
-
]
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
# Generate bindings JSON based on the script path
|
|
96
|
-
try:
|
|
97
|
-
bindings_data = generate_bindings_json(script_path)
|
|
98
|
-
# Add bindings to the config data
|
|
99
|
-
config_data["bindings"] = bindings_data
|
|
100
|
-
except Exception as e:
|
|
101
|
-
click.echo(f"⚠️ Warning: Could not generate bindings: {str(e)}")
|
|
57
|
+
"""Create uipath.json with input/output schemas and bindings."""
|
|
58
|
+
with console.spinner("Initializing UiPath project ..."):
|
|
59
|
+
current_directory = os.getcwd()
|
|
60
|
+
generate_env_file(current_directory)
|
|
102
61
|
|
|
103
|
-
|
|
104
|
-
with open(config_path, "w") as config_file:
|
|
105
|
-
json.dump(config_data, config_file, indent=4)
|
|
62
|
+
result = Middlewares.next("init", entrypoint)
|
|
106
63
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
64
|
+
if result.error_message:
|
|
65
|
+
console.error(
|
|
66
|
+
result.error_message, include_traceback=result.should_include_stacktrace
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
if result.info_message:
|
|
70
|
+
console.info(result.info_message)
|
|
112
71
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
72
|
+
if not result.should_continue:
|
|
73
|
+
return
|
|
74
|
+
|
|
75
|
+
script_path = get_user_script(current_directory, entrypoint=entrypoint)
|
|
76
|
+
|
|
77
|
+
if not script_path:
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
args = generate_args(script_path)
|
|
82
|
+
|
|
83
|
+
relative_path = Path(script_path).relative_to(current_directory).as_posix()
|
|
84
|
+
|
|
85
|
+
config_data = {
|
|
86
|
+
"entryPoints": [
|
|
87
|
+
{
|
|
88
|
+
"filePath": relative_path,
|
|
89
|
+
"uniqueId": str(uuid.uuid4()),
|
|
90
|
+
# "type": "process", OR BE doesn't offer json schema support for type: Process
|
|
91
|
+
"type": "agent",
|
|
92
|
+
"input": args["input"],
|
|
93
|
+
"output": args["output"],
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# Generate bindings JSON based on the script path
|
|
99
|
+
try:
|
|
100
|
+
bindings_data = generate_bindings_json(script_path)
|
|
101
|
+
# Add bindings to the config data
|
|
102
|
+
config_data["bindings"] = bindings_data
|
|
103
|
+
except Exception as e:
|
|
104
|
+
console.warning(f"Warning: Could not generate bindings: {str(e)}")
|
|
105
|
+
|
|
106
|
+
config_path = "uipath.json"
|
|
107
|
+
with open(config_path, "w") as config_file:
|
|
108
|
+
json.dump(config_data, config_file, indent=4)
|
|
109
|
+
|
|
110
|
+
console.success(f"Created '{config_path}' file.")
|
|
111
|
+
except Exception as e:
|
|
112
|
+
console.error(f"Error creating configuration file: {str(e)}")
|
uipath/_cli/cli_invoke.py
CHANGED
|
@@ -7,7 +7,7 @@ import click
|
|
|
7
7
|
import requests
|
|
8
8
|
from dotenv import load_dotenv
|
|
9
9
|
|
|
10
|
-
from .
|
|
10
|
+
from ._utils._console import ConsoleLogger
|
|
11
11
|
|
|
12
12
|
try:
|
|
13
13
|
import tomllib
|
|
@@ -20,22 +20,21 @@ from ._utils._processes import get_release_info
|
|
|
20
20
|
|
|
21
21
|
logger = logging.getLogger(__name__)
|
|
22
22
|
load_dotenv()
|
|
23
|
+
console = ConsoleLogger()
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
def _read_project_name() -> str:
|
|
26
27
|
current_path = os.getcwd()
|
|
27
28
|
toml_path = os.path.join(current_path, "pyproject.toml")
|
|
28
29
|
if not os.path.isfile(toml_path):
|
|
29
|
-
|
|
30
|
+
console.error("pyproject.toml not found.")
|
|
30
31
|
|
|
31
32
|
with open(toml_path, "rb") as f:
|
|
32
33
|
content = tomllib.load(f)
|
|
33
34
|
if "project" not in content:
|
|
34
|
-
|
|
35
|
+
console.error("pyproject.toml is missing the required field: project.")
|
|
35
36
|
if "name" not in content["project"]:
|
|
36
|
-
|
|
37
|
-
"pyproject.toml is missing the required field: project.name"
|
|
38
|
-
)
|
|
37
|
+
console.error("pyproject.toml is missing the required field: project.name.")
|
|
39
38
|
|
|
40
39
|
return content["project"]["name"]
|
|
41
40
|
|
|
@@ -44,60 +43,54 @@ def _read_project_name() -> str:
|
|
|
44
43
|
@click.argument("entrypoint", required=False)
|
|
45
44
|
@click.argument("input", required=False, default="{}")
|
|
46
45
|
def invoke(entrypoint: Optional[str], input: Optional[str]) -> None:
|
|
47
|
-
"""Invoke a
|
|
48
|
-
spinner
|
|
49
|
-
|
|
46
|
+
"""Invoke a published agent."""
|
|
47
|
+
with console.spinner("Loading configuration ..."):
|
|
48
|
+
current_path = os.getcwd()
|
|
49
|
+
load_dotenv(os.path.join(current_path, ".env"), override=True)
|
|
50
|
+
[base_url, token] = get_env_vars()
|
|
51
|
+
|
|
52
|
+
url = f"{base_url}/orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs"
|
|
53
|
+
_, personal_workspace_folder_id = get_personal_workspace_info(base_url, token)
|
|
54
|
+
project_name = _read_project_name()
|
|
55
|
+
|
|
56
|
+
if not personal_workspace_folder_id:
|
|
57
|
+
console.error(
|
|
58
|
+
"No personal workspace found for user. Please try reauthenticating."
|
|
59
|
+
)
|
|
50
60
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"StartInfo": {
|
|
66
|
-
"ReleaseKey": str(release_key),
|
|
67
|
-
"RunAsMe": True,
|
|
68
|
-
"InputArguments": input,
|
|
69
|
-
"EntryPointPath": entrypoint,
|
|
61
|
+
_, release_key = get_release_info(
|
|
62
|
+
base_url, token, project_name, personal_workspace_folder_id
|
|
63
|
+
)
|
|
64
|
+
payload = {
|
|
65
|
+
"StartInfo": {
|
|
66
|
+
"ReleaseKey": str(release_key),
|
|
67
|
+
"RunAsMe": True,
|
|
68
|
+
"InputArguments": input,
|
|
69
|
+
"EntryPointPath": entrypoint,
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
headers = {
|
|
73
|
+
"Authorization": f"Bearer {token}",
|
|
74
|
+
"x-uipath-organizationunitid": str(personal_workspace_folder_id),
|
|
70
75
|
}
|
|
71
|
-
}
|
|
72
|
-
headers = {
|
|
73
|
-
"Authorization": f"Bearer {token}",
|
|
74
|
-
"x-uipath-organizationunitid": str(personal_workspace_folder_id),
|
|
75
|
-
}
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
spinner.stop()
|
|
77
|
+
response = requests.post(url, json=payload, headers=headers)
|
|
79
78
|
|
|
80
79
|
if response.status_code == 201:
|
|
81
80
|
job_key = None
|
|
82
81
|
try:
|
|
83
82
|
job_key = response.json()["value"][0]["Key"]
|
|
84
83
|
except KeyError:
|
|
85
|
-
|
|
86
|
-
click.Abort()
|
|
84
|
+
console.error("Error: Failed to get job key from response")
|
|
87
85
|
if job_key:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
"
|
|
92
|
-
+ click.style(
|
|
93
|
-
f"\u001b]8;;{job_url}\u001b\\{job_url}\u001b]8;;\u001b\\",
|
|
94
|
-
fg="bright_blue",
|
|
95
|
-
bold=True,
|
|
96
|
-
)
|
|
97
|
-
)
|
|
86
|
+
with console.spinner("Starting job ..."):
|
|
87
|
+
job_url = f"{base_url}/orchestrator_/jobs(sidepanel:sidepanel/jobs/{job_key}/details)?fid={personal_workspace_folder_id}"
|
|
88
|
+
console.magic("Job started successfully!")
|
|
89
|
+
console.link("Monitor your job here: ", job_url)
|
|
98
90
|
else:
|
|
99
|
-
|
|
100
|
-
|
|
91
|
+
console.error(
|
|
92
|
+
f"Error: Failed to start job. Status code: {response.status_code} {response.text}"
|
|
93
|
+
)
|
|
101
94
|
|
|
102
95
|
|
|
103
96
|
if __name__ == "__main__":
|
uipath/_cli/cli_new.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# type: ignore
|
|
2
2
|
import os
|
|
3
3
|
import shutil
|
|
4
|
-
import traceback
|
|
5
4
|
|
|
6
5
|
import click
|
|
7
6
|
|
|
7
|
+
from ._utils._console import ConsoleLogger
|
|
8
8
|
from .middlewares import Middlewares
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
console = ConsoleLogger()
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def generate_script(target_directory):
|
|
@@ -26,9 +27,9 @@ version = "0.0.1"
|
|
|
26
27
|
description = "{project_name}"
|
|
27
28
|
authors = [{{ name = "John Doe", email = "john.doe@myemail.com" }}]
|
|
28
29
|
dependencies = [
|
|
29
|
-
"uipath>=2.0.
|
|
30
|
+
"uipath>=2.0.26"
|
|
30
31
|
]
|
|
31
|
-
requires-python = ">=3.
|
|
32
|
+
requires-python = ">=3.10"
|
|
32
33
|
"""
|
|
33
34
|
|
|
34
35
|
with open(project_toml_path, "w") as f:
|
|
@@ -38,44 +39,38 @@ requires-python = ">=3.9"
|
|
|
38
39
|
@click.command()
|
|
39
40
|
@click.argument("name", type=str, default="")
|
|
40
41
|
def new(name: str):
|
|
41
|
-
|
|
42
|
+
"""Generate a quick-start project."""
|
|
42
43
|
directory = os.getcwd()
|
|
43
44
|
|
|
44
45
|
if not name:
|
|
45
|
-
|
|
46
|
-
"Please specify a name for your project
|
|
46
|
+
console.error(
|
|
47
|
+
"Please specify a name for your project:\n`uipath new hello-world`"
|
|
47
48
|
)
|
|
48
49
|
|
|
49
|
-
click.echo(
|
|
50
|
-
click.style("✓ ", fg="green", bold=True)
|
|
51
|
-
+ f"Initializing project {name} in current directory.."
|
|
52
|
-
)
|
|
53
|
-
|
|
54
50
|
result = Middlewares.next("new", name)
|
|
55
51
|
|
|
56
52
|
if result.error_message:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
click.get_current_context().exit(1)
|
|
53
|
+
console.error(
|
|
54
|
+
result.error_message, include_traceback=result.should_include_stacktrace
|
|
55
|
+
)
|
|
61
56
|
|
|
62
57
|
if result.info_message:
|
|
63
|
-
|
|
58
|
+
console.info(result.info_message)
|
|
64
59
|
|
|
65
60
|
if not result.should_continue:
|
|
66
61
|
return
|
|
67
62
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
with console.spinner(f"Creating new project {name} in current directory ..."):
|
|
64
|
+
generate_script(directory)
|
|
65
|
+
console.success("Created 'main.py' file.")
|
|
66
|
+
generate_pyproject(directory, name)
|
|
67
|
+
console.success("Created 'pyproject.toml' file.")
|
|
68
|
+
ctx = click.get_current_context()
|
|
69
|
+
init_cmd = ctx.parent.command.get_command(ctx, "init")
|
|
70
|
+
ctx.invoke(init_cmd)
|
|
71
|
+
console.hint(
|
|
72
|
+
"""Run project: uipath run main.py '{"message": "Hello World!"}'"""
|
|
73
|
+
)
|
|
79
74
|
|
|
80
75
|
|
|
81
76
|
if __name__ == "__main__":
|
uipath/_cli/cli_pack.py
CHANGED
|
@@ -12,7 +12,9 @@ try:
|
|
|
12
12
|
except ImportError:
|
|
13
13
|
import tomli as tomllib
|
|
14
14
|
|
|
15
|
-
from .
|
|
15
|
+
from ._utils._console import ConsoleLogger
|
|
16
|
+
|
|
17
|
+
console = ConsoleLogger()
|
|
16
18
|
|
|
17
19
|
schema = "https://cloud.uipath.com/draft/2024-12/entry-point"
|
|
18
20
|
|
|
@@ -21,7 +23,7 @@ def validate_config_structure(config_data):
|
|
|
21
23
|
required_fields = ["entryPoints"]
|
|
22
24
|
for field in required_fields:
|
|
23
25
|
if field not in config_data:
|
|
24
|
-
|
|
26
|
+
console.error(f"uipath.json is missing the required field: {field}.")
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
def check_config(directory):
|
|
@@ -29,9 +31,9 @@ def check_config(directory):
|
|
|
29
31
|
toml_path = os.path.join(directory, "pyproject.toml")
|
|
30
32
|
|
|
31
33
|
if not os.path.isfile(config_path):
|
|
32
|
-
|
|
34
|
+
console.error("uipath.json not found, please run `uipath init`.")
|
|
33
35
|
if not os.path.isfile(toml_path):
|
|
34
|
-
|
|
36
|
+
console.error("pyproject.toml not found.")
|
|
35
37
|
|
|
36
38
|
with open(config_path, "r") as config_file:
|
|
37
39
|
config_data = json.load(config_file)
|
|
@@ -206,7 +208,7 @@ def pack_fn(projectName, description, entryPoints, version, authors, directory):
|
|
|
206
208
|
# Get bindings from uipath.json if available
|
|
207
209
|
config_path = os.path.join(directory, "uipath.json")
|
|
208
210
|
if not os.path.exists(config_path):
|
|
209
|
-
|
|
211
|
+
console.error("uipath.json not found, please run `uipath init`.")
|
|
210
212
|
|
|
211
213
|
# Define the allowlist of file extensions to include
|
|
212
214
|
file_extensions_included = [".py", ".mermaid", ".json", ".yaml", ".yml"]
|
|
@@ -305,18 +307,16 @@ def read_toml_project(file_path: str) -> dict[str, any]:
|
|
|
305
307
|
with open(file_path, "rb") as f:
|
|
306
308
|
content = tomllib.load(f)
|
|
307
309
|
if "project" not in content:
|
|
308
|
-
|
|
310
|
+
console.error("pyproject.toml is missing the required field: project.")
|
|
309
311
|
if "name" not in content["project"]:
|
|
310
|
-
|
|
311
|
-
"pyproject.toml is missing the required field: project.name"
|
|
312
|
-
)
|
|
312
|
+
console.error("pyproject.toml is missing the required field: project.name.")
|
|
313
313
|
if "description" not in content["project"]:
|
|
314
|
-
|
|
315
|
-
"pyproject.toml is missing the required field: project.description"
|
|
314
|
+
console.error(
|
|
315
|
+
"pyproject.toml is missing the required field: project.description."
|
|
316
316
|
)
|
|
317
317
|
if "version" not in content["project"]:
|
|
318
|
-
|
|
319
|
-
"pyproject.toml is missing the required field: project.version"
|
|
318
|
+
console.error(
|
|
319
|
+
"pyproject.toml is missing the required field: project.version."
|
|
320
320
|
)
|
|
321
321
|
|
|
322
322
|
return {
|
|
@@ -330,63 +330,80 @@ def read_toml_project(file_path: str) -> dict[str, any]:
|
|
|
330
330
|
def get_project_version(directory):
|
|
331
331
|
toml_path = os.path.join(directory, "pyproject.toml")
|
|
332
332
|
if not os.path.exists(toml_path):
|
|
333
|
-
|
|
333
|
+
console.warning("pyproject.toml not found. Using default version 0.0.1")
|
|
334
334
|
return "0.0.1"
|
|
335
335
|
toml_data = read_toml_project(toml_path)
|
|
336
336
|
return toml_data["version"]
|
|
337
337
|
|
|
338
338
|
|
|
339
|
+
def display_project_info(config):
|
|
340
|
+
max_label_length = max(
|
|
341
|
+
len(label) for label in ["Name", "Version", "Description", "Authors"]
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
max_length = 100
|
|
345
|
+
description = config["description"]
|
|
346
|
+
if len(description) >= max_length:
|
|
347
|
+
description = description[: max_length - 3] + " ..."
|
|
348
|
+
|
|
349
|
+
console.log(f"{'Name'.ljust(max_label_length)}: {config['project_name']}")
|
|
350
|
+
console.log(f"{'Version'.ljust(max_label_length)}: {config['version']}")
|
|
351
|
+
console.log(f"{'Description'.ljust(max_label_length)}: {description}")
|
|
352
|
+
console.log(f"{'Authors'.ljust(max_label_length)}: {config['authors']}")
|
|
353
|
+
|
|
354
|
+
|
|
339
355
|
@click.command()
|
|
340
356
|
@click.argument("root", type=str, default="./")
|
|
341
357
|
def pack(root):
|
|
358
|
+
"""Pack the project."""
|
|
342
359
|
version = get_project_version(root)
|
|
343
360
|
|
|
344
361
|
while not os.path.isfile(os.path.join(root, "uipath.json")):
|
|
345
|
-
|
|
346
|
-
"
|
|
362
|
+
console.error(
|
|
363
|
+
"uipath.json not found. Please run `uipath init` in the project directory."
|
|
347
364
|
)
|
|
348
|
-
return
|
|
349
365
|
config = check_config(root)
|
|
350
366
|
if not config["project_name"] or config["project_name"].strip() == "":
|
|
351
|
-
|
|
367
|
+
console.error(
|
|
368
|
+
"Project name cannot be empty. Please specify a name in pyproject.toml."
|
|
369
|
+
)
|
|
352
370
|
|
|
353
371
|
if not config["description"] or config["description"].strip() == "":
|
|
354
|
-
|
|
372
|
+
console.error(
|
|
373
|
+
"Project description cannot be empty. Please specify a description in pyproject.toml."
|
|
374
|
+
)
|
|
355
375
|
|
|
356
376
|
if not config["authors"] or config["authors"].strip() == "":
|
|
357
|
-
|
|
377
|
+
console.error(
|
|
378
|
+
'Project authors cannot be empty. Please specify authors in pyproject.toml:\n authors = [{ name = "John Doe" }]'
|
|
379
|
+
)
|
|
358
380
|
|
|
359
381
|
invalid_chars = ["&", "<", ">", '"', "'", ";"]
|
|
360
382
|
for char in invalid_chars:
|
|
361
383
|
if char in config["project_name"]:
|
|
362
|
-
|
|
384
|
+
console.error(f"Project name contains invalid character: '{char}'")
|
|
363
385
|
|
|
364
386
|
for char in invalid_chars:
|
|
365
387
|
if char in config["description"]:
|
|
366
|
-
|
|
367
|
-
|
|
388
|
+
console.error(f"Project description contains invalid character: '{char}'")
|
|
389
|
+
|
|
390
|
+
with console.spinner("Packaging project ..."):
|
|
391
|
+
try:
|
|
392
|
+
pack_fn(
|
|
393
|
+
config["project_name"],
|
|
394
|
+
config["description"],
|
|
395
|
+
config["entryPoints"],
|
|
396
|
+
version or config["version"],
|
|
397
|
+
config["authors"],
|
|
398
|
+
root,
|
|
399
|
+
)
|
|
400
|
+
display_project_info(config)
|
|
401
|
+
console.success("Project successfully packaged.")
|
|
402
|
+
|
|
403
|
+
except Exception as e:
|
|
404
|
+
console.error(
|
|
405
|
+
f"Failed to create package {config['project_name']}.{version or config['version']}: {str(e)}"
|
|
368
406
|
)
|
|
369
|
-
spinner = Spinner(
|
|
370
|
-
f"Packaging project {config['project_name']}:{version or config['version']} description {config['description']} authored by {config['authors']}"
|
|
371
|
-
)
|
|
372
|
-
try:
|
|
373
|
-
spinner.start()
|
|
374
|
-
pack_fn(
|
|
375
|
-
config["project_name"],
|
|
376
|
-
config["description"],
|
|
377
|
-
config["entryPoints"],
|
|
378
|
-
version or config["version"],
|
|
379
|
-
config["authors"],
|
|
380
|
-
root,
|
|
381
|
-
)
|
|
382
|
-
spinner.stop()
|
|
383
|
-
click.echo(
|
|
384
|
-
click.style("✓ ", fg="green", bold=True) + "Package created successfully!"
|
|
385
|
-
)
|
|
386
|
-
except Exception as e:
|
|
387
|
-
spinner.stop()
|
|
388
|
-
click.echo(f"\n❌ Error: {str(e)}")
|
|
389
|
-
click.Abort()
|
|
390
407
|
|
|
391
408
|
|
|
392
409
|
if __name__ == "__main__":
|