diff options
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/python/qmk/cli/doctor/main.py | 26 | ||||
-rw-r--r-- | lib/python/qmk/git.py | 19 | ||||
-rw-r--r-- | lib/python/qmk/submodules.py | 26 |
3 files changed, 69 insertions, 2 deletions
diff --git a/lib/python/qmk/cli/doctor/main.py b/lib/python/qmk/cli/doctor/main.py index 2898a9894c..1600ab8dd4 100755 --- a/lib/python/qmk/cli/doctor/main.py +++ b/lib/python/qmk/cli/doctor/main.py @@ -11,7 +11,7 @@ from milc.questions import yesno from qmk import submodules from qmk.constants import QMK_FIRMWARE, QMK_FIRMWARE_UPSTREAM from .check import CheckStatus, check_binaries, check_binary_versions, check_submodules -from qmk.git import git_check_repo, git_get_branch, git_get_tag, git_is_dirty, git_get_remotes, git_check_deviation +from qmk.git import git_check_repo, git_get_branch, git_get_tag, git_get_last_log_entry, git_get_common_ancestor, git_is_dirty, git_get_remotes, git_check_deviation from qmk.commands import in_virtualenv @@ -66,10 +66,32 @@ def git_tests(): if git_branch in ['master', 'develop'] and git_deviation: cli.log.warning('{fg_yellow}The local "%s" branch contains commits not found in the upstream branch.', git_branch) status = CheckStatus.WARNING + for branch in [git_branch, 'upstream/master', 'upstream/develop']: + cli.log.info('- Latest %s: %s', branch, git_get_last_log_entry(branch)) + for branch in ['upstream/master', 'upstream/develop']: + cli.log.info('- Common ancestor with %s: %s', branch, git_get_common_ancestor(branch, 'HEAD')) return status +def output_submodule_status(): + """Prints out information related to the submodule status. + """ + cli.log.info('Submodule status:') + sub_status = submodules.status() + for s in sub_status.keys(): + sub_info = sub_status[s] + if 'name' in sub_info: + sub_name = sub_info['name'] + sub_shorthash = sub_info['shorthash'] if 'shorthash' in sub_info else '' + sub_describe = sub_info['describe'] if 'describe' in sub_info else '' + sub_last_log_timestamp = sub_info['last_log_timestamp'] if 'last_log_timestamp' in sub_info else '' + if sub_last_log_timestamp != '': + cli.log.info(f'- {sub_name}: {sub_last_log_timestamp} -- {sub_describe} ({sub_shorthash})') + else: + cli.log.error(f'- {sub_name}: <<< missing or unknown >>>') + + @cli.argument('-y', '--yes', action='store_true', arg_only=True, help='Answer yes to all questions.') @cli.argument('-n', '--no', action='store_true', arg_only=True, help='Answer no to all questions.') @cli.subcommand('Basic QMK environment checks') @@ -129,6 +151,8 @@ def doctor(cli): elif sub_ok == CheckStatus.WARNING and status == CheckStatus.OK: status = CheckStatus.WARNING + output_submodule_status() + # Report a summary of our findings to the user if status == CheckStatus.OK: cli.log.info('{fg_green}QMK is ready to go') diff --git a/lib/python/qmk/git.py b/lib/python/qmk/git.py index 960184a0a2..7fa0306f5c 100644 --- a/lib/python/qmk/git.py +++ b/lib/python/qmk/git.py @@ -62,6 +62,25 @@ def git_get_tag(): return git_tag.stdout.strip() +def git_get_last_log_entry(branch_name): + """Retrieves the last log entry for the branch being worked on. + """ + git_lastlog = cli.run(['git', '--no-pager', 'log', '--pretty=format:%ad (%h) -- %s', '--date=iso', '-n1', branch_name]) + + if git_lastlog.returncode == 0 and git_lastlog.stdout: + return git_lastlog.stdout.strip() + + +def git_get_common_ancestor(branch_a, branch_b): + """Retrieves the common ancestor between for the two supplied branches. + """ + git_merge_base = cli.run(['git', 'merge-base', branch_a, branch_b]) + git_branchpoint_log = cli.run(['git', '--no-pager', 'log', '--pretty=format:%ad (%h) -- %s', '--date=iso', '-n1', git_merge_base.stdout.strip()]) + + if git_branchpoint_log.returncode == 0 and git_branchpoint_log.stdout: + return git_branchpoint_log.stdout.strip() + + def git_get_remotes(): """Returns the current remotes for a repo. """ diff --git a/lib/python/qmk/submodules.py b/lib/python/qmk/submodules.py index 6a272dae50..3cb232a7b5 100644 --- a/lib/python/qmk/submodules.py +++ b/lib/python/qmk/submodules.py @@ -11,7 +11,11 @@ def status(): { 'name': 'submodule_name', 'status': None/False/True, - 'githash': '<sha-1 hash for the submodule> + 'githash': '<sha-1 hash for the submodule>' + 'shorthash': '<short hash for the submodule>' + 'describe': '<output of `git describe --tags`>' + 'last_log_message': 'log message' + 'last_log_timestamp': 'timestamp' } status is None when the submodule doesn't exist, False when it's out of date, and True when it's current @@ -36,6 +40,26 @@ def status(): else: raise ValueError('Unknown `git submodule status` sha-1 prefix character: "%s"' % status) + submodule_logs = cli.run(['git', 'submodule', '-q', 'foreach', 'git --no-pager log --pretty=format:"$sm_path%x01%h%x01%ad%x01%s%x0A" --date=iso -n1']) + for log_line in submodule_logs.stdout.split('\n'): + if not log_line: + continue + + r = log_line.split('\x01') + submodule = r[0] + submodules[submodule]['shorthash'] = r[1] if len(r) > 1 else '' + submodules[submodule]['last_log_timestamp'] = r[2] if len(r) > 2 else '' + submodules[submodule]['last_log_message'] = r[3] if len(r) > 3 else '' + + submodule_tags = cli.run(['git', 'submodule', '-q', 'foreach', 'echo -n "$sm_path "; git describe --tags']) + for log_line in submodule_tags.stdout.split('\n'): + if not log_line: + continue + + r = log_line.split() + submodule = r[0] + submodules[submodule]['describe'] = r[1] if len(r) > 1 else '' + return submodules |