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/__init__.py +29 -0
- ciel/__main__.py +429 -0
- ciel/__version__.py +44 -0
- ciel/build/__init__.py +267 -0
- ciel/build/common.py +98 -0
- ciel/build/gf180mcu.py +263 -0
- ciel/build/git_multi_clone.py +220 -0
- ciel/build/ihp_sg13g2.py +148 -0
- ciel/build/sky130.py +358 -0
- ciel/click_common.py +119 -0
- ciel/common.py +256 -0
- ciel/families.py +119 -0
- ciel/github.py +184 -0
- ciel/manage.py +355 -0
- ciel/py.typed +0 -0
- ciel-0.21.0.dev0.dist-info/METADATA +168 -0
- ciel-0.21.0.dev0.dist-info/RECORD +19 -0
- ciel-0.21.0.dev0.dist-info/WHEEL +4 -0
- ciel-0.21.0.dev0.dist-info/entry_points.txt +3 -0
ciel/build/sky130.py
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
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 os
|
|
15
|
+
import io
|
|
16
|
+
import json
|
|
17
|
+
import venv
|
|
18
|
+
import shlex
|
|
19
|
+
import shutil
|
|
20
|
+
import subprocess
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
from typing import Optional, List, Tuple, Dict
|
|
23
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
24
|
+
|
|
25
|
+
import pcpp
|
|
26
|
+
from rich.console import Console
|
|
27
|
+
from rich.progress import Progress
|
|
28
|
+
|
|
29
|
+
from .git_multi_clone import GitMultiClone
|
|
30
|
+
from .common import patch_open_pdks
|
|
31
|
+
from ..families import Family
|
|
32
|
+
from ..github import opdks_repo
|
|
33
|
+
from ..common import (
|
|
34
|
+
Version,
|
|
35
|
+
get_cielo_dir,
|
|
36
|
+
mkdirp,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
MAGIC_DEFAULT_TAG = "085131b090cb511d785baf52a10cf6df8a657d44"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_open_pdks(
|
|
43
|
+
version, build_directory, jobs=1, repo_path=None
|
|
44
|
+
) -> Tuple[str, Optional[str], Optional[str]]:
|
|
45
|
+
try:
|
|
46
|
+
console = Console()
|
|
47
|
+
|
|
48
|
+
open_pdks_repo = None
|
|
49
|
+
if repo_path is None:
|
|
50
|
+
with Progress() as progress:
|
|
51
|
+
with ThreadPoolExecutor(max_workers=jobs) as executor:
|
|
52
|
+
gmc = GitMultiClone(build_directory, progress)
|
|
53
|
+
open_pdks_future = executor.submit(
|
|
54
|
+
GitMultiClone.clone,
|
|
55
|
+
gmc,
|
|
56
|
+
opdks_repo.link,
|
|
57
|
+
version,
|
|
58
|
+
default_branch="master",
|
|
59
|
+
)
|
|
60
|
+
open_pdks_repo = open_pdks_future.result()
|
|
61
|
+
repo_path = open_pdks_repo.path
|
|
62
|
+
|
|
63
|
+
console.log(f"Done fetching {open_pdks_repo.name}.")
|
|
64
|
+
else:
|
|
65
|
+
console.log(f"Using open_pdks at {repo_path} unaltered.")
|
|
66
|
+
|
|
67
|
+
patch_open_pdks(repo_path)
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
json_raw = open(f"{repo_path}/sky130/sky130.json").read()
|
|
71
|
+
cpp = pcpp.Preprocessor()
|
|
72
|
+
cpp.line_directive = None
|
|
73
|
+
cpp.parse(json_raw)
|
|
74
|
+
json_str = None
|
|
75
|
+
with io.StringIO() as sio:
|
|
76
|
+
cpp.write(sio)
|
|
77
|
+
json_str = sio.getvalue()
|
|
78
|
+
manifest = json.loads(json_str)
|
|
79
|
+
reference_commits = manifest["reference"]
|
|
80
|
+
print(f"Reference commits: {reference_commits}")
|
|
81
|
+
except FileNotFoundError:
|
|
82
|
+
console.log("Warning: Couldn't find open_pdks/sky130 JSON manifest.")
|
|
83
|
+
except json.JSONDecodeError:
|
|
84
|
+
console.log("Warning: Failed to parse open_pdks/sky130 JSON manifest..")
|
|
85
|
+
except KeyError:
|
|
86
|
+
console.log(
|
|
87
|
+
"Warning: Failed to extract reference commits from open_pdks/sky130 JSON manifest."
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return repo_path
|
|
91
|
+
|
|
92
|
+
except subprocess.CalledProcessError as e:
|
|
93
|
+
print(e)
|
|
94
|
+
print(e.stderr)
|
|
95
|
+
exit(-1)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def build_sky130_timing(build_directory, sky130_path, log_dir, jobs=1):
|
|
99
|
+
try:
|
|
100
|
+
console = Console()
|
|
101
|
+
sky130_submodules = (
|
|
102
|
+
subprocess.check_output(
|
|
103
|
+
["find", "./libraries", "-type", "d", "-name", "latest"],
|
|
104
|
+
stderr=subprocess.PIPE,
|
|
105
|
+
cwd=sky130_path,
|
|
106
|
+
)
|
|
107
|
+
.decode("utf8")
|
|
108
|
+
.strip()
|
|
109
|
+
.split("\n")
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
venv_path = os.path.join(build_directory, "venv")
|
|
113
|
+
|
|
114
|
+
with console.status("Building venv…"):
|
|
115
|
+
venv_builder = venv.EnvBuilder(with_pip=True)
|
|
116
|
+
venv_builder.create(venv_path)
|
|
117
|
+
console.log("Done building venv.")
|
|
118
|
+
|
|
119
|
+
with console.status("Installing python-skywater-pdk in venv…"), open(
|
|
120
|
+
f"{log_dir}/venv.log", "w"
|
|
121
|
+
) as out:
|
|
122
|
+
subprocess.check_call(
|
|
123
|
+
[
|
|
124
|
+
"bash",
|
|
125
|
+
"-c",
|
|
126
|
+
f"""
|
|
127
|
+
set -e
|
|
128
|
+
source {venv_path}/bin/activate
|
|
129
|
+
python3 -m pip install wheel
|
|
130
|
+
python3 -m pip install {os.path.join(sky130_path, 'scripts', 'python-skywater-pdk')}
|
|
131
|
+
""",
|
|
132
|
+
],
|
|
133
|
+
stdout=out,
|
|
134
|
+
stderr=out,
|
|
135
|
+
)
|
|
136
|
+
console.log("Done setting up venv.")
|
|
137
|
+
|
|
138
|
+
def do_submodule(submodule: str):
|
|
139
|
+
submodule_cleaned = submodule.strip("/.").replace("/", "_")
|
|
140
|
+
console.log(f"Generating timing files for {submodule}…")
|
|
141
|
+
with open(f"{log_dir}/timing.{submodule_cleaned}.log", "w") as out:
|
|
142
|
+
subprocess.check_call(
|
|
143
|
+
[
|
|
144
|
+
"bash",
|
|
145
|
+
"-c",
|
|
146
|
+
f"""
|
|
147
|
+
set -e
|
|
148
|
+
source {venv_path}/bin/activate
|
|
149
|
+
cd {sky130_path}
|
|
150
|
+
python3 -m skywater_pdk.liberty {submodule}
|
|
151
|
+
python3 -m skywater_pdk.liberty {submodule} all
|
|
152
|
+
python3 -m skywater_pdk.liberty {submodule} all --ccsnoise
|
|
153
|
+
""",
|
|
154
|
+
],
|
|
155
|
+
stdout=out,
|
|
156
|
+
stderr=out,
|
|
157
|
+
)
|
|
158
|
+
console.log(f"Done with {submodule}.")
|
|
159
|
+
|
|
160
|
+
with ThreadPoolExecutor(max_workers=jobs) as executor:
|
|
161
|
+
for submodule in sky130_submodules:
|
|
162
|
+
submodule_path = os.path.join(sky130_path, submodule)
|
|
163
|
+
if (
|
|
164
|
+
not os.path.exists(os.path.join(submodule_path, "cells"))
|
|
165
|
+
or "_sc" not in submodule
|
|
166
|
+
):
|
|
167
|
+
continue
|
|
168
|
+
executor.submit(
|
|
169
|
+
do_submodule,
|
|
170
|
+
submodule,
|
|
171
|
+
)
|
|
172
|
+
console.log("Created timing data.")
|
|
173
|
+
|
|
174
|
+
except subprocess.CalledProcessError as e:
|
|
175
|
+
print(e)
|
|
176
|
+
print(e.stderr)
|
|
177
|
+
exit(-1)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
LIB_FLAG_MAP = {
|
|
181
|
+
"sky130_fd_io": "--enable-io-sky130",
|
|
182
|
+
"sky130_fd_pr": "--enable-primitive-sky130",
|
|
183
|
+
"sky130_ml_xx_hd": "--enable-alpha-sky130",
|
|
184
|
+
"sky130_fd_sc_hd": "--enable-sc-hd-sky130",
|
|
185
|
+
"sky130_fd_sc_hdll": "--enable-sc-hdll-sky130",
|
|
186
|
+
"sky130_fd_sc_lp": "--enable-sc-lp-sky130",
|
|
187
|
+
"sky130_fd_sc_hvl": "--enable-sc-hvl-sky130",
|
|
188
|
+
"sky130_fd_sc_ls": "--enable-sc-ls-sky130",
|
|
189
|
+
"sky130_fd_sc_ms": "--enable-sc-ms-sky130",
|
|
190
|
+
"sky130_fd_sc_hs": "--enable-sc-hs-sky130",
|
|
191
|
+
"sky130_sram_macros": "--enable-sram-sky130",
|
|
192
|
+
"sky130_fd_pr_reram": "--enable-reram-sky130",
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def build_variants(
|
|
197
|
+
magic_bin,
|
|
198
|
+
build_directory,
|
|
199
|
+
open_pdks_path,
|
|
200
|
+
include_libraries,
|
|
201
|
+
log_dir,
|
|
202
|
+
jobs=1,
|
|
203
|
+
):
|
|
204
|
+
try:
|
|
205
|
+
pdk_root_abs = os.path.abspath(build_directory)
|
|
206
|
+
console = Console()
|
|
207
|
+
|
|
208
|
+
def run_sh(script, log_to):
|
|
209
|
+
output_file = open(log_to, "w")
|
|
210
|
+
output_file.write(script + "\n")
|
|
211
|
+
output_file.write("---\n")
|
|
212
|
+
output_file.flush()
|
|
213
|
+
try:
|
|
214
|
+
subprocess.check_call(
|
|
215
|
+
["sh", "-c", script],
|
|
216
|
+
cwd=open_pdks_path,
|
|
217
|
+
stdout=output_file,
|
|
218
|
+
stderr=output_file,
|
|
219
|
+
stdin=open(os.devnull),
|
|
220
|
+
)
|
|
221
|
+
except subprocess.CalledProcessError as e:
|
|
222
|
+
console.log(
|
|
223
|
+
f"An error occurred while building the PDK. Check {log_to} for more information."
|
|
224
|
+
)
|
|
225
|
+
raise e
|
|
226
|
+
|
|
227
|
+
magic_dirname = os.path.dirname(magic_bin)
|
|
228
|
+
library_flags = set([LIB_FLAG_MAP[library] for library in include_libraries])
|
|
229
|
+
library_flags_disable = set(
|
|
230
|
+
[
|
|
231
|
+
LIB_FLAG_MAP[library].replace("enable", "disable")
|
|
232
|
+
for library in LIB_FLAG_MAP
|
|
233
|
+
if library not in include_libraries
|
|
234
|
+
]
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
configuration_flags = ["--enable-sky130-pdk", "--with-reference"] + list(
|
|
238
|
+
library_flags.union(library_flags_disable)
|
|
239
|
+
)
|
|
240
|
+
console.log(f"Configuring with flags {shlex.join(configuration_flags)}")
|
|
241
|
+
|
|
242
|
+
with console.status("Configuring open_pdks…"):
|
|
243
|
+
run_sh(
|
|
244
|
+
f"""
|
|
245
|
+
set -e
|
|
246
|
+
export PATH="{magic_dirname}:$PATH"
|
|
247
|
+
./configure {shlex.join(configuration_flags)}
|
|
248
|
+
""",
|
|
249
|
+
log_to=os.path.join(log_dir, "config.log"),
|
|
250
|
+
)
|
|
251
|
+
console.log("Configured open_pdks.")
|
|
252
|
+
|
|
253
|
+
with console.status("Building variants using open_pdks…"):
|
|
254
|
+
run_sh(
|
|
255
|
+
f"""
|
|
256
|
+
set -e
|
|
257
|
+
export LC_ALL=en_US.UTF-8
|
|
258
|
+
export PATH="{magic_dirname}:$PATH"
|
|
259
|
+
make -j{jobs}
|
|
260
|
+
make 'SHARED_PDKS_PATH={pdk_root_abs}' install
|
|
261
|
+
""",
|
|
262
|
+
log_to=os.path.join(log_dir, "install.log"),
|
|
263
|
+
)
|
|
264
|
+
console.log("Built PDK variants.")
|
|
265
|
+
|
|
266
|
+
with console.status("Cleaning build artifacts…"):
|
|
267
|
+
run_sh(
|
|
268
|
+
"""
|
|
269
|
+
set -e
|
|
270
|
+
rm -rf sources
|
|
271
|
+
""",
|
|
272
|
+
log_to=os.path.join(log_dir, "clean.log"),
|
|
273
|
+
)
|
|
274
|
+
console.log("Cleaned build artifacts.")
|
|
275
|
+
|
|
276
|
+
console.log("Done.")
|
|
277
|
+
|
|
278
|
+
except subprocess.CalledProcessError as e:
|
|
279
|
+
print(e)
|
|
280
|
+
print(e.stderr)
|
|
281
|
+
exit(-1)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def install_sky130(build_directory, pdk_root, version):
|
|
285
|
+
console = Console()
|
|
286
|
+
with console.status("Adding build to list of installed versions…"):
|
|
287
|
+
version_directory = Version(version, "sky130").get_dir(pdk_root)
|
|
288
|
+
if (
|
|
289
|
+
os.path.exists(version_directory)
|
|
290
|
+
and len(os.listdir(version_directory)) != 0
|
|
291
|
+
):
|
|
292
|
+
backup_path = version_directory
|
|
293
|
+
it = 0
|
|
294
|
+
while os.path.exists(backup_path) and len(os.listdir(backup_path)) != 0:
|
|
295
|
+
it += 1
|
|
296
|
+
backup_path = Version(f"{version}.bk{it}", version).get_dir(pdk_root)
|
|
297
|
+
console.log(
|
|
298
|
+
f"Build already found at {version_directory}, moving to {backup_path}…"
|
|
299
|
+
)
|
|
300
|
+
shutil.move(version_directory, backup_path)
|
|
301
|
+
|
|
302
|
+
console.log("Copying…")
|
|
303
|
+
mkdirp(version_directory)
|
|
304
|
+
|
|
305
|
+
sky130_family = Family.by_name["sky130"]
|
|
306
|
+
|
|
307
|
+
for variant in sky130_family.variants:
|
|
308
|
+
variant_build_path = os.path.join(build_directory, variant)
|
|
309
|
+
variant_install_path = os.path.join(version_directory, variant)
|
|
310
|
+
if os.path.isdir(variant_build_path):
|
|
311
|
+
shutil.copytree(variant_build_path, variant_install_path)
|
|
312
|
+
|
|
313
|
+
console.log("Done.")
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def build(
|
|
317
|
+
pdk_root: str,
|
|
318
|
+
version: str,
|
|
319
|
+
jobs: int = 1,
|
|
320
|
+
clear_build_artifacts: bool = True,
|
|
321
|
+
include_libraries: Optional[List[str]] = None,
|
|
322
|
+
using_repos: Optional[Dict[str, str]] = None,
|
|
323
|
+
):
|
|
324
|
+
family = Family.by_name["sky130"]
|
|
325
|
+
library_set = family.resolve_libraries(include_libraries)
|
|
326
|
+
|
|
327
|
+
if using_repos is None:
|
|
328
|
+
using_repos = {}
|
|
329
|
+
|
|
330
|
+
build_directory = os.path.join(get_cielo_dir(pdk_root, "sky130"), "build", version)
|
|
331
|
+
timestamp = datetime.now().strftime("build_sky130-%Y-%m-%d-%H-%M-%S")
|
|
332
|
+
log_dir = os.path.join(build_directory, "logs", timestamp)
|
|
333
|
+
mkdirp(log_dir)
|
|
334
|
+
|
|
335
|
+
console = Console()
|
|
336
|
+
console.log(f"Logging to '{log_dir}'…")
|
|
337
|
+
|
|
338
|
+
open_pdks_path = get_open_pdks(
|
|
339
|
+
version, build_directory, jobs, using_repos.get("open_pdks")
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
magic_bin = shutil.which("magic")
|
|
343
|
+
if magic_bin is None:
|
|
344
|
+
print("Magic is either not installed or not in PATH.")
|
|
345
|
+
exit(-1)
|
|
346
|
+
|
|
347
|
+
build_variants(
|
|
348
|
+
magic_bin,
|
|
349
|
+
build_directory,
|
|
350
|
+
open_pdks_path,
|
|
351
|
+
library_set,
|
|
352
|
+
log_dir,
|
|
353
|
+
jobs,
|
|
354
|
+
),
|
|
355
|
+
install_sky130(build_directory, pdk_root, version)
|
|
356
|
+
|
|
357
|
+
if clear_build_artifacts:
|
|
358
|
+
shutil.rmtree(build_directory)
|
ciel/click_common.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
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 os
|
|
15
|
+
from functools import partial
|
|
16
|
+
from typing import Callable, Optional
|
|
17
|
+
|
|
18
|
+
import click
|
|
19
|
+
|
|
20
|
+
from .common import VOLARE_RESOLVED_HOME
|
|
21
|
+
from .github import volare_repo, GitHubSession
|
|
22
|
+
|
|
23
|
+
opt = partial(click.option, show_default=True)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def opt_pdk_root(function: Callable):
|
|
27
|
+
function = opt(
|
|
28
|
+
"--pdk",
|
|
29
|
+
required=False,
|
|
30
|
+
default=os.getenv("PDK_FAMILY") or "sky130",
|
|
31
|
+
help="The PDK family to install",
|
|
32
|
+
)(function)
|
|
33
|
+
function = opt(
|
|
34
|
+
"--pdk-root",
|
|
35
|
+
required=False,
|
|
36
|
+
default=VOLARE_RESOLVED_HOME,
|
|
37
|
+
help="Path to the PDK root",
|
|
38
|
+
)(function)
|
|
39
|
+
return function
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def opt_build(function: Callable):
|
|
43
|
+
function = opt(
|
|
44
|
+
"-l",
|
|
45
|
+
"--include-libraries",
|
|
46
|
+
multiple=True,
|
|
47
|
+
default=None,
|
|
48
|
+
help="Libraries to include. You can use -l multiple times to include multiple libraries. Pass 'all' to include all of them. A default of 'None' uses a default set for the particular PDK.",
|
|
49
|
+
)(function)
|
|
50
|
+
function = opt(
|
|
51
|
+
"-j",
|
|
52
|
+
"--jobs",
|
|
53
|
+
default=1,
|
|
54
|
+
help="Specifies the number of commands to run simultaneously.",
|
|
55
|
+
)(function)
|
|
56
|
+
function = opt(
|
|
57
|
+
"--sram/--no-sram",
|
|
58
|
+
default=True,
|
|
59
|
+
hidden=True,
|
|
60
|
+
expose_value=False,
|
|
61
|
+
)(function)
|
|
62
|
+
function = opt(
|
|
63
|
+
"--clear-build-artifacts/--keep-build-artifacts",
|
|
64
|
+
default=False,
|
|
65
|
+
help="Whether or not to remove the build artifacts. Keeping the build artifacts is useful when testing.",
|
|
66
|
+
)(function)
|
|
67
|
+
function = opt(
|
|
68
|
+
"-r",
|
|
69
|
+
"--use-repo-at",
|
|
70
|
+
default=None,
|
|
71
|
+
multiple=True,
|
|
72
|
+
hidden=True,
|
|
73
|
+
type=str,
|
|
74
|
+
help="Use this repository instead of cloning and checking out, in the format repo_name=/path/to/repo. You can pass it multiple times to replace multiple repos. This feature is intended for cielo and PDK developers.",
|
|
75
|
+
)(function)
|
|
76
|
+
return function
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def opt_push(function: Callable):
|
|
80
|
+
function = opt("-o", "--owner", default=volare_repo.owner, help="Repository Owner")(
|
|
81
|
+
function
|
|
82
|
+
)
|
|
83
|
+
function = opt("-r", "--repository", default=volare_repo.name, help="Repository")(
|
|
84
|
+
function
|
|
85
|
+
)
|
|
86
|
+
function = opt(
|
|
87
|
+
"--pre/--prod", default=False, help="Push as pre-release or production"
|
|
88
|
+
)(function)
|
|
89
|
+
function = opt(
|
|
90
|
+
"-L",
|
|
91
|
+
"--push-library",
|
|
92
|
+
"push_libraries",
|
|
93
|
+
multiple=True,
|
|
94
|
+
default=None,
|
|
95
|
+
help="Push only libraries in this list. You can use -L multiple times to include multiple libraries. Pass 'None' to push all libraries built.",
|
|
96
|
+
)(function)
|
|
97
|
+
return function
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def set_token_cb(
|
|
101
|
+
ctx: click.Context,
|
|
102
|
+
param: click.Parameter,
|
|
103
|
+
value: Optional[str],
|
|
104
|
+
):
|
|
105
|
+
GitHubSession.Token.override = value
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def opt_token(function: Callable) -> Callable:
|
|
109
|
+
function = opt(
|
|
110
|
+
"-t",
|
|
111
|
+
"--token",
|
|
112
|
+
"session",
|
|
113
|
+
default=None,
|
|
114
|
+
required=False,
|
|
115
|
+
expose_value=False,
|
|
116
|
+
help="Replace the GitHub token used for GitHub requests, which is by default the value of the environment variable GITHUB_TOKEN or None.",
|
|
117
|
+
callback=set_token_cb,
|
|
118
|
+
)(function)
|
|
119
|
+
return function
|