ciel 0.21.0.dev0__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.
ciel/manage.py ADDED
@@ -0,0 +1,355 @@
1
+ # Copyright 2022-2023 Efabless Corporation
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ import io
15
+ import os
16
+ import shutil
17
+ import tarfile
18
+ import tempfile
19
+ import warnings
20
+ from typing import Iterable, List, Optional, Union
21
+
22
+ import rich
23
+ import httpx
24
+ import rich.tree
25
+ import rich.progress
26
+ import zstandard as zstd
27
+ from rich.console import Console
28
+
29
+ from .build.git_multi_clone import mkdirp
30
+ from .github import GitHubSession
31
+ from .common import (
32
+ Version,
33
+ get_versions_dir,
34
+ get_cielo_dir,
35
+ )
36
+ from .build import build, push
37
+ from .families import Family
38
+
39
+
40
+ class VersionNotFound(Exception):
41
+ pass
42
+
43
+
44
+ def print_installed_list(
45
+ pdk_root: str,
46
+ pdk: str,
47
+ *,
48
+ console: Console,
49
+ installed_list: List[Version],
50
+ session: Optional[GitHubSession] = None,
51
+ ):
52
+ if len(installed_list) == 0:
53
+ console.print("[red]No PDKs installed.")
54
+ return
55
+
56
+ versions = installed_list
57
+
58
+ try:
59
+ all_remote_versions = Version._from_github(session)
60
+ remote_versions = all_remote_versions.get(pdk) or []
61
+ remote_version_dict = {rv.name: rv for rv in remote_versions}
62
+ for installed in installed_list:
63
+ remote_version = remote_version_dict.get(installed.name)
64
+ if remote_version is not None:
65
+ installed.commit_date = remote_version.commit_date
66
+ installed.upload_date = remote_version.upload_date
67
+ versions.sort(reverse=True)
68
+ except httpx.HTTPError:
69
+ console.print(
70
+ "[red]Failed to connect to GitHub. Date information may be unavailable."
71
+ )
72
+
73
+ versions_dir = get_versions_dir(pdk_root, pdk)
74
+ tree = rich.tree.Tree(f"In {versions_dir}:")
75
+ for installed in versions:
76
+ day: Optional[str] = None
77
+ if installed.commit_date is not None:
78
+ day = installed.commit_date.strftime("%Y.%m.%d")
79
+ desc = f"{installed.name}"
80
+ if day is not None:
81
+ desc += f" ({day})"
82
+ if installed.is_current(pdk_root):
83
+ tree.add(f"[green][bold]{desc} (enabled)")
84
+ else:
85
+ tree.add(desc)
86
+ console.print(tree)
87
+
88
+
89
+ def print_remote_list(
90
+ pdk_root: str,
91
+ pdk: str,
92
+ console: Console,
93
+ pdk_list: List[Version],
94
+ ):
95
+ installed_list = Version.get_all_installed(pdk_root, pdk)
96
+
97
+ tree = rich.tree.Tree(f"Pre-built {pdk} PDK versions")
98
+ for remote_version in pdk_list:
99
+ name = remote_version.name
100
+ assert (
101
+ remote_version.commit_date is not None
102
+ ), f"Remote version {name} has no commit date"
103
+ day = remote_version.commit_date.strftime("%Y.%m.%d")
104
+ desc = f"[green]{name} ({day})"
105
+ if remote_version.prerelease:
106
+ desc = f"[red]PRE-RELEASE {desc}"
107
+ if remote_version.is_current(pdk_root):
108
+ tree.add(f"[bold]{desc} (enabled)")
109
+ elif name in installed_list:
110
+ tree.add(f"{desc} (installed)")
111
+ else:
112
+ tree.add(desc)
113
+ console.print(tree)
114
+
115
+
116
+ def fetch(
117
+ pdk_root: str,
118
+ pdk: str,
119
+ version: str,
120
+ *,
121
+ build_if_not_found=False,
122
+ also_push=False,
123
+ build_kwargs: dict = {},
124
+ push_kwargs: dict = {},
125
+ include_libraries: Optional[Iterable[str]] = None,
126
+ output: Union[Console, io.TextIOWrapper] = Console(),
127
+ session: Optional[GitHubSession] = None,
128
+ ) -> Version:
129
+ if session is None:
130
+ session = GitHubSession()
131
+
132
+ console = output
133
+ if not isinstance(console, Console):
134
+ console = Console(file=console)
135
+
136
+ version_object = Version(version, pdk)
137
+
138
+ version_directory = version_object.get_dir(pdk_root)
139
+
140
+ pdk_family = Family.by_name.get(pdk)
141
+ if pdk_family is None:
142
+ raise ValueError(f"Unsupported PDK family '{pdk}'.")
143
+
144
+ library_set = pdk_family.resolve_libraries(include_libraries)
145
+
146
+ variants = pdk_family.variants
147
+
148
+ common_missing = False
149
+ missing_libraries = set()
150
+ libs_tech = os.path.join(version_directory, variants[0], "libs.tech")
151
+ if not os.path.isdir(libs_tech):
152
+ common_missing = True
153
+
154
+ for library in library_set:
155
+ if library not in pdk_family.all_libraries:
156
+ raise RuntimeError(f"Unknown library {library}.")
157
+ found = False
158
+ for variant in variants:
159
+ lib_path = os.path.join(version_directory, variant, "libs.ref", library)
160
+ if os.path.isdir(lib_path):
161
+ found = True
162
+ if not found:
163
+ missing_libraries.add(library)
164
+
165
+ affected_paths = []
166
+ if len(missing_libraries) != 0 or common_missing:
167
+ if common_missing:
168
+ console.print(
169
+ f"Version {version} not found locally, attempting to download…"
170
+ )
171
+ affected_paths.append(version_directory)
172
+ else:
173
+ console.print(f"Libraries {missing_libraries} not found, downloading them…")
174
+ for variant in variants:
175
+ affected_paths.append(
176
+ os.path.join(version_directory, variant, "libs.ref", library)
177
+ )
178
+
179
+ tarball_paths = []
180
+ try:
181
+ release_link_list = version_object.get_release_links(
182
+ missing_libraries,
183
+ include_common=common_missing,
184
+ session=session,
185
+ )
186
+ tarball_directory = tempfile.TemporaryDirectory(suffix=".cielo")
187
+ for name, link in release_link_list:
188
+ tarball_path = os.path.join(tarball_directory.name, name)
189
+ tarball_paths.append(tarball_path)
190
+ with session.stream("get", link) as r, rich.progress.Progress(
191
+ console=console
192
+ ) as p:
193
+ total_str: Optional[str] = r.headers.get("Content-length", None)
194
+ total_int: Optional[int] = None
195
+ if total_str is not None:
196
+ total_int = int(total_str)
197
+ task = p.add_task(
198
+ f"Downloading {name}…",
199
+ total=total_int,
200
+ )
201
+ r.raise_for_status()
202
+ with open(tarball_path, "wb") as f:
203
+ for chunk in r.iter_bytes(chunk_size=8192):
204
+ p.advance(task, advance=len(chunk))
205
+ f.write(chunk)
206
+
207
+ with console.status(f"Unpacking {name}…"):
208
+ stream = zstd.open(tarball_path, mode="rb")
209
+ with tarfile.TarFile(fileobj=stream, mode="r") as tf:
210
+ for file in tf:
211
+ if file.isdir():
212
+ continue
213
+ final_path = os.path.join(version_directory, file.name)
214
+ final_dir = os.path.dirname(final_path)
215
+ mkdirp(final_dir)
216
+ io = tf.extractfile(file)
217
+ if io is None:
218
+ raise IOError(
219
+ f"Failed to unpack file in {name}'s tarball: {file.name}."
220
+ )
221
+ with open(final_path, "wb") as f:
222
+ f.write(io.read())
223
+ except httpx.HTTPStatusError as e:
224
+ if e.response is not None and e.response.status_code == 404:
225
+ if not build_if_not_found:
226
+ raise RuntimeError(f"Version {version} not found remotely.")
227
+ console.print(
228
+ f"Version {version} not found remotely, attempting to build…"
229
+ )
230
+ build(
231
+ pdk_root=pdk_root,
232
+ pdk=pdk,
233
+ version=version,
234
+ **build_kwargs,
235
+ )
236
+ if also_push:
237
+ if push_kwargs["push_libraries"] is None:
238
+ push_kwargs["push_libraries"] = Family.by_name[
239
+ pdk
240
+ ].default_includes.copy()
241
+ push(
242
+ pdk_root=pdk_root,
243
+ pdk=pdk,
244
+ version=version,
245
+ session=session,
246
+ **push_kwargs,
247
+ )
248
+ else:
249
+ if e.response is not None:
250
+ raise RuntimeError(
251
+ f"Failed to obtain {version} remotely: {e.response}."
252
+ )
253
+ else:
254
+ raise RuntimeError(f"Failed to request {version} from server: {e}.")
255
+ except KeyboardInterrupt as e:
256
+ console.print("Interrupted.")
257
+ for path in affected_paths:
258
+ shutil.rmtree(path, ignore_errors=True)
259
+ raise e from None
260
+ except Exception as e:
261
+ for path in affected_paths:
262
+ shutil.rmtree(path, ignore_errors=True)
263
+ raise e from None
264
+ finally:
265
+ for path in tarball_paths:
266
+ try:
267
+ os.unlink(path)
268
+ except FileNotFoundError:
269
+ pass
270
+
271
+ for variant in variants:
272
+ variant_install_path = os.path.join(version_directory, variant)
273
+ if not os.path.isdir(variant_install_path):
274
+ continue
275
+ variant_sources_file = os.path.join(variant_install_path, "SOURCES")
276
+ if not os.path.isfile(variant_sources_file):
277
+ with open(variant_sources_file, "w") as f:
278
+ print(f"{pdk_family.repo.name} {version}", file=f)
279
+
280
+ return Version(version, pdk)
281
+
282
+
283
+ def enable(
284
+ pdk_root: str,
285
+ pdk: str,
286
+ version: str,
287
+ *,
288
+ build_if_not_found: bool = False,
289
+ also_push: bool = False,
290
+ build_kwargs: dict = {},
291
+ push_kwargs: dict = {},
292
+ include_libraries: Optional[List[str]] = None,
293
+ output: Union[Console, io.TextIOWrapper] = Console(),
294
+ session: Optional[GitHubSession] = None,
295
+ ) -> Version:
296
+ if session is None:
297
+ session = GitHubSession()
298
+
299
+ console = output
300
+ if not isinstance(console, Console):
301
+ console = Console(file=console)
302
+
303
+ version_object = Version(version, pdk)
304
+ version_directory = version_object.get_dir(pdk_root)
305
+
306
+ pdk_family = Family.by_name.get(pdk)
307
+ if pdk_family is None:
308
+ raise ValueError(f"Unsupported PDK family '{pdk}'.")
309
+
310
+ variants = pdk_family.variants
311
+ version_paths = [os.path.join(version_directory, variant) for variant in variants]
312
+ final_paths = [os.path.join(pdk_root, variant) for variant in variants]
313
+
314
+ fetch(
315
+ pdk_root,
316
+ pdk,
317
+ version,
318
+ build_if_not_found=build_if_not_found,
319
+ also_push=also_push,
320
+ build_kwargs=build_kwargs,
321
+ push_kwargs=push_kwargs,
322
+ include_libraries=include_libraries,
323
+ output=output,
324
+ session=session,
325
+ )
326
+
327
+ current_file = os.path.join(get_cielo_dir(pdk_root, pdk), "current")
328
+ current_file_dir = os.path.dirname(current_file)
329
+ mkdirp(current_file_dir)
330
+
331
+ with console.status(f"Enabling version {version}…"):
332
+ for path in final_paths:
333
+ if os.path.exists(path):
334
+ if os.path.islink(path):
335
+ os.unlink(path)
336
+ else:
337
+ raise FileExistsError(
338
+ f"{path} exists, and not as a symlink. Remove it then try re-enabling."
339
+ )
340
+
341
+ for vpath, fpath in zip(version_paths, final_paths):
342
+ src = os.path.relpath(vpath, pdk_root)
343
+ if os.path.isdir(vpath):
344
+ os.symlink(src=src, dst=fpath)
345
+
346
+ with open(current_file, "w") as f:
347
+ f.write(version)
348
+
349
+ console.print(f"Version {version} enabled for the {pdk} PDK.")
350
+ return version_object
351
+
352
+
353
+ def get(*args, **kwargs):
354
+ warnings.warn("get() has been deprecated: use fetch()")
355
+ return fetch(*args, **kwargs)
ciel/py.typed ADDED
File without changes
@@ -0,0 +1,168 @@
1
+ Metadata-Version: 2.3
2
+ Name: ciel
3
+ Version: 0.21.0.dev0
4
+ Summary: An PDK builder/version manager for PDKs in the open_pdks format
5
+ License: Apache-2.0
6
+ Author: Efabless Corporation and Contributors
7
+ Author-email: donn@efabless.com
8
+ Requires-Python: >=3.8
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Operating System :: MacOS :: MacOS X
12
+ Classifier: Operating System :: POSIX :: Linux
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Requires-Dist: click (>=8,<9)
21
+ Requires-Dist: httpx (>=0.22.0,<0.29)
22
+ Requires-Dist: pcpp (>=1.2,<2)
23
+ Requires-Dist: pyyaml (>=5,<7)
24
+ Requires-Dist: rich (>=12,<14)
25
+ Requires-Dist: zstandard (>=0.19.0,<1)
26
+ Project-URL: Repository, https://github.com/donn/cielo
27
+ Description-Content-Type: text/markdown
28
+
29
+ <h1 align="center">☁️ Cielo</h1>
30
+ <p align="center">
31
+ <a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0"/></a>
32
+ <img src="https://github.com/efabless/cielo/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI Status" />
33
+ <a href="https://invite.skywater.tools"><img src="https://img.shields.io/badge/Community-Skywater%20PDK%20Slack-ff69b4?logo=slack" alt="Invite to the Skywater PDK Slack"/></a>
34
+ <a href="https://github.com/psf/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code Style: Black"/></a>
35
+ </p>
36
+
37
+ <p align="center">Cielo is a version manager (and builder) for builds of <a href="https://github.com/google/open-source-pdks">Google open-source PDKs</a> using <a href="https://github.com/rtimothyedwards/open_pdks">open_pdks</a>.</p>
38
+
39
+ # Requirements
40
+ * Python 3.8+ with PIP
41
+ * macOS or GNU/Linux
42
+
43
+ ## macOS
44
+ Get [Homebrew](https://brew.sh) then:
45
+
46
+ ```sh
47
+ brew install python3
48
+ ```
49
+
50
+ ## Debian and Ubuntu
51
+ Debian 11+ or Ubuntu 20.04+ is required.
52
+
53
+ ```sh
54
+ sudo apt-get update
55
+ sudo apt-get install python3 python3-pip xz-utils
56
+ ```
57
+
58
+ ## RHEL and Derivatives
59
+ RHEL 8+ or compatible operating system required.
60
+ ```sh
61
+ sudo yum install -y python3 python3-pip
62
+ ```
63
+
64
+
65
+ # Installation and Upgrades
66
+ ```sh
67
+ # To install (or upgrade)
68
+ python3 -m pip install --user --upgrade --no-cache-dir cielo
69
+
70
+ # To verify it works
71
+ cielo --version
72
+ ```
73
+
74
+ # About the builds
75
+ In its current inception, cielo supports builds of **sky130** and **gf180mcu** PDKs using [Open_PDKs](https://github.com/efabless/open_pdks), including the following libraries:
76
+
77
+ |sky130|gf180mcu|
78
+ |-|-|
79
+ |sky130_fd_io|gf180mcu_fd_io|
80
+ |sky130_fd_pr|gf180mcu_fd_pr|
81
+ |sky130_fd_sc_hd|gf180mcu_fd_sc_mcu7t5v0|
82
+ |sky130_fd_sc_hvl|gf180mcu_fd_sc_mcu9t5v0|
83
+ |sky130 sram modules|gf180mcu_fd_ip_sram|
84
+
85
+ All builds are identified by their **open_pdks** commit hash.
86
+
87
+ # Usage
88
+ Cielo requires a so-called **PDK Root**. This PDK root can be anywhere on your computer, but by default it's the folder `~/.cielo` in your home directory. If you have the variable `PDK_ROOT` set, cielo will use that instead. You can also manually override both values by supplying the `--pdk-root` commandline argument.
89
+
90
+ ## Listing All Available PDKs
91
+ To list all available pre-built PDKs hosted in this repository, you can just invoke `cielo ls-remote --pdk <PDK>`. If you omit the `--pdk` argument, `sky130` will be used as a default.
92
+
93
+ ```sh
94
+ $ cielo ls-remote --pdk sky130
95
+ Pre-built sky130 PDK versions
96
+ ├── 44a43c23c81b45b8e774ae7a84899a5a778b6b0b (2022.08.16) (enabled)
97
+ ├── e8294524e5f67c533c5d0c3afa0bcc5b2a5fa066 (2022.07.29) (installed)
98
+ ├── 41c0908b47130d5675ff8484255b43f66463a7d6 (2022.04.14) (installed)
99
+ ├── 660c6bdc8715dc7b3db95a1ce85392bbf2a2b195 (2022.04.08)
100
+ ├── 5890e791e37699239abedfd2a67e55162e25cd94 (2022.04.06)
101
+ ├── 8fe7f760ece2bb49b1c310e60243f0558977dae5 (2022.04.06)
102
+ └── 7519dfb04400f224f140749cda44ee7de6f5e095 (2022.02.10)
103
+
104
+ $ cielo ls-remote --pdk gf180mcu
105
+ Pre-built gf180mcu PDK versions
106
+ └── 120b0bd69c745825a0b8b76f364043a1cd08bb6a (2022.09.22)
107
+ ```
108
+
109
+ It includes a commit hash, which is the `open_pdks` version used to build this particular PDK, the date that this commit was created, and whether you already installed this PDK and/or if it is the currently enabled PDK.
110
+
111
+ ## Listing Installed PDKs
112
+ Typing `cielo ls --pdk <pdk>` in the terminal shows you your PDK Root and the PDKs you currently have installed. Again, if you omit the `--pdk` argument, `sky130` will be used as a default.
113
+
114
+ ```sh
115
+ $ cielo ls --pdk sky130
116
+ /home/test/cielo/sky130/versions
117
+ ├── 44a43c23c81b45b8e774ae7a84899a5a778b6b0b (2022.08.16) (enabled)
118
+ ├── e8294524e5f67c533c5d0c3afa0bcc5b2a5fa066 (2022.07.29)
119
+ └── 41c0908b47130d5675ff8484255b43f66463a7d6 (2022.04.14)
120
+ ```
121
+
122
+ (If you're not connected to the Internet, the release date of the commit will not be included.)
123
+
124
+
125
+ ## Downloading and Enabling PDKs
126
+ You can enable a particular sky130 PDK by invoking `cielo enable --pdk <pdk> <open_pdks commit hash>`. This will automatically download that particular version of the PDK, if found, and set it as your currently used PDK.
127
+
128
+ For example, to activate a build of sky130 using open_pdks `7519dfb04400f224f140749cda44ee7de6f5e095`, you invoke `cielo enable --pdk sky130 7519dfb04400f224f140749cda44ee7de6f5e095`, as shown below:
129
+
130
+ ```sh
131
+ $ cielo enable --pdk sky130 7519dfb04400f224f140749cda44ee7de6f5e095
132
+ Downloading pre-built tarball for 7519dfb04400f224f140749cda44ee7de6f5e095… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
133
+ Unpacking… ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
134
+ PDK version 7519dfb04400f224f140749cda44ee7de6f5e095 enabled.
135
+ ```
136
+
137
+ What's more is: if you're using a repository with a `tool_metadata.yml` file, such as [OpenLane](https://github.com/The-OpenROAD-Project/OpenLane) or [DFFRAM](https://github.com/Cloud-V/DFFRAM), you can just invoke `cielo enable --pdk sky130` without the commit hash and Cielo will automatically extract the version required by the utility. Once again, if you omit the `--pdk` argument, `sky130` will be used as a default.
138
+
139
+ ## Building PDKs
140
+ For special cases, you may have to build the PDK yourself, which Cielo does support.
141
+
142
+ You'll need Magic installed and in PATH. You can either do that manually or, if you have [Nix](https://nixos.org), invoke `nix shell github:efabless/openlane2#magic` before building.
143
+
144
+ You can invoke `cielo build --help` for more options. Be aware, the built PDK won't automatically be enabled and you'll have to `cielo enable` the appropriate version.
145
+
146
+ # License
147
+ The Apache License, version 2.0. See 'License'.
148
+
149
+
150
+ Cielo is based on [Volare](https://github.com/efabless/volare) by Efabless
151
+ Corporation:
152
+
153
+ ```
154
+ Copyright 2022-2025 Efabless Corporation
155
+
156
+ Licensed under the Apache License, Version 2.0 (the "License");
157
+ you may not use this file except in compliance with the License.
158
+ You may obtain a copy of the License at
159
+
160
+ http://www.apache.org/licenses/LICENSE-2.0
161
+
162
+ Unless required by applicable law or agreed to in writing, software
163
+ distributed under the License is distributed on an "AS IS" BASIS,
164
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
165
+ See the License for the specific language governing permissions and
166
+ limitations under the License.
167
+ ```
168
+
@@ -0,0 +1,19 @@
1
+ ciel/__init__.py,sha256=Ds7HveaY6MEuAefOAmZWUGZxlJbWmh0VNlI7iJdbi9U,858
2
+ ciel/__main__.py,sha256=2aVGdjzPJO2O1UjDEeOyWxyAw_nqjvT7BDReu24hJlE,12021
3
+ ciel/__version__.py,sha256=CiYOz2nsxhPOSiHi6nLpq-o6zdzLhvEVAG_58UzG5Xs,1510
4
+ ciel/build/__init__.py,sha256=0a8KRwBcwZRFgcsZcYYLJuUMAjMsIfDF-nGt_1LKr3s,7378
5
+ ciel/build/common.py,sha256=DAOaJVCyfgfBvPzhhLiYorRJoHqS4wQ5080VgGnd7Gg,3283
6
+ ciel/build/gf180mcu.py,sha256=J1c9EPFVJpqhibAzle_hiVYNx3gOduE3x4EUBBMWPZM,8775
7
+ ciel/build/git_multi_clone.py,sha256=lgjfZPN4KE9IJq4ph4xnst35hh4Rup16glhJtE8Srek,6902
8
+ ciel/build/ihp_sg13g2.py,sha256=zDIoSL4rKk4XUqjBUZuMFFcngc7FsjuAti7ibqj3zt4,4940
9
+ ciel/build/sky130.py,sha256=5scYrgKHpoTxkLmvxXEXkzfN8lVB60lI8R0iZaiT2RY,12047
10
+ ciel/click_common.py,sha256=YD7OYskwSWKfis7kndPTK32VgqiPmZ2QvSoZljqc6Fw,3741
11
+ ciel/common.py,sha256=tr-kIYvtjMpi9-spLQvlHm2r2eGJUXJFBDmFUwUpBK0,7913
12
+ ciel/families.py,sha256=4ZNvDUSEknlFJmyyFGE-jgd7hkXnKcA9qnH_6GyIiqk,3525
13
+ ciel/github.py,sha256=pFfmICJoTo188bp-3z7b2TLvKVmJC5PAd--ssC4pHSM,5111
14
+ ciel/manage.py,sha256=S90KZHvUBSpkeeFPq1rwK6YKo4jFcHizdeCri4I9LzM,12371
15
+ ciel/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ ciel-0.21.0.dev0.dist-info/METADATA,sha256=ZORoGjY1EgRuYKWu5NgB62rDlhrXCe9R8DE5gkbmoZw,7700
17
+ ciel-0.21.0.dev0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
18
+ ciel-0.21.0.dev0.dist-info/entry_points.txt,sha256=XDz2ZqV8nlrFh2qQ3uqZwFl9lw-mm-FRcEyMXMtYTGY,44
19
+ ciel-0.21.0.dev0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.1.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ cielo=cielo.__main__:cli
3
+