1#!/usr/bin/env python3 2# ex:ts=4:sw=4:sts=4:et 3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- 4# 5# Generate Toaster Fixtures for 'poky.xml' and 'oe-core.xml' 6# 7# Copyright (C) 2022 Wind River Systems 8# SPDX-License-Identifier: GPL-2.0-only 9# 10# Edit the 'current_releases' table for each new release cycle 11# 12# Usage: ./get_fixtures all 13# 14 15import os 16import sys 17import argparse 18 19verbose = False 20 21#################################### 22# Releases 23# 24# https://wiki.yoctoproject.org/wiki/Releases 25# 26# NOTE: for the current releases table, it helps to keep continuing releases 27# in the same table positions since this minimizes the patch diff for review. 28# The order of the table does not matter since Toaster presents them sorted. 29# 30# Traditionally, the two most current releases are included in addition to the 31# 'master' branch and the local installation's 'HEAD'. 32# It is also policy to include all active LTS releases. 33# 34 35# [Codename, Yocto Project Version, Release Date, Current Version, Support Level, Poky Version, BitBake branch] 36current_releases = [ 37 # Release slot #1 38 ['Kirkstone','3.5','April 2022','','Future - Long Term Support (until Apr. 2024)','27.0','1.54'], 39# ['Dunfell','3.1','April 2021','3.1.5 (March 2022)','Stable - Support for 13 months (until Apr. 2022)','23.0','1.46'], 40 # Release slot #2 'local' 41 ['HEAD','HEAD','','Local Yocto Project','HEAD','','HEAD'], 42 # Release slot #3 'master' 43 ['Master','master','','Yocto Project master','master','','master'], 44 # Release slot #4 45 ['Honister','3.4','October 2021','3.4.2 (February 2022)','Support for 7 months (until May 2022)','26.0','1.52'], 46# ['Gatesgarth','3.2','Oct 2020','3.2.4 (May 2021)','EOL','24.0','1.48'], 47 # Optional Release slot #4 48 ['Hardknott','3.3','April 2021','3.3.5 (March 2022)','Stable - Support for 13 months (until Apr. 2022)','25.0','1.50'], 49] 50 51default_poky_layers = [ 52 'openembedded-core', 53 'meta-poky', 54 'meta-yocto-bsp', 55] 56 57default_oe_core_layers = [ 58 'openembedded-core', 59] 60 61#################################### 62# Templates 63 64prolog_template = '''\ 65<?xml version="1.0" encoding="utf-8"?> 66<django-objects version="1.0"> 67 <!-- Set the project default value for DISTRO --> 68 <object model="orm.toastersetting" pk="1"> 69 <field type="CharField" name="name">DEFCONF_DISTRO</field> 70 <field type="CharField" name="value">{{distro}}</field> 71 </object> 72''' 73 74#<!-- Bitbake versions which correspond to the metadata release -->') 75bitbakeversion_poky_template = '''\ 76 <object model="orm.bitbakeversion" pk="{{bitbake_id}}"> 77 <field type="CharField" name="name">{{name}}</field> 78 <field type="CharField" name="giturl">git://git.yoctoproject.org/poky</field> 79 <field type="CharField" name="branch">{{branch}}</field> 80 <field type="CharField" name="dirpath">bitbake</field> 81 </object> 82''' 83bitbakeversion_oecore_template = '''\ 84 <object model="orm.bitbakeversion" pk="{{bitbake_id}}"> 85 <field type="CharField" name="name">{{name}}</field> 86 <field type="CharField" name="giturl">git://git.openembedded.org/bitbake</field> 87 <field type="CharField" name="branch">{{bitbakeversion}}</field> 88 </object> 89''' 90 91# <!-- Releases available --> 92releases_available_template = '''\ 93 <object model="orm.release" pk="{{ra_count}}"> 94 <field type="CharField" name="name">{{name}}</field> 95 <field type="CharField" name="description">{{description}}</field> 96 <field rel="ManyToOneRel" to="orm.bitbakeversion" name="bitbake_version">{{ra_count}}</field> 97 <field type="CharField" name="branch_name">{{release}}</field> 98 <field type="TextField" name="helptext">Toaster will run your builds {{help_source}}.</field> 99 </object> 100''' 101 102# <!-- Default project layers for each release --> 103default_layers_template = '''\ 104 <object model="orm.releasedefaultlayer" pk="{{rdl_count}}"> 105 <field rel="ManyToOneRel" to="orm.release" name="release">{{release_id}}</field> 106 <field type="CharField" name="layer_name">{{layer}}</field> 107 </object> 108''' 109 110default_layers_preface = '''\ 111 <!-- Default layers provided by poky 112 openembedded-core 113 meta-poky 114 meta-yocto-bsp 115 --> 116''' 117 118layer_poky_template = '''\ 119 <object model="orm.layer" pk="{{layer_id}}"> 120 <field type="CharField" name="name">{{layer}}</field> 121 <field type="CharField" name="layer_index_url"></field> 122 <field type="CharField" name="vcs_url">{{vcs_url}}</field> 123 <field type="CharField" name="vcs_web_url">{{vcs_web_url}}</field> 124 <field type="CharField" name="vcs_web_tree_base_url">{{vcs_web_tree_base_url}}</field> 125 <field type="CharField" name="vcs_web_file_base_url">{{vcs_web_file_base_url}}</field> 126 </object> 127''' 128 129layer_oe_core_template = '''\ 130 <object model="orm.layer" pk="{{layer_id}}"> 131 <field type="CharField" name="name">{{layer}}</field> 132 <field type="CharField" name="vcs_url">{{vcs_url}}</field> 133 <field type="CharField" name="vcs_web_url">{{vcs_web_url}}</field> 134 <field type="CharField" name="vcs_web_tree_base_url">{{vcs_web_tree_base_url}}</field> 135 <field type="CharField" name="vcs_web_file_base_url">{{vcs_web_file_base_url}}</field> 136 </object> 137''' 138 139layer_version_template = '''\ 140 <object model="orm.layer_version" pk="{{lv_count}}"> 141 <field rel="ManyToOneRel" to="orm.layer" name="layer">{{layer_id}}</field> 142 <field type="IntegerField" name="layer_source">0</field> 143 <field rel="ManyToOneRel" to="orm.release" name="release">{{release_id}}</field> 144 <field type="CharField" name="branch">{{branch}}</field> 145 <field type="CharField" name="dirpath">{{dirpath}}</field> 146 </object> 147''' 148 149layer_version_HEAD_template = '''\ 150 <object model="orm.layer_version" pk="{{lv_count}}"> 151 <field rel="ManyToOneRel" to="orm.layer" name="layer">{{layer_id}}</field> 152 <field type="IntegerField" name="layer_source">0</field> 153 <field rel="ManyToOneRel" to="orm.release" name="release">{{release_id}}</field> 154 <field type="CharField" name="branch">{{branch}}</field> 155 <field type="CharField" name="commit">{{commit}}</field> 156 <field type="CharField" name="dirpath">{{dirpath}}</field> 157 </object> 158''' 159 160layer_version_oe_core_template = '''\ 161 <object model="orm.layer_version" pk="1"> 162 <field rel="ManyToOneRel" to="orm.layer" name="layer">1</field> 163 <field rel="ManyToOneRel" to="orm.release" name="release">2</field> 164 <field type="CharField" name="local_path">OE-CORE-LAYER-DIR</field> 165 <field type="CharField" name="branch">HEAD</field> 166 <field type="CharField" name="dirpath">meta</field> 167 <field type="IntegerField" name="layer_source">0</field> 168 </object> 169''' 170 171epilog_template = '''\ 172</django-objects> 173''' 174 175################################# 176# Helper Routines 177# 178 179def print_str(str,fd): 180 # Avoid extra newline at end 181 if str and (str[-1] == '\n'): 182 str = str[0:-1] 183 print(str,file=fd) 184 185def print_template(template,params,fd): 186 for line in template.split('\n'): 187 p = line.find('{{') 188 while p > 0: 189 q = line.find('}}') 190 key = line[p+2:q] 191 if key in params: 192 line = line[0:p] + params[key] + line[q+2:] 193 else: 194 line = line[0:p] + '?' + key + '?' + line[q+2:] 195 p = line.find('{{') 196 if line: 197 print(line,file=fd) 198 199################################# 200# Generate poky.xml 201# 202 203def generate_poky(): 204 fd = open('poky.xml','w') 205 206 params = {} 207 params['distro'] = 'poky' 208 print_template(prolog_template,params,fd) 209 print_str('',fd) 210 211 print_str(' <!-- Bitbake versions which correspond to the metadata release -->',fd) 212 for i,release in enumerate(current_releases): 213 params = {} 214 params['release'] = release[0] 215 params['Release'] = release[0] 216 params['release_version'] = release[1] 217 if not (params['release'] in ('HEAD')): # 'master', 218 params['release'] = params['release'][0].lower() + params['release'][1:] 219 params['name'] = params['release'] 220 params['bitbake_id'] = str(i+1) 221 params['branch'] = params['release'] 222 print_template(bitbakeversion_poky_template,params,fd) 223 print_str('',fd) 224 225 print_str('',fd) 226 print_str(' <!-- Releases available -->',fd) 227 for i,release in enumerate(current_releases): 228 params = {} 229 params['release'] = release[0] 230 params['Release'] = release[0] 231 params['release_version'] = release[1] 232 if not (params['release'] in ('HEAD')): #'master', 233 params['release'] = params['release'][0].lower() + params['release'][1:] 234 params['h_release'] = '?h={{release}}' 235 params['name'] = params['release'] 236 params['ra_count'] = str(i+1) 237 params['branch'] = params['release'] 238 239 if 'HEAD' == params['release']: 240 params['help_source'] = 'with the version of the Yocto Project you have cloned or downloaded to your computer' 241 params['description'] = 'Local Yocto Project' 242 params['name'] = 'local' 243 else: 244 params['help_source'] = 'using the tip of the <a href="https://git.yoctoproject.org/cgit/cgit.cgi/poky/log/{{h_release}}">Yocto Project {{Release}} branch</a>' 245 params['description'] = 'Yocto Project {{release_version}} "{{Release}}"' 246 if 'master' == params['release']: 247 params['h_release'] = '' 248 params['description'] = 'Yocto Project master' 249 250 print_template(releases_available_template,params,fd) 251 print_str('',fd) 252 253 print_str(' <!-- Default project layers for each release -->',fd) 254 rdl_count = 1 255 for i,release in enumerate(current_releases): 256 for j,layer in enumerate(default_poky_layers): 257 params = {} 258 params['layer'] = layer 259 params['release'] = release[0] 260 params['Release'] = release[0] 261 params['release_version'] = release[1] 262 if not (params['release'] in ('master','HEAD')): 263 params['release'] = params['release'][0].lower() + params['release'][1:] 264 params['release_id'] = str(i+1) 265 params['rdl_count'] = str(rdl_count) 266 params['branch'] = params['release'] 267 print_template(default_layers_template,params,fd) 268 rdl_count += 1 269 print_str('',fd) 270 271 print_str(default_layers_preface,fd) 272 lv_count = 1 273 for i,layer in enumerate(default_poky_layers): 274 params = {} 275 params['layer'] = layer 276 params['layer_id'] = str(i+1) 277 params['vcs_url'] = 'git://git.yoctoproject.org/poky' 278 params['vcs_web_url'] = 'https://git.yoctoproject.org/cgit/cgit.cgi/poky' 279 params['vcs_web_tree_base_url'] = 'https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/%path%?h=%branch%' 280 params['vcs_web_file_base_url'] = 'https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/%path%?h=%branch%' 281 282 if i: 283 print_str('',fd) 284 print_template(layer_poky_template,params,fd) 285 for j,release in enumerate(current_releases): 286 params['release'] = release[0] 287 params['Release'] = release[0] 288 params['release_version'] = release[1] 289 if not (params['release'] in ('master','HEAD')): 290 params['release'] = params['release'][0].lower() + params['release'][1:] 291 params['release_id'] = str(j+1) 292 params['lv_count'] = str(lv_count) 293 params['branch'] = params['release'] 294 params['commit'] = params['release'] 295 296 params['dirpath'] = params['layer'] 297 if params['layer'] in ('openembedded-core'): #'openembedded-core', 298 params['dirpath'] = 'meta' 299 300 if 'HEAD' == params['release']: 301 print_template(layer_version_HEAD_template,params,fd) 302 else: 303 print_template(layer_version_template,params,fd) 304 lv_count += 1 305 306 print_str(epilog_template,fd) 307 fd.close() 308 309################################# 310# Generate oe-core.xml 311# 312 313def generate_oe_core(): 314 fd = open('oe-core.xml','w') 315 316 params = {} 317 params['distro'] = 'nodistro' 318 print_template(prolog_template,params,fd) 319 print_str('',fd) 320 321 print_str(' <!-- Bitbake versions which correspond to the metadata release -->',fd) 322 for i,release in enumerate(current_releases): 323 params = {} 324 params['release'] = release[0] 325 params['Release'] = release[0] 326 params['bitbakeversion'] = release[6] 327 params['release_version'] = release[1] 328 if not (params['release'] in ('HEAD')): # 'master', 329 params['release'] = params['release'][0].lower() + params['release'][1:] 330 params['name'] = params['release'] 331 params['bitbake_id'] = str(i+1) 332 params['branch'] = params['release'] 333 print_template(bitbakeversion_oecore_template,params,fd) 334 print_str('',fd) 335 336 print_str(' <!-- Releases available -->',fd) 337 for i,release in enumerate(current_releases): 338 params = {} 339 params['release'] = release[0] 340 params['Release'] = release[0] 341 params['release_version'] = release[1] 342 if not (params['release'] in ('HEAD')): #'master', 343 params['release'] = params['release'][0].lower() + params['release'][1:] 344 params['h_release'] = '?h={{release}}' 345 params['name'] = params['release'] 346 params['ra_count'] = str(i+1) 347 params['branch'] = params['release'] 348 349 if 'HEAD' == params['release']: 350 params['help_source'] = 'with the version of OpenEmbedded that you have cloned or downloaded to your computer' 351 params['description'] = 'Local Openembedded' 352 params['name'] = 'local' 353 else: 354 params['help_source'] = 'using the tip of the <a href=\\"https://cgit.openembedded.org/openembedded-core/log/{{h_release}}\\">OpenEmbedded {{Release}}</a> branch' 355 params['description'] = 'Openembedded {{Release}}' 356 if 'master' == params['release']: 357 params['h_release'] = '' 358 params['description'] = 'OpenEmbedded core master' 359 params['Release'] = params['release'] 360 361 print_template(releases_available_template,params,fd) 362 print_str('',fd) 363 364 print_str(' <!-- Default layers for each release -->',fd) 365 rdl_count = 1 366 for i,release in enumerate(current_releases): 367 for j,layer in enumerate(default_oe_core_layers): 368 params = {} 369 params['layer'] = layer 370 params['release'] = release[0] 371 params['Release'] = release[0] 372 params['release_version'] = release[1] 373 if not (params['release'] in ('master','HEAD')): 374 params['release'] = params['release'][0].lower() + params['release'][1:] 375 params['release_id'] = str(i+1) 376 params['rdl_count'] = str(rdl_count) 377 params['branch'] = params['release'] 378 print_template(default_layers_template,params,fd) 379 rdl_count += 1 380 print_str('',fd) 381 382 print_str('',fd) 383 print_str(' <!-- Layer for the Local release -->',fd) 384 lv_count = 1 385 for i,layer in enumerate(default_oe_core_layers): 386 params = {} 387 params['layer'] = layer 388 params['layer_id'] = str(i+1) 389 params['vcs_url'] = 'git://git.openembedded.org/openembedded-core' 390 params['vcs_web_url'] = 'https://cgit.openembedded.org/openembedded-core' 391 params['vcs_web_tree_base_url'] = 'https://cgit.openembedded.org/openembedded-core/tree/%path%?h=%branch%' 392 params['vcs_web_file_base_url'] = 'https://cgit.openembedded.org/openembedded-core/tree/%path%?h=%branch%' 393 if i: 394 print_str('',fd) 395 print_template(layer_oe_core_template,params,fd) 396 397 print_template(layer_version_oe_core_template,params,fd) 398 print_str('',fd) 399 400 print_str(epilog_template,fd) 401 fd.close() 402 403################################# 404# Help 405# 406 407def list_releases(): 408 print("Release ReleaseVer BitbakeVer Support Level") 409 print("========== =========== ========== ==============================================") 410 for release in current_releases: 411 print("%10s %10s %11s %s" % (release[0],release[1],release[6],release[4])) 412 413################################# 414# main 415# 416 417def main(argv): 418 global verbose 419 420 parser = argparse.ArgumentParser(description='gen_fixtures.py: table generate the fixture files') 421 parser.add_argument('--poky', '-p', action='store_const', const='poky', dest='command', help='Generate the poky.xml file') 422 parser.add_argument('--oe-core', '-o', action='store_const', const='oe_core', dest='command', help='Generate the oe-core.xml file') 423 parser.add_argument('--all', '-a', action='store_const', const='all', dest='command', help='Generate all fixture files') 424 parser.add_argument('--list', '-l', action='store_const', const='list', dest='command', help='List the release table') 425 parser.add_argument('--verbose', '-v', action='store_true', dest='verbose', help='Enable verbose debugging output') 426 args = parser.parse_args() 427 428 verbose = args.verbose 429 if 'poky' == args.command: 430 generate_poky() 431 elif 'oe_core' == args.command: 432 generate_oe_core() 433 elif 'all' == args.command: 434 generate_poky() 435 generate_oe_core() 436 elif 'all' == args.command: 437 list_releases() 438 elif 'list' == args.command: 439 list_releases() 440 441 else: 442 print("No command for 'gen_fixtures.py' selected") 443 444if __name__ == '__main__': 445 main(sys.argv[1:]) 446