# # Copyright (C) 2018 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """A commandline tool to check and update packages in external/
import fileutils import git_utils import updater_utils from base_updater import Updater from color import Color, color_string from crates_updater import CratesUpdater from git_updater import GitUpdater from github_archive_updater import GithubArchiveUpdater
try:
rel_proj_path = str(fileutils.get_relative_project_path(full_path)) except ValueError: # Absolute paths to other trees will not be relative to our tree. # There are no portable instructions for upgrading that project, # since the path will differ between machines (or checkouts).
rel_proj_path = "<absolute path to project>"
commit_message = commit_message_generator(metadata.name, updater.latest_version, rel_proj_path, args.bug)
git_utils.remove_gitmodules(full_path)
git_utils.add_file(full_path, '*')
git_utils.commit(full_path, commit_message, args.no_verify)
def has_new_version(updater: Updater) -> bool: """Checks if a newer version of the project is available.""" if updater.latest_version isnotNone: if updater.current_version != updater.latest_version or updater.alternative_latest_version isnotNone: returnTrue returnFalse
def check_if_on_latest_tag_but_newer_sha_available(updater: Updater) -> bool: """This is an edge case where METADATA is on the latest tag but there is a newer SHA available.""" if updater.current_version == updater.latest_version and updater.alternative_latest_version isnotNone: returnTrue returnFalse
def print_project_status(updater: Updater) -> None: """Prints the current status of the project on console."""
out_of_date_question = f'Would you like to upgrade to {alternative_ver_type} {alternative_version} instead of {latest_ver_type} {latest_version}? (yes/no)\n'
up_to_date_question = f'Would you like to upgrade to {alternative_ver_type} {alternative_version}? (yes/no)\n'
recom_message = color_string(f'We recommend upgrading to {alternative_ver_type} {alternative_version} instead. ', Color.FRESH)
not_recom_message = color_string(f'We DO NOT recommend upgrading to {alternative_ver_type} {alternative_version}. ', Color.STALE)
answer = input(warning) if"yes".startswith(answer.lower()): returnTrue elif answer.lower().startswith("no"): returnFalse # If user types something that is not "yes" or "no" or something similar, abort. else: raise ValueError(f"Invalid input: {answer}")
def check_and_update(args: argparse.Namespace,
proj_path: Path,
update_lib=False) -> Union[Updater, str]: """Checks updates for a project.
Args:
args: commandline arguments
proj_path: Absolute or relative path to the project.
update_lib: Iffalse, will only check for new version, but not update. """
if update_lib: if args.custom_version isnotNone:
updater.set_custom_version(args.custom_version)
print(f"Upgrading to custom version {args.custom_version}") elif args.refresh:
updater.refresh_without_upgrading() elif new_version_available: if updater.alternative_latest_version isnotNone: if use_alternative_version(updater):
updater.set_new_version(updater.alternative_latest_version) else: return updater
_do_update(args, updater, metadata) return updater
# pylint: disable=broad-except except Exception as err:
logging.exception("Failed to check or update %s", proj_path) return str(err)
def check_and_update_path(args: argparse.Namespace, paths: Iterable[Path],
update_lib: bool,
delay: int) -> Dict[str, Dict[str, str]]:
results = {} for path in paths:
res = {}
updater = check_and_update(args, path, update_lib) if isinstance(updater, str):
res['error'] = updater else:
res['current'] = updater.current_version
res['latest'] = updater.latest_version
results[str(fileutils.canonicalize_project_path(path))] = res
time.sleep(delay) return results
def _list_all_metadata() -> Iterator[str]: for path, dirs, files in os.walk(fileutils.external_path()): if fileutils.METADATA_FILENAME in files: # Skip sub directories.
dirs[:] = [] yield path
dirs.sort(key=lambda d: d.lower())
def write_json(json_file: str, results: Dict[str, Dict[str, str]]) -> None: """Output a JSON report.""" with Path(json_file).open('w', encoding='utf-8') as res_file:
json.dump(results, res_file, sort_keys=True, indent=4)
def validate(args: argparse.Namespace) -> None: """Handler for validate command."""
paths = fileutils.resolve_command_line_paths(args.paths) try:
canonical_path = fileutils.canonicalize_project_path(paths[0])
print(f'Validating {canonical_path}...')
updater, _ = build_updater(paths[0])
print('Difference with upstream:')
updater.validate() except Exception: # pylint: disable=broad-exception-caught
logging.exception("Failed to check or update %s", paths)
def check(args: argparse.Namespace) -> None: """Handler for check command.""" if args.all:
paths = [Path(p) for p in _list_all_metadata()] else:
paths = fileutils.resolve_command_line_paths(args.paths)
results = check_and_update_path(args, paths, False, args.delay)
if args.json_output isnotNone:
write_json(args.json_output, results)
def update(args: argparse.Namespace) -> None: """Handler for update command."""
all_paths = fileutils.resolve_command_line_paths(args.paths) # Remove excluded paths.
excludes = set() if args.exclude isNoneelse set(args.exclude)
filtered_paths = [path for path in all_paths ifnot path.name in excludes] # Now we can update each path.
results = check_and_update_path(args, filtered_paths, True, 0)
if args.json_output isnotNone:
write_json(args.json_output, results)
parser = argparse.ArgumentParser(
prog='tools/external_updater/updater.sh',
description='Check updates for third party projects in external/.')
subparsers = parser.add_subparsers(dest='cmd')
subparsers.required = True
# Creates parser for check command.
check_parser = subparsers.add_parser( 'check',
help='Check update for one project.')
check_parser.add_argument( 'paths',
nargs='*',
help='Paths of the project. ' 'Relative paths will be resolved from external/.')
check_parser.add_argument( '--json-output',
help='Path of a json file to write result to.')
check_parser.add_argument( '--all',
action='store_true',
help='If set, check updates for all supported projects.')
check_parser.add_argument( '--delay',
default=0,
type=int,
help='Time in seconds to wait between checking two projects.')
check_parser.set_defaults(func=check)
# Creates parser for update command.
update_parser = subparsers.add_parser( 'update',
help='Update one project.')
update_parser.add_argument( 'paths',
nargs='*',
help='Paths of the project as globs.')
update_parser.add_argument( '--no-build',
action='store_false',
dest='build',
help='Skip building')
update_parser.add_argument( '--no-upload',
action='store_true',
help='Does not upload to Gerrit after upgrade')
update_parser.add_argument( '--bug',
type=int,
help='Bug number for this update')
update_parser.add_argument( '--custom-version',
type=str,
help='Custom version we want to upgrade to.')
update_parser.add_argument( '--skip-post-update',
action='store_true',
help='Skip post_update script if post_update script exists')
update_parser.add_argument( '--keep-local-changes',
action='store_true',
help='Updates the current branch instead of creating a new branch')
update_parser.add_argument( '--no-verify',
action='store_true',
help='Pass --no-verify to git commit')
update_parser.add_argument( '--exclude',
action='append',
help='Names of projects to exclude. ' 'These are just the final part of the path ' 'with no directories.')
update_parser.add_argument( '--refresh',
help='Run update and refresh to the current version.',
action='store_true')
update_parser.add_argument( '--keep-date',
help='Run update and do not change date in METADATA.',
action='store_true')
update_parser.add_argument( '--json-output',
help='Path of a json file to write result to.')
update_parser.set_defaults(func=update)
diff_parser = subparsers.add_parser( 'validate',
help='Check if Android version is what it claims to be.')
diff_parser.add_argument( 'paths',
nargs='*',
help='Paths of the project.' 'Relative paths will be resolved from external/.')
diff_parser.set_defaults(func=validate)
return parser.parse_args()
def main() -> None: """The main entry."""
args = parse_args()
args.func(args)
if __name__ == '__main__':
main()
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.