diff options
| -rwxr-xr-x | bitbake/bin/bitbake-setup | 287 | ||||
| -rw-r--r-- | bitbake/lib/bb/tests/setup.py | 12 |
2 files changed, 147 insertions, 152 deletions
diff --git a/bitbake/bin/bitbake-setup b/bitbake/bin/bitbake-setup index 7878cd9394..e9e73a9270 100755 --- a/bitbake/bin/bitbake-setup +++ b/bitbake/bin/bitbake-setup | |||
| @@ -32,9 +32,9 @@ logger = bb.msg.logger_create('bitbake-setup', sys.stdout) | |||
| 32 | def cache_dir(top_dir): | 32 | def cache_dir(top_dir): |
| 33 | return os.path.join(top_dir, '.bitbake-setup-cache') | 33 | return os.path.join(top_dir, '.bitbake-setup-cache') |
| 34 | 34 | ||
| 35 | def init_bb_cache(settings, args): | 35 | def init_bb_cache(top_dir, settings, args): |
| 36 | dldir = settings["default"]["dl-dir"] | 36 | dldir = settings["default"]["dl-dir"] |
| 37 | bb_cachedir = os.path.join(cache_dir(args.top_dir), 'bitbake-cache') | 37 | bb_cachedir = os.path.join(cache_dir(top_dir), 'bitbake-cache') |
| 38 | 38 | ||
| 39 | d = bb.data.init() | 39 | d = bb.data.init() |
| 40 | d.setVar("DL_DIR", dldir) | 40 | d.setVar("DL_DIR", dldir) |
| @@ -389,7 +389,7 @@ def choose_fragments(possibilities, parameters, non_interactive, skip_selection) | |||
| 389 | choices[k] = options_enumerated[option_n][1] | 389 | choices[k] = options_enumerated[option_n][1] |
| 390 | return choices | 390 | return choices |
| 391 | 391 | ||
| 392 | def obtain_config(settings, args, source_overrides, d): | 392 | def obtain_config(top_dir, settings, args, source_overrides, d): |
| 393 | if args.config: | 393 | if args.config: |
| 394 | config_id = args.config[0] | 394 | config_id = args.config[0] |
| 395 | config_parameters = args.config[1:] | 395 | config_parameters = args.config[1:] |
| @@ -407,7 +407,7 @@ def obtain_config(settings, args, source_overrides, d): | |||
| 407 | upstream_config = {'type':'network','uri':config_id,'name':get_config_name(config_id),'data':json.load(f)} | 407 | upstream_config = {'type':'network','uri':config_id,'name':get_config_name(config_id),'data':json.load(f)} |
| 408 | else: | 408 | else: |
| 409 | print("Looking up config {} in configuration registry".format(config_id)) | 409 | print("Looking up config {} in configuration registry".format(config_id)) |
| 410 | registry_path = update_registry(settings["default"]["registry"], cache_dir(args.top_dir), d) | 410 | registry_path = update_registry(settings["default"]["registry"], cache_dir(top_dir), d) |
| 411 | registry_configs = list_registry(registry_path, with_expired=True) | 411 | registry_configs = list_registry(registry_path, with_expired=True) |
| 412 | if config_id not in registry_configs: | 412 | if config_id not in registry_configs: |
| 413 | raise Exception("Config {} not found in configuration registry, re-run 'init' without parameters to choose from available configurations.".format(config_id)) | 413 | raise Exception("Config {} not found in configuration registry, re-run 'init' without parameters to choose from available configurations.".format(config_id)) |
| @@ -416,7 +416,7 @@ def obtain_config(settings, args, source_overrides, d): | |||
| 416 | if has_expired(expiry_date): | 416 | if has_expired(expiry_date): |
| 417 | print("This configuration is no longer supported after {}. Please consider changing to a supported configuration.".format(expiry_date)) | 417 | print("This configuration is no longer supported after {}. Please consider changing to a supported configuration.".format(expiry_date)) |
| 418 | else: | 418 | else: |
| 419 | registry_path = update_registry(settings["default"]["registry"], cache_dir(args.top_dir), d) | 419 | registry_path = update_registry(settings["default"]["registry"], cache_dir(top_dir), d) |
| 420 | registry_configs = list_registry(registry_path, with_expired=True) | 420 | registry_configs = list_registry(registry_path, with_expired=True) |
| 421 | config_id = choose_config(registry_configs, args.non_interactive) | 421 | config_id = choose_config(registry_configs, args.non_interactive) |
| 422 | config_parameters = [] | 422 | config_parameters = [] |
| @@ -429,7 +429,7 @@ def obtain_config(settings, args, source_overrides, d): | |||
| 429 | upstream_config['skip-selection'] = args.skip_selection | 429 | upstream_config['skip-selection'] = args.skip_selection |
| 430 | return upstream_config | 430 | return upstream_config |
| 431 | 431 | ||
| 432 | def init_config(settings, args, d): | 432 | def init_config(top_dir, settings, args, d): |
| 433 | stdout = sys.stdout | 433 | stdout = sys.stdout |
| 434 | def handle_task_progress(event, d): | 434 | def handle_task_progress(event, d): |
| 435 | rate = event.rate if event.rate else '' | 435 | rate = event.rate if event.rate else '' |
| @@ -437,10 +437,10 @@ def init_config(settings, args, d): | |||
| 437 | print("{}% {} ".format(progress, rate), file=stdout, end='\r') | 437 | print("{}% {} ".format(progress, rate), file=stdout, end='\r') |
| 438 | 438 | ||
| 439 | source_overrides = json.load(open(args.source_overrides)) if args.source_overrides else {'sources':{}} | 439 | source_overrides = json.load(open(args.source_overrides)) if args.source_overrides else {'sources':{}} |
| 440 | upstream_config = obtain_config(settings, args, source_overrides, d) | 440 | upstream_config = obtain_config(top_dir, settings, args, source_overrides, d) |
| 441 | print("\nRun 'bitbake-setup init --non-interactive {}' to select this configuration non-interactively.\n".format(" ".join(upstream_config['non-interactive-cmdline-options']))) | 441 | print("\nRun 'bitbake-setup init --non-interactive {}' to select this configuration non-interactively.\n".format(" ".join(upstream_config['non-interactive-cmdline-options']))) |
| 442 | 442 | ||
| 443 | builddir = os.path.join(os.path.abspath(args.top_dir), args.build_dir_name or "{}-{}".format(upstream_config['name']," ".join(upstream_config['non-interactive-cmdline-options'][1:]).replace(" ","-").replace("/","_"))) | 443 | builddir = os.path.join(os.path.abspath(top_dir), args.build_dir_name or "{}-{}".format(upstream_config['name']," ".join(upstream_config['non-interactive-cmdline-options'][1:]).replace(" ","-").replace("/","_"))) |
| 444 | if os.path.exists(os.path.join(builddir, "layers")): | 444 | if os.path.exists(os.path.join(builddir, "layers")): |
| 445 | print("Build already initialized in {}\nUse 'bitbake-setup status' to check if it needs to be updated or 'bitbake-setup update' to perform the update.".format(builddir)) | 445 | print("Build already initialized in {}\nUse 'bitbake-setup status' to check if it needs to be updated or 'bitbake-setup update' to perform the update.".format(builddir)) |
| 446 | return | 446 | return |
| @@ -511,7 +511,7 @@ def are_layers_changed(layers, layerdir, d): | |||
| 511 | 511 | ||
| 512 | return changed | 512 | return changed |
| 513 | 513 | ||
| 514 | def build_status(settings, args, d, update=False): | 514 | def build_status(top_dir, settings, args, d, update=False): |
| 515 | builddir = args.build_dir | 515 | builddir = args.build_dir |
| 516 | 516 | ||
| 517 | confdir = os.path.join(builddir, "config") | 517 | confdir = os.path.join(builddir, "config") |
| @@ -523,7 +523,7 @@ def build_status(settings, args, d, update=False): | |||
| 523 | args.non_interactive = True | 523 | args.non_interactive = True |
| 524 | args.skip_selection = current_upstream_config['skip-selection'] | 524 | args.skip_selection = current_upstream_config['skip-selection'] |
| 525 | source_overrides = current_upstream_config["source-overrides"] | 525 | source_overrides = current_upstream_config["source-overrides"] |
| 526 | new_upstream_config = obtain_config(settings, args, source_overrides, d) | 526 | new_upstream_config = obtain_config(top_dir, settings, args, source_overrides, d) |
| 527 | 527 | ||
| 528 | write_config(new_upstream_config, confdir) | 528 | write_config(new_upstream_config, confdir) |
| 529 | config_diff = bb.process.run('git -C {} diff'.format(confdir))[0] | 529 | config_diff = bb.process.run('git -C {} diff'.format(confdir))[0] |
| @@ -544,8 +544,8 @@ def build_status(settings, args, d, update=False): | |||
| 544 | 544 | ||
| 545 | print("\nConfiguration in {} has not changed.".format(builddir)) | 545 | print("\nConfiguration in {} has not changed.".format(builddir)) |
| 546 | 546 | ||
| 547 | def build_update(settings, args, d): | 547 | def build_update(top_dir, settings, args, d): |
| 548 | build_status(settings, args, d, update=True) | 548 | build_status(top_dir, settings, args, d, update=True) |
| 549 | 549 | ||
| 550 | def do_fetch(fetcher, dir): | 550 | def do_fetch(fetcher, dir): |
| 551 | # git fetcher simply dumps git output to stdout; in bitbake context that is redirected to temp/log.do_fetch | 551 | # git fetcher simply dumps git output to stdout; in bitbake context that is redirected to temp/log.do_fetch |
| @@ -595,8 +595,8 @@ def list_registry(registry_path, with_expired): | |||
| 595 | json_data[config_name] = {"description": config_desc} | 595 | json_data[config_name] = {"description": config_desc} |
| 596 | return json_data | 596 | return json_data |
| 597 | 597 | ||
| 598 | def list_configs(settings, args, d): | 598 | def list_configs(top_dir, settings, args, d): |
| 599 | registry_path = update_registry(settings["default"]["registry"], cache_dir(args.top_dir), d) | 599 | registry_path = update_registry(settings["default"]["registry"], cache_dir(top_dir), d) |
| 600 | json_data = list_registry(registry_path, args.with_expired) | 600 | json_data = list_registry(registry_path, args.with_expired) |
| 601 | print("\nAvailable configurations:") | 601 | print("\nAvailable configurations:") |
| 602 | for config_name, config_data in json_data.items(): | 602 | for config_name, config_data in json_data.items(): |
| @@ -614,7 +614,7 @@ def list_configs(settings, args, d): | |||
| 614 | json.dump(json_data, f, sort_keys=True, indent=4) | 614 | json.dump(json_data, f, sort_keys=True, indent=4) |
| 615 | print("Available configurations written into {}".format(args.write_json)) | 615 | print("Available configurations written into {}".format(args.write_json)) |
| 616 | 616 | ||
| 617 | def install_buildtools(settings, args, d): | 617 | def install_buildtools(top_dir, settings, args, d): |
| 618 | buildtools_install_dir = os.path.join(args.build_dir, 'buildtools') | 618 | buildtools_install_dir = os.path.join(args.build_dir, 'buildtools') |
| 619 | if os.path.exists(buildtools_install_dir): | 619 | if os.path.exists(buildtools_install_dir): |
| 620 | if not args.force: | 620 | if not args.force: |
| @@ -634,117 +634,113 @@ def install_buildtools(settings, args, d): | |||
| 634 | subprocess.check_call("{} -d {} --downloads-directory {}".format(install_buildtools, buildtools_install_dir, buildtools_download_dir), shell=True) | 634 | subprocess.check_call("{} -d {} --downloads-directory {}".format(install_buildtools, buildtools_install_dir, buildtools_download_dir), shell=True) |
| 635 | 635 | ||
| 636 | def default_settings_path(top_dir): | 636 | def default_settings_path(top_dir): |
| 637 | return os.path.join(top_dir, 'bitbake-setup.conf') | 637 | return os.path.join(top_dir, 'settings.conf') |
| 638 | 638 | ||
| 639 | def write_settings(top_dir, force_replace, non_interactive=True): | 639 | def create_settings(top_dir, non_interactive=True): |
| 640 | settings_path = default_settings_path(top_dir) | 640 | settings_path = default_settings_path(top_dir) |
| 641 | if not os.path.exists(settings_path) or force_replace: | 641 | settings = configparser.ConfigParser() |
| 642 | 642 | settings['default'] = { | |
| 643 | settings = configparser.ConfigParser() | 643 | } |
| 644 | settings['default'] = { | 644 | os.makedirs(os.path.dirname(settings_path), exist_ok=True) |
| 645 | 'registry':default_registry, | 645 | |
| 646 | 'dl-dir':os.path.join(top_dir, '.bitbake-setup-downloads'), | 646 | siteconfpath = os.path.join(top_dir, 'site.conf') |
| 647 | } | 647 | print('A new empty settings file will be created in (you can add settings to it to override defaults from the global settings file)\n {}\n'.format(settings_path)) |
| 648 | os.makedirs(os.path.dirname(settings_path), exist_ok=True) | 648 | print('A common site.conf file will be created, please edit or replace before running builds\n {}\n'.format(siteconfpath)) |
| 649 | 649 | if not non_interactive: | |
| 650 | siteconfpath = os.path.join(top_dir, 'site.conf') | 650 | y_or_n = input('Bitbake-setup will be configured with the above settings in {}, (y/N): '.format(top_dir)) |
| 651 | print('Configuration registry set to\n {}\n'.format(settings['default']['registry'])) | 651 | if y_or_n != 'y': |
| 652 | print('Bitbake-setup download cache (DL_DIR) set to\n {}\n'.format(settings['default']['dl-dir'])) | 652 | print("\nYou can run 'bitbake-setup install-settings' to edit them before setting up builds") |
| 653 | print('A new settings file will be created in\n {}\n'.format(settings_path)) | 653 | exit() |
| 654 | print('A common site.conf file will be created, please edit or replace before running builds\n {}\n'.format(siteconfpath)) | 654 | print() |
| 655 | if not non_interactive: | ||
| 656 | y_or_n = input('Bitbake-setup will be configured with the above settings in {}, (y/N): '.format(top_dir)) | ||
| 657 | if y_or_n != 'y': | ||
| 658 | print("\nYou can run 'bitbake-setup install-settings' to edit them before setting up builds") | ||
| 659 | exit() | ||
| 660 | print() | ||
| 661 | |||
| 662 | if os.path.exists(settings_path): | ||
| 663 | backup_conf = settings_path + "-backup.{}".format(time.strftime("%Y%m%d%H%M%S")) | ||
| 664 | os.rename(settings_path, backup_conf) | ||
| 665 | print("Previous settings are in {}".format(backup_conf)) | ||
| 666 | with open(settings_path, 'w') as settingsfile: | ||
| 667 | settings.write(settingsfile) | ||
| 668 | |||
| 669 | if os.path.exists(siteconfpath): | ||
| 670 | backup_siteconf = siteconfpath + "-backup.{}".format(time.strftime("%Y%m%d%H%M%S")) | ||
| 671 | os.rename(siteconfpath, backup_siteconf) | ||
| 672 | print("Previous settings are in {}".format(backup_siteconf)) | ||
| 673 | with open(siteconfpath, 'w') as siteconffile: | ||
| 674 | siteconffile.write('# This file is intended for build host-specific bitbake settings\n') | ||
| 675 | 655 | ||
| 676 | def load_settings(top_dir, non_interactive): | 656 | if os.path.exists(settings_path): |
| 677 | # This creates a new settings file if it does not yet exist | 657 | backup_conf = settings_path + "-backup.{}".format(time.strftime("%Y%m%d%H%M%S")) |
| 678 | write_settings(top_dir, force_replace=False, non_interactive=non_interactive) | 658 | os.rename(settings_path, backup_conf) |
| 659 | print("Previous settings are in {}".format(backup_conf)) | ||
| 660 | with open(settings_path, 'w') as settingsfile: | ||
| 661 | settings.write(settingsfile) | ||
| 662 | |||
| 663 | if os.path.exists(siteconfpath): | ||
| 664 | backup_siteconf = siteconfpath + "-backup.{}".format(time.strftime("%Y%m%d%H%M%S")) | ||
| 665 | os.rename(siteconfpath, backup_siteconf) | ||
| 666 | print("Previous settings are in {}".format(backup_siteconf)) | ||
| 667 | with open(siteconfpath, 'w') as siteconffile: | ||
| 668 | siteconffile.write('# This file is intended for build host-specific bitbake settings\n') | ||
| 679 | 669 | ||
| 670 | def load_settings(top_dir, non_interactive): | ||
| 680 | settings_path = default_settings_path(top_dir) | 671 | settings_path = default_settings_path(top_dir) |
| 672 | if not os.path.exists(settings_path): | ||
| 673 | create_settings(top_dir, non_interactive=non_interactive) | ||
| 674 | |||
| 681 | settings = configparser.ConfigParser() | 675 | settings = configparser.ConfigParser() |
| 682 | print('Loading settings from\n {}\n'.format(settings_path)) | 676 | print('Loading settings from\n {}\n'.format(settings_path)) |
| 683 | settings.read_file(open(settings_path)) | 677 | settings.read_file(open(settings_path)) |
| 684 | return settings | 678 | return settings |
| 685 | 679 | ||
| 686 | def global_settings_path(args): | 680 | def global_settings_path(args): |
| 687 | return os.path.abspath(args.global_settings) if args.global_settings else os.path.join(os.path.expanduser('~'), '.config', 'bitbake-setup', 'config') | 681 | return os.path.abspath(args.global_settings) if args.global_settings else os.path.join(os.path.expanduser('~'), '.config', 'bitbake-setup', 'settings.conf') |
| 688 | 682 | ||
| 689 | def write_global_settings(settings_path, force_replace, non_interactive=True): | 683 | def create_global_settings(settings_path, non_interactive=True): |
| 690 | if not os.path.exists(settings_path) or force_replace: | 684 | settings = configparser.ConfigParser() |
| 691 | 685 | settings['default'] = { | |
| 692 | settings = configparser.ConfigParser() | 686 | 'top-dir-prefix':os.path.expanduser('~'), |
| 693 | settings['default'] = { | 687 | 'top-dir-name':'bitbake-builds', |
| 694 | 'top-dir-prefix':os.path.expanduser('~'), | 688 | 'registry':default_registry, |
| 695 | 'top-dir-name':'bitbake-builds' | 689 | 'dl-dir':os.path.join(os.path.expanduser('~'), '.cache', 'bitbake-setup', 'downloads'), |
| 696 | } | 690 | } |
| 697 | os.makedirs(os.path.dirname(settings_path), exist_ok=True) | 691 | os.makedirs(os.path.dirname(settings_path), exist_ok=True) |
| 698 | print('Configuring global settings in\n {}\n'.format(settings_path)) | 692 | print('Configuring global settings in\n {}\n'.format(settings_path)) |
| 699 | print('Top directory prefix (where all top level directories are created) set to\n {}\n'.format(settings['default']['top-dir-prefix'])) | 693 | print('Top directory prefix (where all top level directories are created) set to\n {}\n'.format(settings['default']['top-dir-prefix'])) |
| 700 | print('Top directory name (this is added to the top directory prefix to form a top directory where builds are set up) set to\n {}\n'.format(settings['default']['top-dir-name'])) | 694 | print('Top directory name (this is added to the top directory prefix to form a top directory where builds are set up) set to\n {}\n'.format(settings['default']['top-dir-name'])) |
| 701 | if not non_interactive: | 695 | print('Configuration registry set to\n {}\n'.format(settings['default']['registry'])) |
| 702 | y_or_n = input('Write out the global settings as specified above (y/N)? ') | 696 | print('Bitbake-setup download cache (DL_DIR) set to\n {}\n'.format(settings['default']['dl-dir'])) |
| 703 | if y_or_n != 'y': | 697 | if not non_interactive: |
| 704 | print("\nYou can run 'bitbake-setup install-global-settings' to edit them before setting up builds") | 698 | y_or_n = input('Write out the global settings as specified above (y/N)? ') |
| 705 | exit() | 699 | if y_or_n != 'y': |
| 706 | print() | 700 | print("\nYou can run 'bitbake-setup install-global-settings' to edit them before setting up builds") |
| 707 | 701 | exit() | |
| 708 | if os.path.exists(settings_path): | 702 | print() |
| 709 | backup_conf = settings_path + "-backup.{}".format(time.strftime("%Y%m%d%H%M%S")) | 703 | |
| 710 | os.rename(settings_path, backup_conf) | 704 | if os.path.exists(settings_path): |
| 711 | print("Previous global settings are in {}".format(backup_conf)) | 705 | backup_conf = settings_path + "-backup.{}".format(time.strftime("%Y%m%d%H%M%S")) |
| 712 | with open(settings_path, 'w') as settingsfile: | 706 | os.rename(settings_path, backup_conf) |
| 713 | settings.write(settingsfile) | 707 | print("Previous global settings are in {}".format(backup_conf)) |
| 708 | with open(settings_path, 'w') as settingsfile: | ||
| 709 | settings.write(settingsfile) | ||
| 714 | 710 | ||
| 715 | def load_global_settings(settings_path, non_interactive): | 711 | def load_global_settings(settings_path, non_interactive): |
| 716 | # This creates a new settings file if it does not yet exist | 712 | if not os.path.exists(settings_path): |
| 717 | write_global_settings(settings_path, force_replace=False, non_interactive=non_interactive) | 713 | create_global_settings(settings_path, non_interactive=non_interactive) |
| 718 | 714 | ||
| 719 | settings = configparser.ConfigParser() | 715 | settings = configparser.ConfigParser() |
| 720 | print('Loading global settings from\n {}\n'.format(settings_path)) | 716 | print('Loading global settings from\n {}\n'.format(settings_path)) |
| 721 | settings.read_file(open(settings_path)) | 717 | settings.read_file(open(settings_path)) |
| 722 | return settings | 718 | return settings |
| 723 | 719 | ||
| 724 | def change_settings(top_dir, new_settings): | 720 | def change_setting(settings_path, settings, args): |
| 725 | settings = load_settings(top_dir, non_interactive=True) | 721 | if args.section and args.key and args.value: |
| 726 | for section, section_settings in new_settings.items(): | 722 | settings[args.section][args.key] = args.value |
| 727 | for setting, value in section_settings.items(): | 723 | print("Setting '{}' in section '{}' is changed to '{}'".format(args.key, args.section, args.value)) |
| 728 | settings[section][setting] = value | 724 | if args.unset: |
| 729 | print("Setting '{}' in section '{}' is changed to '{}'".format(setting, section, value)) | 725 | section = args.unset[0] |
| 726 | setting = args.unset[1] | ||
| 727 | if section in settings.keys() and setting in settings[section].keys(): | ||
| 728 | del settings[section][setting] | ||
| 729 | print("Setting '{} in section '{}' is removed".format(setting, section)) | ||
| 730 | 730 | ||
| 731 | settings_path = default_settings_path(top_dir) | ||
| 732 | with open(settings_path, 'w') as settingsfile: | 731 | with open(settings_path, 'w') as settingsfile: |
| 733 | settings.write(settingsfile) | 732 | settings.write(settingsfile) |
| 734 | print("New settings written to {}".format(settings_path)) | 733 | print("New settings written to {}".format(settings_path)) |
| 735 | return settings | ||
| 736 | 734 | ||
| 737 | def change_global_settings(settings_path, new_settings): | 735 | def setting_global(args): |
| 738 | settings = load_global_settings(settings_path, non_interactive=True) | 736 | settings = load_global_settings(global_settings_path(args), args.non_interactive) |
| 739 | for section, section_settings in new_settings.items(): | 737 | settings_path = global_settings_path(args) |
| 740 | for setting, value in section_settings.items(): | 738 | change_setting(settings_path, settings, args) |
| 741 | settings[section][setting] = value | ||
| 742 | print("Setting '{}' in section '{}' is changed to '{}'".format(setting, section, value)) | ||
| 743 | 739 | ||
| 744 | with open(settings_path, 'w') as settingsfile: | 740 | def setting(top_dir, args): |
| 745 | settings.write(settingsfile) | 741 | settings = load_settings(top_dir, args.non_interactive) |
| 746 | print("New global settings written to {}".format(settings_path)) | 742 | settings_path = default_settings_path(top_dir) |
| 747 | return settings | 743 | change_setting(settings_path, settings, args) |
| 748 | 744 | ||
| 749 | def get_build_dir_via_bbpath(): | 745 | def get_build_dir_via_bbpath(): |
| 750 | bbpath = os.environ.get('BBPATH') | 746 | bbpath = os.environ.get('BBPATH') |
| @@ -755,7 +751,7 @@ def get_build_dir_via_bbpath(): | |||
| 755 | return build_dir | 751 | return build_dir |
| 756 | return None | 752 | return None |
| 757 | 753 | ||
| 758 | def get_top_dir(args, global_settings): | 754 | def get_top_dir(args, settings): |
| 759 | build_dir_via_bbpath = get_build_dir_via_bbpath() | 755 | build_dir_via_bbpath = get_build_dir_via_bbpath() |
| 760 | if build_dir_via_bbpath: | 756 | if build_dir_via_bbpath: |
| 761 | top_dir = os.path.dirname(build_dir_via_bbpath) | 757 | top_dir = os.path.dirname(build_dir_via_bbpath) |
| @@ -763,20 +759,25 @@ def get_top_dir(args, global_settings): | |||
| 763 | return top_dir | 759 | return top_dir |
| 764 | 760 | ||
| 765 | if hasattr(args, 'build_dir'): | 761 | if hasattr(args, 'build_dir'): |
| 766 | # commands without --top-dir-prefix/name arguments (status, update) still need to know where | ||
| 767 | # the top dir is, but it should be auto-deduced as parent of args.build_dir | ||
| 768 | top_dir = os.path.dirname(os.path.normpath(args.build_dir)) | 762 | top_dir = os.path.dirname(os.path.normpath(args.build_dir)) |
| 769 | return top_dir | 763 | return top_dir |
| 770 | 764 | ||
| 771 | top_dir_prefix = args.top_dir_prefix if args.top_dir_prefix else global_settings['default']['top-dir-prefix'] | 765 | top_dir_prefix = settings['default']['top-dir-prefix'] |
| 772 | top_dir_name = args.top_dir_name if args.top_dir_name else global_settings['default']['top-dir-name'] | 766 | top_dir_name = settings['default']['top-dir-name'] |
| 773 | return os.path.join(top_dir_prefix, top_dir_name) | 767 | return os.path.join(top_dir_prefix, top_dir_name) |
| 774 | 768 | ||
| 775 | def main(): | 769 | def merge_settings(global_settings, local_settings, cmdline_settings): |
| 776 | def add_top_dir_arg(parser): | 770 | all_settings = global_settings |
| 777 | parser.add_argument('--top-dir-prefix', help='Top level directory prefix. This is where all top level directories are created.') | 771 | for section, section_settings in local_settings.items(): |
| 778 | parser.add_argument('--top-dir-name', help='Top level directory name. Together with the top directory prefix this forms a top directory where builds are set up and downloaded configurations and layers are cached for reproducibility and offline builds.') | 772 | for setting, value in section_settings.items(): |
| 773 | all_settings[section][setting] = value | ||
| 774 | |||
| 775 | for (section, setting, value) in cmdline_settings: | ||
| 776 | all_settings[section][setting] = value | ||
| 777 | |||
| 778 | return all_settings | ||
| 779 | 779 | ||
| 780 | def main(): | ||
| 780 | def add_build_dir_arg(parser): | 781 | def add_build_dir_arg(parser): |
| 781 | build_dir = get_build_dir_via_bbpath() | 782 | build_dir = get_build_dir_via_bbpath() |
| 782 | if build_dir: | 783 | if build_dir: |
| @@ -792,18 +793,17 @@ def main(): | |||
| 792 | parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true') | 793 | parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true') |
| 793 | parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR') | 794 | parser.add_argument('--color', choices=['auto', 'always', 'never'], default='auto', help='Colorize output (where %(metavar)s is %(choices)s)', metavar='COLOR') |
| 794 | parser.add_argument('--no-network', action='store_true', help='Do not check whether configuration repositories and layer repositories have been updated; use only the local cache.') | 795 | parser.add_argument('--no-network', action='store_true', help='Do not check whether configuration repositories and layer repositories have been updated; use only the local cache.') |
| 795 | parser.add_argument('--global-settings', action='store', help='Path to the global settings file where defaults for top directory prefix and name can be specified') | 796 | parser.add_argument('--global-settings', action='store', help='Path to the global settings file.') |
| 797 | parser.add_argument('--setting', default=[], action='append', nargs=3, help='Modify a setting (for this bitbake-setup invocation only), for example "--setting default top-dir-prefix /path/to/top/dir".') | ||
| 796 | 798 | ||
| 797 | subparsers = parser.add_subparsers() | 799 | subparsers = parser.add_subparsers() |
| 798 | 800 | ||
| 799 | parser_list = subparsers.add_parser('list', help='List available configurations') | 801 | parser_list = subparsers.add_parser('list', help='List available configurations') |
| 800 | add_top_dir_arg(parser_list) | ||
| 801 | parser_list.add_argument('--with-expired', action='store_true', help='List also configurations that are no longer supported due to reaching their end-of-life dates.') | 802 | parser_list.add_argument('--with-expired', action='store_true', help='List also configurations that are no longer supported due to reaching their end-of-life dates.') |
| 802 | parser_list.add_argument('--write-json', action='store', help='Write available configurations into a json file so they can be programmatically processed.') | 803 | parser_list.add_argument('--write-json', action='store', help='Write available configurations into a json file so they can be programmatically processed.') |
| 803 | parser_list.set_defaults(func=list_configs) | 804 | parser_list.set_defaults(func=list_configs) |
| 804 | 805 | ||
| 805 | parser_init = subparsers.add_parser('init', help='Select a configuration and initialize a build from it') | 806 | parser_init = subparsers.add_parser('init', help='Select a configuration and initialize a build from it') |
| 806 | add_top_dir_arg(parser_init) | ||
| 807 | parser_init.add_argument('config', nargs='*', help="path/URL/id to a configuration file (use 'list' command to get available ids), followed by configuration options. Bitbake-setup will ask to choose from available choices if command line doesn't completely specify them.") | 807 | parser_init.add_argument('config', nargs='*', help="path/URL/id to a configuration file (use 'list' command to get available ids), followed by configuration options. Bitbake-setup will ask to choose from available choices if command line doesn't completely specify them.") |
| 808 | parser_init.add_argument('--non-interactive', action='store_true', help='Do not ask to interactively choose from available options; if bitbake-setup cannot make a decision it will stop with a failure.') | 808 | parser_init.add_argument('--non-interactive', action='store_true', help='Do not ask to interactively choose from available options; if bitbake-setup cannot make a decision it will stop with a failure.') |
| 809 | parser_init.add_argument('--source-overrides', action='store', help='Override sources information (repositories/revisions) with values from a local json file.') | 809 | parser_init.add_argument('--source-overrides', action='store', help='Override sources information (repositories/revisions) with values from a local json file.') |
| @@ -824,25 +824,16 @@ def main(): | |||
| 824 | parser_install_buildtools.add_argument('--force', action='store_true', help='Force a reinstall of buildtools over the previous installation.') | 824 | parser_install_buildtools.add_argument('--force', action='store_true', help='Force a reinstall of buildtools over the previous installation.') |
| 825 | parser_install_buildtools.set_defaults(func=install_buildtools) | 825 | parser_install_buildtools.set_defaults(func=install_buildtools) |
| 826 | 826 | ||
| 827 | parser_install_settings = subparsers.add_parser('install-settings', help='Write a settings file with default values into the top level directory (contains the location of build configuration registry, downloads directory and other settings specific to a top directory)') | 827 | parser_install_global_settings = subparsers.add_parser('install-global-settings', help='Write a global settings file with default values') |
| 828 | add_top_dir_arg(parser_install_settings) | 828 | parser_install_global_settings.set_defaults(func=create_global_settings) |
| 829 | parser_install_settings.set_defaults(func=write_settings) | ||
| 830 | |||
| 831 | parser_install_global_settings = subparsers.add_parser('install-global-settings', help='Write a global settings file with default values (contains the default prefix and name of the top directory)') | ||
| 832 | parser_install_global_settings.set_defaults(func=write_global_settings) | ||
| 833 | |||
| 834 | parser_change_setting = subparsers.add_parser('change-setting', help='Change a setting in the settings file') | ||
| 835 | add_top_dir_arg(parser_change_setting) | ||
| 836 | parser_change_setting.add_argument('section', help="Section in a settings file, typically 'default'") | ||
| 837 | parser_change_setting.add_argument('key', help="Name of the setting") | ||
| 838 | parser_change_setting.add_argument('value', help="Value of the setting") | ||
| 839 | parser_change_setting.set_defaults(func=change_settings) | ||
| 840 | 829 | ||
| 841 | parser_change_global_setting = subparsers.add_parser('change-global-setting', help='Change a setting in the global settings file') | 830 | parser_setting = subparsers.add_parser('setting', help='Set or unset a setting in a setting file (e.g. the default prefix and name of the top directory, the location of build configuration registry, downloads directory and other settings specific to a top directory)') |
| 842 | parser_change_global_setting.add_argument('section', help="Section in a global settings file, typically 'default'") | 831 | parser_setting.add_argument('section', nargs='?', help="Section in a settings file, typically 'default'") |
| 843 | parser_change_global_setting.add_argument('key', help="Name of the setting") | 832 | parser_setting.add_argument('key', nargs='?', help="Name of the setting") |
| 844 | parser_change_global_setting.add_argument('value', help="Value of the setting") | 833 | parser_setting.add_argument('value', nargs='?', help="Value of the setting") |
| 845 | parser_change_global_setting.set_defaults(func=change_global_settings) | 834 | parser_setting.add_argument('--global', action='store_true', help="Modify the setting in a global settings file, rather than one specific to a top directory") |
| 835 | parser_setting.add_argument('--unset', nargs=2, help="Unset a setting, e.g. 'bitbake-setup setting --unset default registry' would revert to the registry setting in a global settings file") | ||
| 836 | parser_setting.set_defaults(func=setting) | ||
| 846 | 837 | ||
| 847 | args = parser.parse_args() | 838 | args = parser.parse_args() |
| 848 | 839 | ||
| @@ -859,11 +850,8 @@ def main(): | |||
| 859 | level=logger.getEffectiveLevel()) | 850 | level=logger.getEffectiveLevel()) |
| 860 | 851 | ||
| 861 | if 'func' in args: | 852 | if 'func' in args: |
| 862 | if args.func == write_global_settings: | 853 | if args.func == create_global_settings: |
| 863 | write_global_settings(global_settings_path(args), force_replace=True) | 854 | create_global_settings(global_settings_path(args)) |
| 864 | return | ||
| 865 | elif args.func == change_global_settings: | ||
| 866 | change_global_settings(global_settings_path(args), {args.section:{args.key:args.value}}) | ||
| 867 | return | 855 | return |
| 868 | 856 | ||
| 869 | if hasattr(args, 'build_dir'): | 857 | if hasattr(args, 'build_dir'): |
| @@ -874,19 +862,24 @@ def main(): | |||
| 874 | if not hasattr(args, 'non_interactive'): | 862 | if not hasattr(args, 'non_interactive'): |
| 875 | args.non_interactive = True | 863 | args.non_interactive = True |
| 876 | 864 | ||
| 865 | if args.func == setting and vars(args)['global']: | ||
| 866 | setting_global(args) | ||
| 867 | return | ||
| 868 | |||
| 877 | global_settings = load_global_settings(global_settings_path(args), args.non_interactive) | 869 | global_settings = load_global_settings(global_settings_path(args), args.non_interactive) |
| 878 | args.top_dir = get_top_dir(args, global_settings) | 870 | top_dir = get_top_dir(args, merge_settings(global_settings, {}, args.setting)) |
| 879 | 871 | ||
| 880 | print('Bitbake-setup is using {} as top directory (can be changed with --top-dir-prefix/name arguments or by setting them in {}).\n'.format(args.top_dir, global_settings_path(args))) | 872 | if args.func == setting: |
| 881 | if args.func == write_settings: | 873 | setting(top_dir, args) |
| 882 | write_settings(args.top_dir, force_replace=True) | 874 | return |
| 883 | elif args.func == change_settings: | 875 | |
| 884 | change_settings(args.top_dir, {args.section:{args.key:args.value}}) | 876 | print('Bitbake-setup is using {} as top directory (can be changed by setting top dir prefix and name in {}).\n'.format(top_dir, global_settings_path(args))) |
| 885 | else: | 877 | |
| 886 | settings = load_settings(args.top_dir, args.non_interactive) | 878 | settings = load_settings(top_dir, args.non_interactive) |
| 887 | d = init_bb_cache(settings, args) | 879 | settings = merge_settings(global_settings, settings, args.setting) |
| 888 | args.func(settings, args, d) | 880 | d = init_bb_cache(top_dir, settings, args) |
| 889 | save_bb_cache() | 881 | args.func(top_dir, settings, args, d) |
| 882 | save_bb_cache() | ||
| 890 | else: | 883 | else: |
| 891 | from argparse import Namespace | 884 | from argparse import Namespace |
| 892 | parser.print_help() | 885 | parser.print_help() |
diff --git a/bitbake/lib/bb/tests/setup.py b/bitbake/lib/bb/tests/setup.py index 495d1da203..22edda40e4 100644 --- a/bitbake/lib/bb/tests/setup.py +++ b/bitbake/lib/bb/tests/setup.py | |||
| @@ -235,16 +235,18 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"])) | |||
| 235 | out = self.runbbsetup("install-global-settings") | 235 | out = self.runbbsetup("install-global-settings") |
| 236 | settings_path = "{}/global-config".format(self.tempdir) | 236 | settings_path = "{}/global-config".format(self.tempdir) |
| 237 | self.assertIn(settings_path, out[0]) | 237 | self.assertIn(settings_path, out[0]) |
| 238 | out = self.runbbsetup("change-global-setting default top-dir-prefix {}".format(self.tempdir)) | 238 | out = self.runbbsetup("setting --global default top-dir-prefix {}".format(self.tempdir)) |
| 239 | self.assertIn("Setting 'top-dir-prefix' in section 'default' is changed to", out[0]) | 239 | self.assertIn("Setting 'top-dir-prefix' in section 'default' is changed to", out[0]) |
| 240 | self.assertIn("New global settings written to".format(settings_path), out[0]) | 240 | self.assertIn("New settings written to".format(settings_path), out[0]) |
| 241 | out = self.runbbsetup("setting --global default dl-dir {}".format(os.path.join(self.tempdir, 'downloads'))) | ||
| 242 | self.assertIn("Setting 'dl-dir' in section 'default' is changed to", out[0]) | ||
| 243 | self.assertIn("New settings written to".format(settings_path), out[0]) | ||
| 241 | 244 | ||
| 242 | # check that writing settings works and then adjust them to point to | 245 | # check that writing settings works and then adjust them to point to |
| 243 | # test registry repo | 246 | # test registry repo |
| 244 | out = self.runbbsetup("install-settings") | 247 | out = self.runbbsetup("setting default registry 'git://{};protocol=file;branch=master;rev=master'".format(self.registrypath)) |
| 245 | settings_path = "{}/bitbake-builds/bitbake-setup.conf".format(self.tempdir) | 248 | settings_path = "{}/bitbake-builds/settings.conf".format(self.tempdir) |
| 246 | self.assertIn(settings_path, out[0]) | 249 | self.assertIn(settings_path, out[0]) |
| 247 | out = self.runbbsetup("change-setting default registry 'git://{};protocol=file;branch=master;rev=master'".format(self.registrypath)) | ||
| 248 | self.assertIn("Setting 'registry' in section 'default' is changed to", out[0]) | 250 | self.assertIn("Setting 'registry' in section 'default' is changed to", out[0]) |
| 249 | self.assertIn("New settings written to".format(settings_path), out[0]) | 251 | self.assertIn("New settings written to".format(settings_path), out[0]) |
| 250 | 252 | ||
