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