partcad-cli 0.5.22__tar.gz → 0.6.2__tar.gz
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.
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/PKG-INFO +12 -4
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/README.md +10 -2
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/pyproject.toml +1 -1
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/requirements.txt +1 -1
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli/__init__.py +1 -1
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli/cli.py +32 -3
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli/cli_add.py +21 -1
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli/cli_info.py +16 -0
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli/cli_inspect.py +25 -3
- partcad_cli-0.6.2/src/partcad_cli/cli_list.py +525 -0
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli/cli_status.py +3 -0
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli.egg-info/PKG-INFO +12 -4
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli.egg-info/requires.txt +1 -1
- partcad_cli-0.5.22/src/partcad_cli/cli_list.py +0 -245
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/setup.cfg +0 -0
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli/cli_init.py +0 -0
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli/cli_install.py +0 -0
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli/cli_render.py +0 -0
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli.egg-info/SOURCES.txt +0 -0
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli.egg-info/dependency_links.txt +0 -0
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli.egg-info/entry_points.txt +0 -0
- {partcad_cli-0.5.22 → partcad_cli-0.6.2}/src/partcad_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: partcad-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Summary: Command-line interface to PartCAD
|
|
5
5
|
Author-email: Roman Kuzmenko <openvmp@proton.me>
|
|
6
6
|
Maintainer-email: Roman Kuzmenko <openvmp@proton.me>
|
|
@@ -12,7 +12,7 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Requires-Python: >=3.10
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
|
-
Requires-Dist: partcad==0.
|
|
15
|
+
Requires-Dist: partcad==0.6.2
|
|
16
16
|
Requires-Dist: renderlab
|
|
17
17
|
Requires-Dist: rlPyCairo
|
|
18
18
|
Requires-Dist: svglib
|
|
@@ -30,14 +30,22 @@ Requires-Dist: ocp_vscode
|
|
|
30
30
|
|
|
31
31
|
PartCAD is the first package manager for CAD models
|
|
32
32
|
and a framework for managing assemblies.
|
|
33
|
-
It
|
|
33
|
+
It aims to complement Git with everything necessary to substitute
|
|
34
34
|
commercial Product Lifecycle Management (PLM) tools.
|
|
35
35
|
|
|
36
36
|
PartCAD maintains information about mechanical parts and
|
|
37
37
|
how they come together to form larger assemblies.
|
|
38
|
-
The same parts
|
|
38
|
+
The same parts can be reused in multiple assemblies and multiple projects.
|
|
39
39
|
And all of that is supercharged by the ultimate versioning and collaboration features of Git.
|
|
40
40
|
|
|
41
|
+
PartCAD features include:
|
|
42
|
+
|
|
43
|
+
- 3D part models using STEP, STL and 3MF files
|
|
44
|
+
- 3D part models using CadQuery, build123d and OpenSCAD scripting languages (including AI-generated: Gemini and GPT)
|
|
45
|
+
- 2D blueprints using DXF, build123d and SVG files
|
|
46
|
+
- Fully featured object-oriented approach to maintain part interfaces and mating information (with multiple class inheritance etc)
|
|
47
|
+
- Live preview of 3D models while coding in VS Code
|
|
48
|
+
|
|
41
49
|
Find [more documentation here](https://partcad.readthedocs.io/en/latest/?badge=latest) and visit [our website](https://partcad.org/).
|
|
42
50
|
|
|
43
51
|
## Installation
|
|
@@ -10,14 +10,22 @@
|
|
|
10
10
|
|
|
11
11
|
PartCAD is the first package manager for CAD models
|
|
12
12
|
and a framework for managing assemblies.
|
|
13
|
-
It
|
|
13
|
+
It aims to complement Git with everything necessary to substitute
|
|
14
14
|
commercial Product Lifecycle Management (PLM) tools.
|
|
15
15
|
|
|
16
16
|
PartCAD maintains information about mechanical parts and
|
|
17
17
|
how they come together to form larger assemblies.
|
|
18
|
-
The same parts
|
|
18
|
+
The same parts can be reused in multiple assemblies and multiple projects.
|
|
19
19
|
And all of that is supercharged by the ultimate versioning and collaboration features of Git.
|
|
20
20
|
|
|
21
|
+
PartCAD features include:
|
|
22
|
+
|
|
23
|
+
- 3D part models using STEP, STL and 3MF files
|
|
24
|
+
- 3D part models using CadQuery, build123d and OpenSCAD scripting languages (including AI-generated: Gemini and GPT)
|
|
25
|
+
- 2D blueprints using DXF, build123d and SVG files
|
|
26
|
+
- Fully featured object-oriented approach to maintain part interfaces and mating information (with multiple class inheritance etc)
|
|
27
|
+
- Live preview of 3D models while coding in VS Code
|
|
28
|
+
|
|
21
29
|
Find [more documentation here](https://partcad.readthedocs.io/en/latest/?badge=latest) and visit [our website](https://partcad.org/).
|
|
22
30
|
|
|
23
31
|
## Installation
|
|
@@ -40,6 +40,13 @@ def main():
|
|
|
40
40
|
action="count",
|
|
41
41
|
default=0,
|
|
42
42
|
)
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
"-q",
|
|
45
|
+
help="Decrease the level of verbosity",
|
|
46
|
+
dest="quiet",
|
|
47
|
+
action="count",
|
|
48
|
+
default=0,
|
|
49
|
+
)
|
|
43
50
|
parser.add_argument(
|
|
44
51
|
"--no-ansi",
|
|
45
52
|
help="Plain logging output. Do not use colors or animations.",
|
|
@@ -55,6 +62,10 @@ def main():
|
|
|
55
62
|
)
|
|
56
63
|
# TODO(clairbee): add a config option to change logging mechanism and level
|
|
57
64
|
subparsers = parser.add_subparsers(dest="command")
|
|
65
|
+
subparsers.add_parser(
|
|
66
|
+
"version",
|
|
67
|
+
help="Print PartCAD version and exit",
|
|
68
|
+
)
|
|
58
69
|
cli_help_add(subparsers)
|
|
59
70
|
cli_help_init(subparsers)
|
|
60
71
|
cli_help_info(subparsers)
|
|
@@ -72,10 +83,13 @@ def main():
|
|
|
72
83
|
else:
|
|
73
84
|
logging.basicConfig()
|
|
74
85
|
|
|
75
|
-
if args.
|
|
76
|
-
pc.logging.setLevel(logging.
|
|
86
|
+
if args.quiet > 0:
|
|
87
|
+
pc.logging.setLevel(logging.ERROR)
|
|
77
88
|
else:
|
|
78
|
-
|
|
89
|
+
if args.verbosity > 0:
|
|
90
|
+
pc.logging.setLevel(logging.DEBUG)
|
|
91
|
+
else:
|
|
92
|
+
pc.logging.setLevel(logging.INFO)
|
|
79
93
|
|
|
80
94
|
try:
|
|
81
95
|
# First, handle the commands that don't require a context or initialize it
|
|
@@ -86,6 +100,9 @@ def main():
|
|
|
86
100
|
elif args.command == "status":
|
|
87
101
|
cli_status(args)
|
|
88
102
|
return
|
|
103
|
+
elif args.command == "version":
|
|
104
|
+
pc_logging.info("PartCAD version: %s" % pc.__version__)
|
|
105
|
+
return
|
|
89
106
|
|
|
90
107
|
if args.command == "install" or args.command == "update":
|
|
91
108
|
user_config.force_update = True
|
|
@@ -126,6 +143,18 @@ def main():
|
|
|
126
143
|
cli_list_assemblies(args, ctx)
|
|
127
144
|
cli_list_parts(args, ctx)
|
|
128
145
|
|
|
146
|
+
elif args.command == "list-sketches":
|
|
147
|
+
with pc_logging.Process("ListSketches", "this"):
|
|
148
|
+
cli_list_sketches(args, ctx)
|
|
149
|
+
|
|
150
|
+
elif args.command == "list-interfaces":
|
|
151
|
+
with pc_logging.Process("ListInterfaces", "this"):
|
|
152
|
+
cli_list_interfaces(args, ctx)
|
|
153
|
+
|
|
154
|
+
elif args.command == "list-mates":
|
|
155
|
+
with pc_logging.Process("ListMates", "this"):
|
|
156
|
+
cli_list_mates(args, ctx)
|
|
157
|
+
|
|
129
158
|
elif args.command == "list-parts":
|
|
130
159
|
with pc_logging.Process("ListParts", "this"):
|
|
131
160
|
cli_list_parts(args, ctx)
|
|
@@ -33,6 +33,21 @@ def cli_help_add(subparsers):
|
|
|
33
33
|
"add-part",
|
|
34
34
|
help="Add a part",
|
|
35
35
|
)
|
|
36
|
+
parser_add_part.add_argument(
|
|
37
|
+
"--desc",
|
|
38
|
+
help="The part description (also used by LLMs).",
|
|
39
|
+
dest="desc",
|
|
40
|
+
type=str,
|
|
41
|
+
required=False,
|
|
42
|
+
)
|
|
43
|
+
parser_add_part.add_argument(
|
|
44
|
+
"--ai",
|
|
45
|
+
help="Generative AI provider.",
|
|
46
|
+
dest="provider",
|
|
47
|
+
type=str,
|
|
48
|
+
choices=["google", "openai"],
|
|
49
|
+
required=False,
|
|
50
|
+
)
|
|
36
51
|
parser_add_part.add_argument(
|
|
37
52
|
"kind",
|
|
38
53
|
help="Type of the part",
|
|
@@ -78,7 +93,12 @@ def cli_add(args, ctx):
|
|
|
78
93
|
|
|
79
94
|
def cli_add_part(args, ctx):
|
|
80
95
|
prj = ctx.get_project(pc.ROOT)
|
|
81
|
-
|
|
96
|
+
config = {}
|
|
97
|
+
if args.desc:
|
|
98
|
+
config["desc"] = args.desc
|
|
99
|
+
if args.provider:
|
|
100
|
+
config["provider"] = args.provider
|
|
101
|
+
if prj.add_part(args.kind, args.path, config):
|
|
82
102
|
Path(args.path).touch()
|
|
83
103
|
|
|
84
104
|
|
|
@@ -29,6 +29,12 @@ def cli_help_info(subparsers):
|
|
|
29
29
|
)
|
|
30
30
|
|
|
31
31
|
group_type = parser_info.add_mutually_exclusive_group(required=False)
|
|
32
|
+
group_type.add_argument(
|
|
33
|
+
"-i",
|
|
34
|
+
help="The object is an interface",
|
|
35
|
+
dest="interface",
|
|
36
|
+
action="store_true",
|
|
37
|
+
)
|
|
32
38
|
group_type.add_argument(
|
|
33
39
|
"-a",
|
|
34
40
|
help="The object is an assembly",
|
|
@@ -37,6 +43,12 @@ def cli_help_info(subparsers):
|
|
|
37
43
|
)
|
|
38
44
|
group_type.add_argument(
|
|
39
45
|
"-s",
|
|
46
|
+
help="The object is a sketch",
|
|
47
|
+
dest="sketch",
|
|
48
|
+
action="store_true",
|
|
49
|
+
)
|
|
50
|
+
group_type.add_argument(
|
|
51
|
+
"-S",
|
|
40
52
|
help="The object is a scene",
|
|
41
53
|
dest="scene",
|
|
42
54
|
action="store_true",
|
|
@@ -75,6 +87,10 @@ def cli_info(args, ctx):
|
|
|
75
87
|
|
|
76
88
|
if args.assembly:
|
|
77
89
|
obj = ctx.get_assembly(path, params=params)
|
|
90
|
+
elif args.interface:
|
|
91
|
+
obj = ctx.get_interface(path)
|
|
92
|
+
elif args.sketch:
|
|
93
|
+
obj = ctx.get_sketch(path, params=params)
|
|
78
94
|
else:
|
|
79
95
|
obj = ctx.get_part(path, params=params)
|
|
80
96
|
|
|
@@ -35,6 +35,12 @@ def cli_help_inspect(subparsers):
|
|
|
35
35
|
)
|
|
36
36
|
|
|
37
37
|
group_type = parser_inspect.add_mutually_exclusive_group(required=False)
|
|
38
|
+
group_type.add_argument(
|
|
39
|
+
"-i",
|
|
40
|
+
help="The object is an interface",
|
|
41
|
+
dest="interface",
|
|
42
|
+
action="store_true",
|
|
43
|
+
)
|
|
38
44
|
group_type.add_argument(
|
|
39
45
|
"-a",
|
|
40
46
|
help="The object is an assembly",
|
|
@@ -43,6 +49,12 @@ def cli_help_inspect(subparsers):
|
|
|
43
49
|
)
|
|
44
50
|
group_type.add_argument(
|
|
45
51
|
"-s",
|
|
52
|
+
help="The object is a sketch",
|
|
53
|
+
dest="sketch",
|
|
54
|
+
action="store_true",
|
|
55
|
+
)
|
|
56
|
+
group_type.add_argument(
|
|
57
|
+
"-S",
|
|
46
58
|
help="The object is a scene",
|
|
47
59
|
dest="scene",
|
|
48
60
|
action="store_true",
|
|
@@ -81,6 +93,10 @@ def cli_inspect(args, ctx):
|
|
|
81
93
|
|
|
82
94
|
if args.assembly:
|
|
83
95
|
obj = ctx.get_assembly(path, params=params)
|
|
96
|
+
elif args.interface:
|
|
97
|
+
obj = ctx.get_interface(path)
|
|
98
|
+
elif args.sketch:
|
|
99
|
+
obj = ctx.get_sketch(path, params=params)
|
|
84
100
|
else:
|
|
85
101
|
obj = ctx.get_part(path, params=params)
|
|
86
102
|
|
|
@@ -94,8 +110,14 @@ def cli_inspect(args, ctx):
|
|
|
94
110
|
)
|
|
95
111
|
else:
|
|
96
112
|
if args.verbal:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
113
|
+
if args.package is None:
|
|
114
|
+
package_obj = ctx.get_project("/")
|
|
115
|
+
else:
|
|
116
|
+
package_obj = ctx.get_project(args.package)
|
|
117
|
+
|
|
118
|
+
summary = obj.get_summary(package_obj)
|
|
119
|
+
pc_logging.info("Summary: %s" % summary)
|
|
120
|
+
if args.quiet > 0:
|
|
121
|
+
print("%s" % summary)
|
|
100
122
|
else:
|
|
101
123
|
obj.show()
|
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
#
|
|
2
|
+
# OpenVMP, 2023
|
|
3
|
+
#
|
|
4
|
+
# Author: Roman Kuzmenko
|
|
5
|
+
# Created: 2023-12-23
|
|
6
|
+
#
|
|
7
|
+
# Licensed under Apache License, Version 2.0.
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
import time
|
|
11
|
+
|
|
12
|
+
import partcad as pc
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def cli_help_list(subparsers):
|
|
16
|
+
parser_list = subparsers.add_parser(
|
|
17
|
+
"list",
|
|
18
|
+
help="List imported packages",
|
|
19
|
+
)
|
|
20
|
+
parser_list_all = subparsers.add_parser(
|
|
21
|
+
"list-all",
|
|
22
|
+
help="List available parts, assemblies and scenes",
|
|
23
|
+
)
|
|
24
|
+
parser_list_sketches = subparsers.add_parser(
|
|
25
|
+
"list-sketches",
|
|
26
|
+
help="List available sketches",
|
|
27
|
+
)
|
|
28
|
+
parser_list_interfaces = subparsers.add_parser(
|
|
29
|
+
"list-interfaces",
|
|
30
|
+
help="List available interfaces",
|
|
31
|
+
)
|
|
32
|
+
parser_list_mates = subparsers.add_parser(
|
|
33
|
+
"list-mates",
|
|
34
|
+
help="List available mating interfaces",
|
|
35
|
+
)
|
|
36
|
+
parser_list_parts = subparsers.add_parser(
|
|
37
|
+
"list-parts",
|
|
38
|
+
help="List available parts",
|
|
39
|
+
)
|
|
40
|
+
parser_list_assemblies = subparsers.add_parser(
|
|
41
|
+
"list-assemblies",
|
|
42
|
+
help="List available assemblies",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
parser_list_all.add_argument(
|
|
46
|
+
"-r",
|
|
47
|
+
help="Recursively process all imported packages",
|
|
48
|
+
dest="recursive",
|
|
49
|
+
action="store_true",
|
|
50
|
+
)
|
|
51
|
+
parser_list_sketches.add_argument(
|
|
52
|
+
"-r",
|
|
53
|
+
help="Recursively process all imported packages",
|
|
54
|
+
dest="recursive",
|
|
55
|
+
action="store_true",
|
|
56
|
+
)
|
|
57
|
+
parser_list_interfaces.add_argument(
|
|
58
|
+
"-r",
|
|
59
|
+
help="Recursively process all imported packages",
|
|
60
|
+
dest="recursive",
|
|
61
|
+
action="store_true",
|
|
62
|
+
)
|
|
63
|
+
parser_list_mates.add_argument(
|
|
64
|
+
"-r",
|
|
65
|
+
help="Recursively process all imported packages",
|
|
66
|
+
dest="recursive",
|
|
67
|
+
action="store_true",
|
|
68
|
+
)
|
|
69
|
+
parser_list_parts.add_argument(
|
|
70
|
+
"-r",
|
|
71
|
+
help="Recursively process all imported packages",
|
|
72
|
+
dest="recursive",
|
|
73
|
+
action="store_true",
|
|
74
|
+
)
|
|
75
|
+
parser_list_assemblies.add_argument(
|
|
76
|
+
"-r",
|
|
77
|
+
help="Recursively process all imported packages",
|
|
78
|
+
dest="recursive",
|
|
79
|
+
action="store_true",
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
parser_list_all.add_argument(
|
|
83
|
+
"-u",
|
|
84
|
+
help="Only process objects used by the given assembly or scene.",
|
|
85
|
+
dest="used_by",
|
|
86
|
+
type=str,
|
|
87
|
+
required=False,
|
|
88
|
+
)
|
|
89
|
+
parser_list_sketches.add_argument(
|
|
90
|
+
"-u",
|
|
91
|
+
help="Only process objects used by the given assembly or scene.",
|
|
92
|
+
dest="used_by",
|
|
93
|
+
type=str,
|
|
94
|
+
required=False,
|
|
95
|
+
)
|
|
96
|
+
parser_list_interfaces.add_argument(
|
|
97
|
+
"-u",
|
|
98
|
+
help="Only process objects used by the given assembly or scene.",
|
|
99
|
+
dest="used_by",
|
|
100
|
+
type=str,
|
|
101
|
+
required=False,
|
|
102
|
+
)
|
|
103
|
+
parser_list_mates.add_argument(
|
|
104
|
+
"-u",
|
|
105
|
+
help="Only process objects used by the given assembly or scene.",
|
|
106
|
+
dest="used_by",
|
|
107
|
+
type=str,
|
|
108
|
+
required=False,
|
|
109
|
+
)
|
|
110
|
+
parser_list_parts.add_argument(
|
|
111
|
+
"-u",
|
|
112
|
+
help="Only process objects used by the given assembly or scene.",
|
|
113
|
+
dest="used_by",
|
|
114
|
+
type=str,
|
|
115
|
+
required=False,
|
|
116
|
+
)
|
|
117
|
+
parser_list_assemblies.add_argument(
|
|
118
|
+
"-u",
|
|
119
|
+
help="Only process objects used by the given assembly or scene.",
|
|
120
|
+
dest="used_by",
|
|
121
|
+
type=str,
|
|
122
|
+
required=False,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
parser_list_sketches.add_argument(
|
|
126
|
+
"package",
|
|
127
|
+
help="Package to retrieve the object from",
|
|
128
|
+
type=str,
|
|
129
|
+
nargs="?",
|
|
130
|
+
)
|
|
131
|
+
parser_list_interfaces.add_argument(
|
|
132
|
+
"package",
|
|
133
|
+
help="Package to retrieve the object from",
|
|
134
|
+
type=str,
|
|
135
|
+
nargs="?",
|
|
136
|
+
)
|
|
137
|
+
parser_list_mates.add_argument(
|
|
138
|
+
"package",
|
|
139
|
+
help="Package to retrieve the object from",
|
|
140
|
+
type=str,
|
|
141
|
+
nargs="?",
|
|
142
|
+
)
|
|
143
|
+
parser_list_parts.add_argument(
|
|
144
|
+
"package",
|
|
145
|
+
help="Package to retrieve the object from",
|
|
146
|
+
type=str,
|
|
147
|
+
nargs="?",
|
|
148
|
+
)
|
|
149
|
+
parser_list_assemblies.add_argument(
|
|
150
|
+
"package",
|
|
151
|
+
help="Package to retrieve the object from",
|
|
152
|
+
type=str,
|
|
153
|
+
nargs="?",
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def cli_list(args, ctx):
|
|
158
|
+
pkg_count = 0
|
|
159
|
+
|
|
160
|
+
projects = ctx.get_all_packages()
|
|
161
|
+
projects = sorted(projects, key=lambda p: p["name"])
|
|
162
|
+
|
|
163
|
+
# TODO(clairbee): remove the following workaround after replacing 'print'
|
|
164
|
+
# with corresponding logging calls
|
|
165
|
+
time.sleep(2)
|
|
166
|
+
|
|
167
|
+
output = "PartCAD packages:\n"
|
|
168
|
+
for project in projects:
|
|
169
|
+
project_name = project["name"]
|
|
170
|
+
|
|
171
|
+
line = "\t%s" % project_name
|
|
172
|
+
padding_size = 60 - len(project_name)
|
|
173
|
+
if padding_size < 4:
|
|
174
|
+
padding_size = 4
|
|
175
|
+
line += " " * padding_size
|
|
176
|
+
line += "%s" % project["desc"]
|
|
177
|
+
output += line + "\n"
|
|
178
|
+
pkg_count = pkg_count + 1
|
|
179
|
+
|
|
180
|
+
if pkg_count < 1:
|
|
181
|
+
output += "\t<none>\n"
|
|
182
|
+
pc.logging.info(output)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def cli_list_sketches(args, ctx):
|
|
186
|
+
sketch_count = 0
|
|
187
|
+
sketch_kinds = 0
|
|
188
|
+
|
|
189
|
+
if args.used_by is not None:
|
|
190
|
+
pc.logging.info("Instantiating %s..." % args.used_by)
|
|
191
|
+
ctx.get_assembly(args.used_by)
|
|
192
|
+
else:
|
|
193
|
+
ctx.get_all_packages()
|
|
194
|
+
|
|
195
|
+
# TODO(clairbee): remove the following workaround after replacing 'print'
|
|
196
|
+
# with corresponding logging calls
|
|
197
|
+
time.sleep(2)
|
|
198
|
+
|
|
199
|
+
output = "PartCAD sketches:\n"
|
|
200
|
+
for project_name in ctx.projects:
|
|
201
|
+
if (
|
|
202
|
+
hasattr(args, "package")
|
|
203
|
+
and not args.package is None
|
|
204
|
+
and args.package != project_name
|
|
205
|
+
):
|
|
206
|
+
continue
|
|
207
|
+
|
|
208
|
+
if project_name != ctx.get_current_project_path() and (
|
|
209
|
+
not args.recursive
|
|
210
|
+
and hasattr(args, "package")
|
|
211
|
+
and args.package is None
|
|
212
|
+
):
|
|
213
|
+
continue
|
|
214
|
+
|
|
215
|
+
project = ctx.projects[project_name]
|
|
216
|
+
|
|
217
|
+
for sketch_name, sketch in project.sketches.items():
|
|
218
|
+
if args.used_by is not None and sketch.count == 0:
|
|
219
|
+
continue
|
|
220
|
+
|
|
221
|
+
line = "\t"
|
|
222
|
+
if args.recursive:
|
|
223
|
+
line += "%s" % project_name
|
|
224
|
+
line += " " + " " * (35 - len(project_name))
|
|
225
|
+
line += "%s" % sketch_name
|
|
226
|
+
if args.used_by is not None:
|
|
227
|
+
sketch = project.sketches[sketch_name]
|
|
228
|
+
line += "(%d)" % sketch.count
|
|
229
|
+
sketch_count = sketch_count + sketch.count
|
|
230
|
+
line += " " + " " * (35 - len(sketch_name))
|
|
231
|
+
|
|
232
|
+
desc = sketch.desc if sketch.desc is not None else ""
|
|
233
|
+
desc = desc.replace(
|
|
234
|
+
"\n", "\n" + " " * (80 if args.recursive else 44)
|
|
235
|
+
)
|
|
236
|
+
line += "%s" % desc
|
|
237
|
+
output += line + "\n"
|
|
238
|
+
sketch_kinds = sketch_kinds + 1
|
|
239
|
+
|
|
240
|
+
if sketch_kinds > 0:
|
|
241
|
+
if args.used_by is None:
|
|
242
|
+
output += "Total: %d\n" % sketch_kinds
|
|
243
|
+
else:
|
|
244
|
+
output += "Total: %d sketches of %d kinds\n" % (
|
|
245
|
+
sketch_count,
|
|
246
|
+
sketch_kinds,
|
|
247
|
+
)
|
|
248
|
+
else:
|
|
249
|
+
output += "\t<none>\n"
|
|
250
|
+
pc.logging.info(output)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def cli_list_interfaces(args, ctx):
|
|
254
|
+
interface_count = 0
|
|
255
|
+
interface_kinds = 0
|
|
256
|
+
|
|
257
|
+
if args.used_by is not None:
|
|
258
|
+
pc.logging.info("Instantiating %s..." % args.used_by)
|
|
259
|
+
ctx.get_assembly(args.used_by)
|
|
260
|
+
else:
|
|
261
|
+
ctx.get_all_packages()
|
|
262
|
+
|
|
263
|
+
# TODO(clairbee): remove the following workaround after replacing 'print'
|
|
264
|
+
# with corresponding logging calls
|
|
265
|
+
time.sleep(2)
|
|
266
|
+
|
|
267
|
+
output = "PartCAD interfaces:\n"
|
|
268
|
+
for project_name in ctx.projects:
|
|
269
|
+
if (
|
|
270
|
+
hasattr(args, "package")
|
|
271
|
+
and not args.package is None
|
|
272
|
+
and args.package != project_name
|
|
273
|
+
):
|
|
274
|
+
continue
|
|
275
|
+
|
|
276
|
+
if project_name != ctx.get_current_project_path() and (
|
|
277
|
+
not args.recursive
|
|
278
|
+
and hasattr(args, "package")
|
|
279
|
+
and args.package is None
|
|
280
|
+
):
|
|
281
|
+
continue
|
|
282
|
+
|
|
283
|
+
project = ctx.projects[project_name]
|
|
284
|
+
|
|
285
|
+
for interface_name, interface in project.interfaces.items():
|
|
286
|
+
if args.used_by is not None and interface.count == 0:
|
|
287
|
+
continue
|
|
288
|
+
|
|
289
|
+
line = "\t"
|
|
290
|
+
if args.recursive:
|
|
291
|
+
line += "%s" % project_name
|
|
292
|
+
line += " " + " " * (35 - len(project_name))
|
|
293
|
+
line += "%s" % interface_name
|
|
294
|
+
if args.used_by is not None:
|
|
295
|
+
interface = project.get_interface(interface_name)
|
|
296
|
+
line += "(%d)" % interface.count
|
|
297
|
+
interface_count = interface_count + interface.count
|
|
298
|
+
line += " " + " " * (35 - len(interface_name))
|
|
299
|
+
|
|
300
|
+
desc = interface.desc if interface.desc is not None else ""
|
|
301
|
+
desc = desc.replace(
|
|
302
|
+
"\n", "\n" + " " * (80 if args.recursive else 44)
|
|
303
|
+
)
|
|
304
|
+
line += "%s" % desc
|
|
305
|
+
output += line + "\n"
|
|
306
|
+
interface_kinds = interface_kinds + 1
|
|
307
|
+
|
|
308
|
+
if interface_kinds > 0:
|
|
309
|
+
if args.used_by is None:
|
|
310
|
+
output += "Total: %d\n" % interface_kinds
|
|
311
|
+
else:
|
|
312
|
+
output += "Total: %d interfaces of %d kinds\n" % (
|
|
313
|
+
interface_count,
|
|
314
|
+
interface_kinds,
|
|
315
|
+
)
|
|
316
|
+
else:
|
|
317
|
+
output += "\t<none>\n"
|
|
318
|
+
pc.logging.info(output)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def cli_list_mates(args, ctx):
|
|
322
|
+
mating_kinds = 0
|
|
323
|
+
|
|
324
|
+
if args.used_by is not None:
|
|
325
|
+
pc.logging.info("Instantiating %s..." % args.used_by)
|
|
326
|
+
ctx.get_assembly(args.used_by)
|
|
327
|
+
else:
|
|
328
|
+
ctx.get_all_packages()
|
|
329
|
+
|
|
330
|
+
# TODO(clairbee): remove the following workaround after replacing 'print'
|
|
331
|
+
# with corresponding logging calls
|
|
332
|
+
time.sleep(2)
|
|
333
|
+
|
|
334
|
+
output = "PartCAD mating interfaces:\n"
|
|
335
|
+
for source_interface_name in ctx.mates:
|
|
336
|
+
source_package_name = source_interface_name.split(":")[0]
|
|
337
|
+
short_source_interface_name = source_interface_name.split(":")[1]
|
|
338
|
+
|
|
339
|
+
for target_interface_name in ctx.mates[source_interface_name]:
|
|
340
|
+
target_package_name = target_interface_name.split(":")[0]
|
|
341
|
+
short_target_interface_name = target_interface_name.split(":")[1]
|
|
342
|
+
|
|
343
|
+
mating = ctx.mates[source_interface_name][target_interface_name]
|
|
344
|
+
|
|
345
|
+
if (
|
|
346
|
+
hasattr(args, "package")
|
|
347
|
+
and not args.package is None
|
|
348
|
+
and args.package != source_package_name
|
|
349
|
+
and args.package != target_package_name
|
|
350
|
+
):
|
|
351
|
+
continue
|
|
352
|
+
|
|
353
|
+
if (
|
|
354
|
+
source_package_name != ctx.get_current_project_path()
|
|
355
|
+
and target_package_name != ctx.get_current_project_path()
|
|
356
|
+
and not args.recursive
|
|
357
|
+
and hasattr(args, "package")
|
|
358
|
+
and args.package is None
|
|
359
|
+
):
|
|
360
|
+
continue
|
|
361
|
+
|
|
362
|
+
# source_project = ctx.projects[source_package_name]
|
|
363
|
+
# target_project = ctx.projects[target_package_name]
|
|
364
|
+
|
|
365
|
+
# source_interface = source_project.get_interface(
|
|
366
|
+
# short_source_interface_name
|
|
367
|
+
# )
|
|
368
|
+
# target_interface = target_project.get_interface(
|
|
369
|
+
# short_target_interface_name
|
|
370
|
+
# )
|
|
371
|
+
|
|
372
|
+
if args.used_by is not None and mating.count == 0:
|
|
373
|
+
continue
|
|
374
|
+
|
|
375
|
+
line = "\t"
|
|
376
|
+
line += "%s" % source_interface_name
|
|
377
|
+
line += " " + " " * (35 - len(source_interface_name))
|
|
378
|
+
line += "%s" % target_interface_name
|
|
379
|
+
line += " " + " " * (35 - len(target_interface_name))
|
|
380
|
+
|
|
381
|
+
desc = mating.desc if mating.desc is not None else ""
|
|
382
|
+
desc = desc.replace("\n", "\n\t" + " " * 72)
|
|
383
|
+
line += "%s" % desc
|
|
384
|
+
output += line + "\n"
|
|
385
|
+
mating_kinds = mating_kinds + 1
|
|
386
|
+
|
|
387
|
+
if mating_kinds > 0:
|
|
388
|
+
output += "Total: %d mating interfaces\n" % (mating_kinds,)
|
|
389
|
+
else:
|
|
390
|
+
output += "\t<none>\n"
|
|
391
|
+
pc.logging.info(output)
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
def cli_list_parts(args, ctx):
|
|
395
|
+
part_count = 0
|
|
396
|
+
part_kinds = 0
|
|
397
|
+
|
|
398
|
+
if args.used_by is not None:
|
|
399
|
+
pc.logging.info("Instantiating %s..." % args.used_by)
|
|
400
|
+
ctx.get_assembly(args.used_by)
|
|
401
|
+
else:
|
|
402
|
+
ctx.get_all_packages()
|
|
403
|
+
|
|
404
|
+
# TODO(clairbee): remove the following workaround after replacing 'print'
|
|
405
|
+
# with corresponding logging calls
|
|
406
|
+
time.sleep(2)
|
|
407
|
+
|
|
408
|
+
output = "PartCAD parts:\n"
|
|
409
|
+
for project_name in ctx.projects:
|
|
410
|
+
if (
|
|
411
|
+
hasattr(args, "package")
|
|
412
|
+
and not args.package is None
|
|
413
|
+
and args.package != project_name
|
|
414
|
+
):
|
|
415
|
+
continue
|
|
416
|
+
|
|
417
|
+
if project_name != ctx.get_current_project_path() and (
|
|
418
|
+
not args.recursive
|
|
419
|
+
and hasattr(args, "package")
|
|
420
|
+
and args.package is None
|
|
421
|
+
):
|
|
422
|
+
continue
|
|
423
|
+
|
|
424
|
+
project = ctx.projects[project_name]
|
|
425
|
+
|
|
426
|
+
for part_name, part in project.parts.items():
|
|
427
|
+
if args.used_by is not None and part.count == 0:
|
|
428
|
+
continue
|
|
429
|
+
|
|
430
|
+
line = "\t"
|
|
431
|
+
if args.recursive:
|
|
432
|
+
line += "%s" % project_name
|
|
433
|
+
line += " " + " " * (35 - len(project_name))
|
|
434
|
+
line += "%s" % part_name
|
|
435
|
+
if args.used_by is not None:
|
|
436
|
+
part = project.parts[part_name]
|
|
437
|
+
line += "(%d)" % part.count
|
|
438
|
+
part_count = part_count + part.count
|
|
439
|
+
line += " " + " " * (35 - len(part_name))
|
|
440
|
+
|
|
441
|
+
desc = part.desc if part.desc is not None else ""
|
|
442
|
+
desc = desc.replace(
|
|
443
|
+
"\n", "\n" + " " * (80 if args.recursive else 44)
|
|
444
|
+
)
|
|
445
|
+
line += "%s" % desc
|
|
446
|
+
output += line + "\n"
|
|
447
|
+
part_kinds = part_kinds + 1
|
|
448
|
+
|
|
449
|
+
if part_kinds > 0:
|
|
450
|
+
if args.used_by is None:
|
|
451
|
+
output += "Total: %d\n" % part_kinds
|
|
452
|
+
else:
|
|
453
|
+
output += "Total: %d parts of %d kinds\n" % (part_count, part_kinds)
|
|
454
|
+
else:
|
|
455
|
+
output += "\t<none>\n"
|
|
456
|
+
pc.logging.info(output)
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
def cli_list_assemblies(args, ctx):
|
|
460
|
+
assy_count = 0
|
|
461
|
+
assy_kinds = 0
|
|
462
|
+
|
|
463
|
+
if args.used_by is not None:
|
|
464
|
+
print("Instantiating %s..." % args.used_by)
|
|
465
|
+
# TODO(clairbee): do not call it twice in 'list-all'
|
|
466
|
+
ctx.get_assembly(args.used_by)
|
|
467
|
+
else:
|
|
468
|
+
ctx.get_all_packages()
|
|
469
|
+
|
|
470
|
+
# TODO(clairbee): remove the following workaround after replacing 'print'
|
|
471
|
+
# with corresponding logging calls
|
|
472
|
+
time.sleep(2)
|
|
473
|
+
|
|
474
|
+
output = "PartCAD assemblies:\n"
|
|
475
|
+
for project_name in ctx.projects:
|
|
476
|
+
if (
|
|
477
|
+
hasattr(args, "package")
|
|
478
|
+
and not args.package is None
|
|
479
|
+
and args.package != project_name
|
|
480
|
+
):
|
|
481
|
+
continue
|
|
482
|
+
|
|
483
|
+
if project_name != ctx.get_current_project_path() and (
|
|
484
|
+
not args.recursive
|
|
485
|
+
and hasattr(args, "package")
|
|
486
|
+
and args.package is None
|
|
487
|
+
):
|
|
488
|
+
continue
|
|
489
|
+
|
|
490
|
+
project = ctx.projects[project_name]
|
|
491
|
+
|
|
492
|
+
for assy_name, assy in project.assemblies.items():
|
|
493
|
+
if args.used_by is not None and assy.count == 0:
|
|
494
|
+
continue
|
|
495
|
+
|
|
496
|
+
line = "\t"
|
|
497
|
+
if args.recursive:
|
|
498
|
+
line += "%s" % project_name
|
|
499
|
+
line += " " + " " * (35 - len(project_name))
|
|
500
|
+
line += "%s" % assy_name
|
|
501
|
+
if args.used_by is not None:
|
|
502
|
+
assy = project.assemblies[assy_name]
|
|
503
|
+
line += "(%d)" % assy.count
|
|
504
|
+
assy_count = assy_count + assy.count
|
|
505
|
+
line += " " + " " * (35 - len(assy_name))
|
|
506
|
+
|
|
507
|
+
desc = assy.desc if assy.desc is not None else ""
|
|
508
|
+
desc = desc.replace(
|
|
509
|
+
"\n", "\n" + " " * (80 if args.recursive else 44)
|
|
510
|
+
)
|
|
511
|
+
line += "%s" % desc
|
|
512
|
+
output += line + "\n"
|
|
513
|
+
assy_kinds = assy_kinds + 1
|
|
514
|
+
|
|
515
|
+
if assy_kinds > 0:
|
|
516
|
+
if args.used_by is None:
|
|
517
|
+
output += "Total: %d\n" % assy_kinds
|
|
518
|
+
else:
|
|
519
|
+
output += "Total: %d assemblies of %d kinds\n" % (
|
|
520
|
+
assy_count,
|
|
521
|
+
assy_kinds,
|
|
522
|
+
)
|
|
523
|
+
else:
|
|
524
|
+
output += "\t<none>\n"
|
|
525
|
+
pc.logging.info(output)
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import os
|
|
11
11
|
import threading
|
|
12
12
|
|
|
13
|
+
from partcad import __version__ as version
|
|
13
14
|
import partcad.logging as pc_logging
|
|
14
15
|
import partcad.user_config as user_config
|
|
15
16
|
|
|
@@ -37,6 +38,8 @@ def get_size(start_path="."):
|
|
|
37
38
|
|
|
38
39
|
def cli_status(args):
|
|
39
40
|
with pc_logging.Process("Status", "this"):
|
|
41
|
+
pc_logging.info("PartCAD version: %s" % version)
|
|
42
|
+
|
|
40
43
|
path = user_config.internal_state_dir
|
|
41
44
|
pc_logging.info("Internal data storage location: %s" % path)
|
|
42
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: partcad-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Summary: Command-line interface to PartCAD
|
|
5
5
|
Author-email: Roman Kuzmenko <openvmp@proton.me>
|
|
6
6
|
Maintainer-email: Roman Kuzmenko <openvmp@proton.me>
|
|
@@ -12,7 +12,7 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Requires-Python: >=3.10
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
|
-
Requires-Dist: partcad==0.
|
|
15
|
+
Requires-Dist: partcad==0.6.2
|
|
16
16
|
Requires-Dist: renderlab
|
|
17
17
|
Requires-Dist: rlPyCairo
|
|
18
18
|
Requires-Dist: svglib
|
|
@@ -30,14 +30,22 @@ Requires-Dist: ocp_vscode
|
|
|
30
30
|
|
|
31
31
|
PartCAD is the first package manager for CAD models
|
|
32
32
|
and a framework for managing assemblies.
|
|
33
|
-
It
|
|
33
|
+
It aims to complement Git with everything necessary to substitute
|
|
34
34
|
commercial Product Lifecycle Management (PLM) tools.
|
|
35
35
|
|
|
36
36
|
PartCAD maintains information about mechanical parts and
|
|
37
37
|
how they come together to form larger assemblies.
|
|
38
|
-
The same parts
|
|
38
|
+
The same parts can be reused in multiple assemblies and multiple projects.
|
|
39
39
|
And all of that is supercharged by the ultimate versioning and collaboration features of Git.
|
|
40
40
|
|
|
41
|
+
PartCAD features include:
|
|
42
|
+
|
|
43
|
+
- 3D part models using STEP, STL and 3MF files
|
|
44
|
+
- 3D part models using CadQuery, build123d and OpenSCAD scripting languages (including AI-generated: Gemini and GPT)
|
|
45
|
+
- 2D blueprints using DXF, build123d and SVG files
|
|
46
|
+
- Fully featured object-oriented approach to maintain part interfaces and mating information (with multiple class inheritance etc)
|
|
47
|
+
- Live preview of 3D models while coding in VS Code
|
|
48
|
+
|
|
41
49
|
Find [more documentation here](https://partcad.readthedocs.io/en/latest/?badge=latest) and visit [our website](https://partcad.org/).
|
|
42
50
|
|
|
43
51
|
## Installation
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# OpenVMP, 2023
|
|
3
|
-
#
|
|
4
|
-
# Author: Roman Kuzmenko
|
|
5
|
-
# Created: 2023-12-23
|
|
6
|
-
#
|
|
7
|
-
# Licensed under Apache License, Version 2.0.
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
import time
|
|
11
|
-
|
|
12
|
-
import partcad as pc
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def cli_help_list(subparsers):
|
|
16
|
-
parser_list = subparsers.add_parser(
|
|
17
|
-
"list",
|
|
18
|
-
help="List imported packages",
|
|
19
|
-
)
|
|
20
|
-
parser_list_all = subparsers.add_parser(
|
|
21
|
-
"list-all",
|
|
22
|
-
help="List available parts, assemblies and scenes",
|
|
23
|
-
)
|
|
24
|
-
parser_list_parts = subparsers.add_parser(
|
|
25
|
-
"list-parts",
|
|
26
|
-
help="List available parts",
|
|
27
|
-
)
|
|
28
|
-
parser_list_assemblies = subparsers.add_parser(
|
|
29
|
-
"list-assemblies",
|
|
30
|
-
help="List available assemblies",
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
parser_list_all.add_argument(
|
|
34
|
-
"-r",
|
|
35
|
-
help="Recursively process all imported packages",
|
|
36
|
-
dest="recursive",
|
|
37
|
-
action="store_true",
|
|
38
|
-
)
|
|
39
|
-
parser_list_parts.add_argument(
|
|
40
|
-
"-r",
|
|
41
|
-
help="Recursively process all imported packages",
|
|
42
|
-
dest="recursive",
|
|
43
|
-
action="store_true",
|
|
44
|
-
)
|
|
45
|
-
parser_list_assemblies.add_argument(
|
|
46
|
-
"-r",
|
|
47
|
-
help="Recursively process all imported packages",
|
|
48
|
-
dest="recursive",
|
|
49
|
-
action="store_true",
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
parser_list_all.add_argument(
|
|
53
|
-
"-u",
|
|
54
|
-
help="Only process objects used by the given assembly or scene.",
|
|
55
|
-
dest="used_by",
|
|
56
|
-
type=str,
|
|
57
|
-
required=False,
|
|
58
|
-
)
|
|
59
|
-
parser_list_parts.add_argument(
|
|
60
|
-
"-u",
|
|
61
|
-
help="Only process objects used by the given assembly or scene.",
|
|
62
|
-
dest="used_by",
|
|
63
|
-
type=str,
|
|
64
|
-
required=False,
|
|
65
|
-
)
|
|
66
|
-
parser_list_assemblies.add_argument(
|
|
67
|
-
"-u",
|
|
68
|
-
help="Only process objects used by the given assembly or scene.",
|
|
69
|
-
dest="used_by",
|
|
70
|
-
type=str,
|
|
71
|
-
required=False,
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
parser_list_parts.add_argument(
|
|
75
|
-
"package",
|
|
76
|
-
help="Package to retrieve the object from",
|
|
77
|
-
type=str,
|
|
78
|
-
nargs="?",
|
|
79
|
-
)
|
|
80
|
-
parser_list_assemblies.add_argument(
|
|
81
|
-
"package",
|
|
82
|
-
help="Package to retrieve the object from",
|
|
83
|
-
type=str,
|
|
84
|
-
nargs="?",
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def cli_list(args, ctx):
|
|
89
|
-
pkg_count = 0
|
|
90
|
-
|
|
91
|
-
projects = ctx.get_all_packages()
|
|
92
|
-
projects = sorted(projects, key=lambda p: p["name"])
|
|
93
|
-
|
|
94
|
-
# TODO(clairbee): remove the following workaround after replacing 'print'
|
|
95
|
-
# with corresponding logging calls
|
|
96
|
-
time.sleep(2)
|
|
97
|
-
|
|
98
|
-
output = "PartCAD packages:\n"
|
|
99
|
-
for project in projects:
|
|
100
|
-
project_name = project["name"]
|
|
101
|
-
|
|
102
|
-
line = "\t%s" % project_name
|
|
103
|
-
padding_size = 60 - len(project_name)
|
|
104
|
-
if padding_size < 4:
|
|
105
|
-
padding_size = 4
|
|
106
|
-
line += " " * padding_size
|
|
107
|
-
line += "%s" % project["desc"]
|
|
108
|
-
output += line + "\n"
|
|
109
|
-
pkg_count = pkg_count + 1
|
|
110
|
-
|
|
111
|
-
if pkg_count < 1:
|
|
112
|
-
output += "\t<none>\n"
|
|
113
|
-
pc.logging.info(output)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def cli_list_parts(args, ctx):
|
|
117
|
-
part_count = 0
|
|
118
|
-
part_kinds = 0
|
|
119
|
-
|
|
120
|
-
if args.used_by is not None:
|
|
121
|
-
pc.logging.info("Instantiating %s..." % args.used_by)
|
|
122
|
-
ctx.get_assembly(args.used_by)
|
|
123
|
-
else:
|
|
124
|
-
ctx.get_all_packages()
|
|
125
|
-
|
|
126
|
-
# TODO(clairbee): remove the following workaround after replacing 'print'
|
|
127
|
-
# with corresponding logging calls
|
|
128
|
-
time.sleep(2)
|
|
129
|
-
|
|
130
|
-
output = "PartCAD parts:\n"
|
|
131
|
-
for project_name in ctx.projects:
|
|
132
|
-
if (
|
|
133
|
-
hasattr(args, "package")
|
|
134
|
-
and not args.package is None
|
|
135
|
-
and args.package != project_name
|
|
136
|
-
):
|
|
137
|
-
continue
|
|
138
|
-
|
|
139
|
-
if project_name != ctx.get_current_project_path() and (
|
|
140
|
-
not args.recursive
|
|
141
|
-
and hasattr(args, "package")
|
|
142
|
-
and args.package is None
|
|
143
|
-
):
|
|
144
|
-
continue
|
|
145
|
-
if project_name.startswith("partcad-"):
|
|
146
|
-
continue
|
|
147
|
-
project = ctx.projects[project_name]
|
|
148
|
-
|
|
149
|
-
for part_name, part in project.parts.items():
|
|
150
|
-
if args.used_by is not None and part.count == 0:
|
|
151
|
-
continue
|
|
152
|
-
|
|
153
|
-
line = "\t"
|
|
154
|
-
if args.recursive:
|
|
155
|
-
line += "%s" % project_name
|
|
156
|
-
line += " " + " " * (35 - len(project_name))
|
|
157
|
-
line += "%s" % part_name
|
|
158
|
-
if args.used_by is not None:
|
|
159
|
-
part = project.parts[part_name]
|
|
160
|
-
line += "(%d)" % part.count
|
|
161
|
-
part_count = part_count + part.count
|
|
162
|
-
line += " " + " " * (35 - len(part_name))
|
|
163
|
-
|
|
164
|
-
desc = part.desc
|
|
165
|
-
desc = desc.replace("\n", "\n" + " " * 44)
|
|
166
|
-
line += "%s" % desc
|
|
167
|
-
output += line + "\n"
|
|
168
|
-
part_kinds = part_kinds + 1
|
|
169
|
-
|
|
170
|
-
if part_kinds > 0:
|
|
171
|
-
if args.used_by is None:
|
|
172
|
-
output += "Total: %d\n" % part_kinds
|
|
173
|
-
else:
|
|
174
|
-
output += "Total: %d parts of %d kinds\n" % (part_count, part_kinds)
|
|
175
|
-
else:
|
|
176
|
-
output += "\t<none>\n"
|
|
177
|
-
pc.logging.info(output)
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
def cli_list_assemblies(args, ctx):
|
|
181
|
-
assy_count = 0
|
|
182
|
-
assy_kinds = 0
|
|
183
|
-
|
|
184
|
-
if args.used_by is not None:
|
|
185
|
-
print("Instantiating %s..." % args.used_by)
|
|
186
|
-
# TODO(clairbee): do not call it twice in 'list-all'
|
|
187
|
-
ctx.get_assembly(args.used_by)
|
|
188
|
-
else:
|
|
189
|
-
ctx.get_all_packages()
|
|
190
|
-
|
|
191
|
-
# TODO(clairbee): remove the following workaround after replacing 'print'
|
|
192
|
-
# with corresponding logging calls
|
|
193
|
-
time.sleep(2)
|
|
194
|
-
|
|
195
|
-
output = "PartCAD assemblies:\n"
|
|
196
|
-
for project_name in ctx.projects:
|
|
197
|
-
if (
|
|
198
|
-
hasattr(args, "package")
|
|
199
|
-
and not args.package is None
|
|
200
|
-
and args.package != project_name
|
|
201
|
-
):
|
|
202
|
-
continue
|
|
203
|
-
|
|
204
|
-
if project_name != ctx.get_current_project_path() and (
|
|
205
|
-
not args.recursive
|
|
206
|
-
and hasattr(args, "package")
|
|
207
|
-
and args.package is None
|
|
208
|
-
):
|
|
209
|
-
continue
|
|
210
|
-
if project_name.startswith("partcad-"):
|
|
211
|
-
continue
|
|
212
|
-
project = ctx.projects[project_name]
|
|
213
|
-
|
|
214
|
-
for assy_name, assy in project.assemblies.items():
|
|
215
|
-
if args.used_by is not None and assy.count == 0:
|
|
216
|
-
continue
|
|
217
|
-
|
|
218
|
-
line = "\t"
|
|
219
|
-
if args.recursive:
|
|
220
|
-
line += "%s" % project_name
|
|
221
|
-
line += " " + " " * (35 - len(project_name))
|
|
222
|
-
line += "%s" % assy_name
|
|
223
|
-
if args.used_by is not None:
|
|
224
|
-
assy = project.assemblies[assy_name]
|
|
225
|
-
line += "(%d)" % assy.count
|
|
226
|
-
assy_count = assy_count + assy.count
|
|
227
|
-
line += " " + " " * (35 - len(assy_name))
|
|
228
|
-
|
|
229
|
-
desc = assy.desc
|
|
230
|
-
desc = desc.replace("\n", "\n" + " " * 44)
|
|
231
|
-
line += "%s" % desc
|
|
232
|
-
output += line + "\n"
|
|
233
|
-
assy_kinds = assy_kinds + 1
|
|
234
|
-
|
|
235
|
-
if assy_kinds > 0:
|
|
236
|
-
if args.used_by is None:
|
|
237
|
-
output += "Total: %d\n" % assy_kinds
|
|
238
|
-
else:
|
|
239
|
-
output += "Total: %d assemblies of %d kinds\n" % (
|
|
240
|
-
assy_count,
|
|
241
|
-
assy_kinds,
|
|
242
|
-
)
|
|
243
|
-
else:
|
|
244
|
-
output += "\t<none>\n"
|
|
245
|
-
pc.logging.info(output)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|