aboutsummaryrefslogtreecommitdiff
path: root/lib/python/qmk/commands.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python/qmk/commands.py')
-rw-r--r--lib/python/qmk/commands.py142
1 files changed, 117 insertions, 25 deletions
diff --git a/lib/python/qmk/commands.py b/lib/python/qmk/commands.py
index 3a35c1103..8c66228b2 100644
--- a/lib/python/qmk/commands.py
+++ b/lib/python/qmk/commands.py
@@ -2,6 +2,7 @@
2""" 2"""
3import json 3import json
4import os 4import os
5import sys
5import shutil 6import shutil
6from pathlib import Path 7from pathlib import Path
7from subprocess import DEVNULL 8from subprocess import DEVNULL
@@ -10,7 +11,7 @@ from time import strftime
10from milc import cli 11from milc import cli
11 12
12import qmk.keymap 13import qmk.keymap
13from qmk.constants import KEYBOARD_OUTPUT_PREFIX 14from qmk.constants import QMK_FIRMWARE, KEYBOARD_OUTPUT_PREFIX
14from qmk.json_schema import json_load 15from qmk.json_schema import json_load
15 16
16time_fmt = '%Y-%m-%d-%H:%M:%S' 17time_fmt = '%Y-%m-%d-%H:%M:%S'
@@ -86,11 +87,17 @@ def create_make_command(keyboard, keymap, target=None, parallel=1, **env_vars):
86 return create_make_target(':'.join(make_args), parallel, **env_vars) 87 return create_make_target(':'.join(make_args), parallel, **env_vars)
87 88
88 89
89def get_git_version(repo_dir='.', check_dir='.'): 90def get_git_version(current_time, repo_dir='.', check_dir='.'):
90 """Returns the current git version for a repo, or the current time. 91 """Returns the current git version for a repo, or the current time.
91 """ 92 """
92 git_describe_cmd = ['git', 'describe', '--abbrev=6', '--dirty', '--always', '--tags'] 93 git_describe_cmd = ['git', 'describe', '--abbrev=6', '--dirty', '--always', '--tags']
93 94
95 if repo_dir != '.':
96 repo_dir = Path('lib') / repo_dir
97
98 if check_dir != '.':
99 check_dir = repo_dir / check_dir
100
94 if Path(check_dir).exists(): 101 if Path(check_dir).exists():
95 git_describe = cli.run(git_describe_cmd, stdin=DEVNULL, cwd=repo_dir) 102 git_describe = cli.run(git_describe_cmd, stdin=DEVNULL, cwd=repo_dir)
96 103
@@ -100,23 +107,40 @@ def get_git_version(repo_dir='.', check_dir='.'):
100 else: 107 else:
101 cli.log.warn(f'"{" ".join(git_describe_cmd)}" returned error code {git_describe.returncode}') 108 cli.log.warn(f'"{" ".join(git_describe_cmd)}" returned error code {git_describe.returncode}')
102 print(git_describe.stderr) 109 print(git_describe.stderr)
103 return strftime(time_fmt) 110 return current_time
104 111
105 return strftime(time_fmt) 112 return current_time
106 113
107 114
108def write_version_h(git_version, build_date, chibios_version, chibios_contrib_version): 115def create_version_h(skip_git=False, skip_all=False):
109 """Generate and write quantum/version.h 116 """Generate version.h contents
110 """ 117 """
111 version_h = [ 118 if skip_all:
112 f'#define QMK_VERSION "{git_version}"', 119 current_time = "1970-01-01-00:00:00"
113 f'#define QMK_BUILDDATE "{build_date}"', 120 else:
114 f'#define CHIBIOS_VERSION "{chibios_version}"', 121 current_time = strftime(time_fmt)
115 f'#define CHIBIOS_CONTRIB_VERSION "{chibios_contrib_version}"', 122
116 ] 123 if skip_git:
124 git_version = "NA"
125 chibios_version = "NA"
126 chibios_contrib_version = "NA"
127 else:
128 git_version = get_git_version(current_time)
129 chibios_version = get_git_version(current_time, "chibios", "os")
130 chibios_contrib_version = get_git_version(current_time, "chibios-contrib", "os")
131
132 version_h_lines = f"""/* This file was automatically generated. Do not edit or copy.
133 */
134
135#pragma once
136
137#define QMK_VERSION "{git_version}"
138#define QMK_BUILDDATE "{current_time}"
139#define CHIBIOS_VERSION "{chibios_version}"
140#define CHIBIOS_CONTRIB_VERSION "{chibios_contrib_version}"
141"""
117 142
118 version_h_file = Path('quantum/version.h') 143 return version_h_lines
119 version_h_file.write_text('\n'.join(version_h))
120 144
121 145
122def compile_configurator_json(user_keymap, bootloader=None, parallel=1, **env_vars): 146def compile_configurator_json(user_keymap, bootloader=None, parallel=1, **env_vars):
@@ -149,13 +173,8 @@ def compile_configurator_json(user_keymap, bootloader=None, parallel=1, **env_va
149 keymap_dir.mkdir(exist_ok=True, parents=True) 173 keymap_dir.mkdir(exist_ok=True, parents=True)
150 keymap_c.write_text(c_text) 174 keymap_c.write_text(c_text)
151 175
152 # Write the version.h file 176 version_h = Path('quantum/version.h')
153 git_version = get_git_version() 177 version_h.write_text(create_version_h())
154 build_date = strftime('%Y-%m-%d-%H:%M:%S')
155 chibios_version = get_git_version("lib/chibios", "lib/chibios/os")
156 chibios_contrib_version = get_git_version("lib/chibios-contrib", "lib/chibios-contrib/os")
157
158 write_version_h(git_version, build_date, chibios_version, chibios_contrib_version)
159 178
160 # Return a command that can be run to make the keymap and flash if given 179 # Return a command that can be run to make the keymap and flash if given
161 verbose = 'true' if cli.config.general.verbose else 'false' 180 verbose = 'true' if cli.config.general.verbose else 'false'
@@ -181,10 +200,6 @@ def compile_configurator_json(user_keymap, bootloader=None, parallel=1, **env_va
181 make_command.append(f'{key}={value}') 200 make_command.append(f'{key}={value}')
182 201
183 make_command.extend([ 202 make_command.extend([
184 f'GIT_VERSION={git_version}',
185 f'BUILD_DATE={build_date}',
186 f'CHIBIOS_VERSION={chibios_version}',
187 f'CHIBIOS_CONTRIB_VERSION={chibios_contrib_version}',
188 f'KEYBOARD={user_keymap["keyboard"]}', 203 f'KEYBOARD={user_keymap["keyboard"]}',
189 f'KEYMAP={user_keymap["keymap"]}', 204 f'KEYMAP={user_keymap["keymap"]}',
190 f'KEYBOARD_FILESAFE={keyboard_filesafe}', 205 f'KEYBOARD_FILESAFE={keyboard_filesafe}',
@@ -223,3 +238,80 @@ def parse_configurator_json(configurator_file):
223 user_keymap['layout'] = aliases[orig_keyboard]['layouts'][user_keymap['layout']] 238 user_keymap['layout'] = aliases[orig_keyboard]['layouts'][user_keymap['layout']]
224 239
225 return user_keymap 240 return user_keymap
241
242
243def git_get_username():
244 """Retrieves user's username from Git config, if set.
245 """
246 git_username = cli.run(['git', 'config', '--get', 'user.name'])
247
248 if git_username.returncode == 0 and git_username.stdout:
249 return git_username.stdout.strip()
250
251
252def git_check_repo():
253 """Checks that the .git directory exists inside QMK_HOME.
254
255 This is a decent enough indicator that the qmk_firmware directory is a
256 proper Git repository, rather than a .zip download from GitHub.
257 """
258 dot_git_dir = QMK_FIRMWARE / '.git'
259
260 return dot_git_dir.is_dir()
261
262
263def git_get_branch():
264 """Returns the current branch for a repo, or None.
265 """
266 git_branch = cli.run(['git', 'branch', '--show-current'])
267 if not git_branch.returncode != 0 or not git_branch.stdout:
268 # Workaround for Git pre-2.22
269 git_branch = cli.run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
270
271 if git_branch.returncode == 0:
272 return git_branch.stdout.strip()
273
274
275def git_is_dirty():
276 """Returns 1 if repo is dirty, or 0 if clean
277 """
278 git_diff_staged_cmd = ['git', 'diff', '--quiet']
279 git_diff_unstaged_cmd = [*git_diff_staged_cmd, '--cached']
280
281 unstaged = cli.run(git_diff_staged_cmd)
282 staged = cli.run(git_diff_unstaged_cmd)
283
284 return unstaged.returncode != 0 or staged.returncode != 0
285
286
287def git_get_remotes():
288 """Returns the current remotes for a repo.
289 """
290 remotes = {}
291
292 git_remote_show_cmd = ['git', 'remote', 'show']
293 git_remote_get_cmd = ['git', 'remote', 'get-url']
294
295 git_remote_show = cli.run(git_remote_show_cmd)
296 if git_remote_show.returncode == 0:
297 for name in git_remote_show.stdout.splitlines():
298 git_remote_name = cli.run([*git_remote_get_cmd, name])
299 remotes[name.strip()] = {"url": git_remote_name.stdout.strip()}
300
301 return remotes
302
303
304def git_check_deviation(active_branch):
305 """Return True if branch has custom commits
306 """
307 cli.run(['git', 'fetch', 'upstream', active_branch])
308 deviations = cli.run(['git', '--no-pager', 'log', f'upstream/{active_branch}...{active_branch}'])
309 return bool(deviations.returncode)
310
311
312def in_virtualenv():
313 """Check if running inside a virtualenv.
314 Based on https://stackoverflow.com/a/1883251
315 """
316 active_prefix = getattr(sys, "base_prefix", None) or getattr(sys, "real_prefix", None) or sys.prefix
317 return active_prefix != sys.prefix