/
__init__.py
542 lines (452 loc) · 22 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2018-2019 releng-tool
# Implementation in this file is considered "API safe". There is a strong
# attempt to prevent the changing of the following classes, methods, etc. to
# prevent compatibility issues as both this tool and extensions (if any) evolve.
class RelengRegistryInterface(object):
"""
interface of the registry passed into an extension's setup stage
This is the public interface of the releng-tool's registry which outlines
methods which can be invoked by an extension during the setup stage. When an
extension defines "def releng_setup(app):" the ``app`` value will be an
instance of this interface (``RelengRegistryInterface``). During the setup
call, an extension may call any of the defined methods using their ``app``
context.
"""
def add_extract_type(self, name, handler):
"""
register extraction support with a given name for this extension
An extension will invoke this method will attempting to support a custom
extraction method for a release engineering process. The extraction
type is identified by the provided ``name`` value. Packages being
processed with VCS type paired with a extension-defined fetch type or a
package extraction override will be processed through the provided
``handler``.
An extension must define a proper ``name`` for the extract-type:
- The name is a string value.
- The name must be prefixed with ``ext-``.
- The name should be all lowercase.
- The dash character ``-`` is the recommended separator.
The ``handler`` must be compatible with the implementation defined in
``RelengExtractExtensionInterface``. There is no requirement that the
handler needs to inherit this interface.
Additional notes:
- The releng-tool process may instantiation one or more of the provided
handler types.
- The first extension loaded with a custom extract-type will take
precedence over other extensions.
Args:
name: the name of this extract type
handler: the extract-type class handler
Raises:
RelengInvalidSetupException: raised when the provided ``name`` or
``handler`` values are not supported by the releng-tool process
"""
pass
def add_fetch_type(self, name, handler):
"""
register fetch support with a given name for this extension
An extension will invoke this method will attempting to support a custom
fetch method for a release engineering process. The fetch type is
identified by the provided ``name`` value. Packages being processed with
a matching VCS type will be processed through the provided ``handler``.
An extension must define a proper ``name`` for the fetch-type:
- The name is a string value.
- The name must be prefixed with ``ext-``.
- The name should be all lowercase.
- The dash character ``-`` is the recommended separator.
The ``handler`` must be compatible with the implementation defined in
``RelengFetchExtensionInterface``. There is no requirement that the
handler needs to inherit this interface.
Additional notes:
- The releng-tool process may instantiation one or more of the provided
handler types.
- The first extension loaded with a custom fetch-type will take
precedence over other extensions.
Args:
name: the name of this fetch type
handler: the fetch-type class handler
Raises:
RelengInvalidSetupException: raised when the provided ``name`` or
``handler`` values are not supported by the releng-tool process
"""
pass
def add_package_type(self, name, handler):
"""
register package support with a given name for this extension
An extension will invoke this method will attempting to support a custom
package methods for a release engineering process. The package type is
identified by the provided ``name`` value. Packages being processed with
a matching type will be processed through the provided ``handler`` for
each package stage (configuration, building, etc.).
An extension must define a proper ``name`` for the package-type:
- The name is a string value.
- The name must be prefixed with ``ext-``.
- The name should be all lowercase.
- The dash character ``-`` is the recommended separator.
The ``handler`` must be compatible with the implementation defined in
``RelengPackageExtensionInterface``. There is no requirement that the
handler needs to inherit this interface.
Additional notes:
- The releng-tool process may instantiation one or more of the provided
handler types.
- The first extension loaded with a custom package-type will take
precedence over other extensions.
Args:
name: the name of this package type
handler: the package-type class handler
Raises:
RelengInvalidSetupException: raised when the provided ``name`` or
``handler`` values are not supported by the releng-tool process
"""
pass
def require_version(self, version):
"""
perform a required-version check
Enables an extension to explicitly check for a required releng-tool
version before being loaded. Invoking this method with a
dotted-separated ``version`` string, the string will be parsed and
compared with the running releng-tool version. If the required version
is met, this method will have no effect. In the event that the required
version is not met, the exception ``RelengVersionNotSupportedException``
will be raised. The extension implementation does not need to explicitly
handle this exception (as it is caught by the registry loading process).
Args:
version: dotted-separated version string
Raises:
RelengVersionNotSupportedException: raised when the required version
for this extension is not met
"""
pass
# ##############################################################################
class RelengPackageOptions(object):
"""
releng package-type options
Provides a series of options from the releng process into a package-type
handler. A handler's ``configure``, ``build``, and ``install`` methods will
be passed options to react on.
Attributes:
def_dir: the directory holder the package definition
env: package's environment variables
ext: extension (pass-through) options
name: the name of the package being processed
version: the version of the package
"""
def __init__(self):
self.def_dir = None
self.env = None
self.ext = {}
self.name = None
self.version = None
class RelengConfigureOptions(RelengPackageOptions):
"""
releng configure-type options
Provides a series of options from the releng process into a configure-type
handler. A handler's ``configuration`` method will be passed options to
react on.
Attributes:
build_dir: directory for a package's buildable content
build_output_dir: build output directory for the package process
conf_defs: command line definitions to apply
conf_env: environment variables to use
conf_opts: command line options to apply
host_dir: directory container for host tools
install_type: installation type (host, staging, target or images)
jobs: number of calculated jobs to allow at a given time
jobsconf: number of jobs to allow at a given time (0: auto)
prefix: prefix for system root (if applicable)
staging_dir: directory container for staged content
symbols_dir: directory container for symbols content
target_dir: directory container for target content
"""
def __init__(self):
super(RelengConfigureOptions, self).__init__()
self.build_dir = None
self.build_output_dir = None
self.conf_defs = None
self.conf_env = None
self.conf_opts = None
self.host_dir = None
self.install_type = None
self.jobs = 1
self.jobsconf = 0
self.prefix = None
self.staging_dir = None
self.symbols_dir = None
self.target_dir = None
class RelengBuildOptions(RelengPackageOptions):
"""
releng build-type options
Provides a series of options from the releng process into a build-type
handler. A handler's ``build`` method will be passed options to react on.
Attributes:
build_defs: command line definitions to apply
build_dir: directory for a package's buildable content
build_env: environment variables to use
build_opts: command line options to apply
build_output_dir: build output directory for the package process
host_dir: directory container for host tools
jobs: number of calculated jobs to allow at a given time
jobsconf: number of jobs to allow at a given time (0: auto)
prefix: prefix for system root (if applicable)
staging_dir: directory container for staged content
symbols_dir: directory container for symbols content
target_dir: directory container for target content
"""
def __init__(self):
super(RelengBuildOptions, self).__init__()
self.build_defs = None
self.build_dir = None
self.build_env = None
self.build_opts = None
self.build_output_dir = None
self.host_dir = None
self.jobs = 1
self.jobsconf = 0
self.prefix = None
self.staging_dir = None
self.symbols_dir = None
self.target_dir = None
class RelengExtractOptions(RelengPackageOptions):
"""
releng extract-type options
Provides a series of options from the releng process into a extract-type
handler. A handler's ``extract`` method will be passed options to react on.
Attributes:
cache_dir: directory to store cached content (if applicable)
cache_file: file to store cached content (if applicable)
revision: revision to use to fetch from source control
strip_count: strip-count for package extraction (if applicable)
work_dir: the working directory
"""
def __init__(self):
super(RelengExtractOptions, self).__init__()
self.cache_dir = None
self.cache_file = None
self.revision = None
self.strip_count = 1
self.work_dir = None
class RelengFetchOptions(RelengPackageOptions):
"""
releng fetch-type options
Provides a series of options from the releng process into a fetch-type
handler. A handler's ``fetch`` method will be passed options to react on.
Attributes:
cache_dir: directory to store cached content (if applicable)
cache_file: file to store cached content (if applicable)
revision: revision to use to fetch from source control
site: the site (uri) to acquire a package's resources
"""
def __init__(self):
super(RelengFetchOptions, self).__init__()
self.cache_dir = None
self.cache_file = None
self.revision = None
self.site = None
class RelengInstallOptions(RelengPackageOptions):
"""
releng install-type options
Provides a series of options from the releng process into a install-type
handler. A handler's ``installation`` method will be passed options to react
on.
Attributes:
build_dir: directory for a package's buildable content
build_output_dir: build output directory for the package process
cache_file: location to cache file (if applicable)
dest_dirs: list of directories to install to
host_dir: directory container for host tools
images_dir: directory container for (final) images
install_defs: command line definitions to apply
install_env: environment variables to use
install_opts: command line options to apply
install_type: installation type
prefix: prefix for system root (if applicable)
staging_dir: directory container for staged content
symbols_dir: directory container for symbols content
target_dir: directory container for target content
"""
def __init__(self):
super(RelengInstallOptions, self).__init__()
self.build_dir = None
self.build_output_dir = None
self.cache_file = None
self.dest_dirs = None
self.host_dir = None
self.images_dir = None
self.install_defs = None
self.install_env = None
self.install_opts = None
self.install_type = None
self.prefix = None
self.staging_dir = None
self.symbols_dir = None
self.target_dir = None
# ##############################################################################
class RelengExtensionInterface(object):
"""
interface to implement a custom fetch-type
Extensions wishing to define a custom fetch type can implement this
interface and register it (see ``add_fetch_type``) during the extension's
setup stage. This will allow an project support custom VCS-types defined in
package definitions (for example "<PKG>_VCS_TYPE='ext-myawesomefetchtype'").
"""
pass
class RelengExtractExtensionInterface(RelengExtensionInterface):
"""
interface to implement a custom fetch-type
Extensions wishing to define a custom fetch type can implement this
interface and register it (see ``add_fetch_type``) during the extension's
setup stage. This will allow an project support custom VCS-types defined in
package definitions (for example "<PKG>_VCS_TYPE='ext-myawesomefetchtype'").
"""
def extract(self, name, opts):
"""
handle a custom extract operation
When a package attempts to be "extracted" and VCS-type is defined to the
custom extraction name, this method will be invoked. Package information
to perform the extraction is provided by the ``opts`` argument. The main
goal of this operation is to populate the provided work or "build"
directory (same as the working directory) based off the package's cache
directory or file (which varies base don the package type). On
completion, this method should return ``True`` to indicate a successful
extraction. If an error occurs, this method should return ``False``. A
failed extraction operation is not required to clean the work directory.
The ``extract`` method may be called multiple times throughout the
lifetime of a releng-tool process (i.e. once per project being
extracted).
Args:
name: the name of this extraction type
opts: the extract options (see ``RelengExtractOptions``)
Returns:
``True`` on successful extraction; otherwise ``False``
"""
return False
class RelengFetchExtensionInterface(RelengExtensionInterface):
"""
interface to implement a custom fetch-type
Extensions wishing to define a custom fetch type can implement this
interface and register it (see ``add_fetch_type``) during the extension's
setup stage. This will allow an project support custom VCS-types defined in
package definitions (for example "<PKG>_VCS_TYPE='ext-myawesomefetchtype'").
"""
def fetch(self, name, opts):
"""
handle a custom fetch operation
When a package attempts to be "fetched" and VCS-type is defined to the
custom fetch name, this method will be invoked. Package information to
perform the fetch on is provided by the ``opts`` argument. The main goal
of this operation is to fetch content from a provided site into either
a cache file or a cache directory. On completion, this method should
return either the cache file or cache directory depending on which has
been populated from the fetch operation. The returned catch value should
match the same value provided in the fetch options: ``opts.cache_file``
if the fetch operation populates a cached file or ``opts.cache_dir`` if
the fetch operation populates a cache directory. If the fetch operation
returns a ``None`, this is an indication that the fetch operation has
failed. A failed fetch operation is not required to clean the work
directory; however, it is the responsibility of the custom fetch type to
manage the state of the ``cache_dir`` (if applicable) and other external
resources it may managed.
The ``fetch`` method may be called multiple times throughout the
lifetime of a releng-tool process (i.e. once per project being fetched).
Args:
name: the name of this fetch type
opts: the fetch options (see ``RelengFetchOptions``)
Returns:
``True`` on successful fetch; otherwise ``False``
"""
return False
class RelengPackageExtensionInterface(RelengExtensionInterface):
"""
interface to implement a custom fetch-type
Extensions wishing to define a custom fetch type can implement this
interface and register it (see ``add_fetch_type``) during the extension's
setup stage. This will allow an project support custom VCS-types defined in
package definitions (for example "<PKG>_VCS_TYPE='ext-myawesomefetchtype'").
"""
def build(self, name, opts):
"""
handle a custom build operation
When a package reaches the building stage and package-type is defined
to the custom package-type name, this method will be invoked. Package
information to perform the build on is provided by the ``opts``
argument. The main goal of this operation is to complete the build stage
of a specific package in the provided work directory (same as the
working directory). On completion, this method should return ``True`` to
indicate a successful build. If an error occurs, this method should
return ``False``. A failed build operation is not required to clean the
work directory; however, the implementation should (attempt) to support
a build request on a package which may have previously failed (i.e.
build options or sources may have been changed to result in a successful
build).
The ``build`` method may be called multiple times throughout the
lifetime of a releng-tool process (i.e. once per project being built).
Args:
name: the name of this package type
opts: the build options (see ``RelengPackageOptions``)
Returns:
``True`` on a successful build; otherwise ``False``
"""
return False
def configure(self, opts):
"""
handle a custom configure operation
When a package reaches the configuration stage and package-type is
defined to the custom package-type name, this method will be invoked.
Package information to perform the configuration on is provided by the
``opts`` argument. The main goal of this operation is to complete the
configuration stage of a specific package in the provided work directory
(same as the working directory). On completion, this method should
return ``True`` to indicate a successful configuration. If an error
occurs, this method should return ``False``. A failed configuration
operation is not required to clean the work directory; however, the
implementation should (attempt) to support a configuration request on a
package which may have previously failed (i.e. configuration options or
sources may have been changed to result in a successful configuration).
The ``configure`` method may be called multiple times throughout the
lifetime of a releng-tool process (i.e. once per project being
configured).
Args:
name: the name of this package type
opts: the configuration options (see ``RelengPackageOptions``)
Returns:
``True`` on a successful configuration; otherwise ``False``
"""
return False
def install(self, name, opts):
"""
handle a custom install operation
When a package reaches the installation stage and package-type is
defined to the custom package-type name, this method will be invoked.
Package information to perform the installation on is provided by the
``opts`` argument. The main goal of this operation is to complete the
install stage of a specific package in the provided work directory
(same as the working directory). On completion, this method should
return ``True`` to indicate a successful installation. If an error
occurs, this method should return ``False``. A failed install operation
is not required to clean the work directory; however, the implementation
should (attempt) to support an install request on a package which may
have previously failed (i.e. install options or sources may have been
changed to result in a successful installation).
The ``install`` method may be called multiple times throughout the
lifetime of a releng-tool process (i.e. once per project being
installed).
Args:
name: the name of this package type
opts: the install options (see ``RelengPackageOptions``)
Returns:
`True`` on a successful installation; otherwise ``False``
"""
return False
# ##############################################################################
class RelengInvalidSetupException(Exception):
"""
exception raised when a loading extension has a setup issue
"""
pass
class RelengVersionNotSupportedException(Exception):
"""
exception raised when an extension does not support the releng-tool version
"""
pass