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 | ||