Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/Tools/ardupilotwaf/git_submodule.py
Views: 1798
# encoding: utf-812"""3Waf tool for defining ardupilot's submodules, so that they are kept up to date.4Submodules can be considered dynamic sources, since they are updated during the5build. Furthermore, they can be used to generate other dynamic sources (mavlink6headers generation, for example). Thus, the correct use of this tool should7have three build groups: first one for updating the submodules, second for8generating any dynamic source from them, and the last one for the build. And9post_mode should be set to POST_LAZY. Example::1011def build(bld):12bld.post_mode = waflib.Build.POST_LAZY1314bld.add_group('git_submodules')15# gtest submodule16bld(17features='git_submodule'18git_submodule='gtest',19)20# mavlink submodule with syntactic sugar21bld.git_submodule('mavlink')22...2324# now, for the dynamic sources25bld.add_group('dynamic_sources')26...2728# now, below go the task generators for normal build process29bld.add_group('build')30...31"""3233from waflib import Context, Logs, Task, Utils34from waflib.Configure import conf35from waflib.TaskGen import before_method, feature, taskgen_method3637import os.path38import re3940class update_submodule(Task.Task):41color = 'BLUE'42run_str = '${GIT} submodule update --recursive --init -- ${SUBMODULE_PATH}'4344fast_forward_diff_re = dict(45removed=re.compile(r'-Subproject commit ([0-9a-f]+)'),46added=re.compile(r'\+Subproject commit ([0-9a-f]+)')47)4849def is_fast_forward(self, path):50bld = self.generator.bld51git = self.env.get_flat('GIT')5253cmd = git, 'diff', '--submodule=short', '--', os.path.basename(path)54cwd = self.cwd.make_node(os.path.dirname(path))55out = bld.cmd_and_log(cmd, quiet=Context.BOTH, cwd=cwd)5657m = self.fast_forward_diff_re['removed'].search(out)58n = self.fast_forward_diff_re['added'].search(out)59if not m or not n:60bld.fatal('git_submodule: failed to parse diff')6162head = n.group(1)63wanted = m.group(1)64cmd = git, 'merge-base', head, wanted65cwd = self.cwd.make_node(path)66out = bld.cmd_and_log(cmd, quiet=Context.BOTH, cwd=cwd)6768return out.strip() == head6970def runnable_status(self):71e = self.env.get_flat72cmd = e('GIT'), 'submodule', 'status', '--recursive', '--', e('SUBMODULE_PATH')73out = self.generator.bld.cmd_and_log(cmd, quiet=Context.BOTH, cwd=self.cwd)7475self.non_fast_forward = []7677# git submodule status uses a blank prefix for submodules that are up78# to date79r = Task.SKIP_ME80for line in out.splitlines():81prefix = line[0]82path = line[1:].split()[1]83if prefix == ' ':84continue85if prefix == '-':86r = Task.RUN_ME87if prefix == '+':88if not self.is_fast_forward(path):89self.non_fast_forward.append(path)90else:91r = Task.RUN_ME9293if getattr(self,'non_fast_forward',[]):94r = Task.SKIP_ME9596return r9798def uid(self):99if not hasattr(self, 'uid_'):100m = Utils.md5()101def u(s):102m.update(s.encode('utf-8'))103u(self.__class__.__name__)104u(self.env.get_flat('SUBMODULE_PATH'))105self.uid_ = m.digest()106107return self.uid_108109def __str__(self):110return 'Submodule update: %s' % self.submodule111112def configure(cfg):113cfg.find_program('git')114115_submodules_tasks = {}116117@taskgen_method118def git_submodule_update(self, name):119if name not in _submodules_tasks:120module_node = self.bld.srcnode.make_node(os.path.join('modules', name))121122tsk = self.create_task('update_submodule', submodule=name)123tsk.cwd = self.bld.srcnode124tsk.env.SUBMODULE_PATH = module_node.abspath()125126_submodules_tasks[name] = tsk127128return _submodules_tasks[name]129130131@feature('git_submodule')132@before_method('process_source')133def process_module_dependencies(self):134self.git_submodule = getattr(self, 'git_submodule', '')135if not self.git_submodule:136self.bld.fatal('git_submodule: empty or missing git_submodule argument')137self.git_submodule_update(self.git_submodule)138139@conf140def git_submodule(bld, git_submodule, **kw):141kw['git_submodule'] = git_submodule142kw['features'] = Utils.to_list(kw.get('features', ''))143kw['features'].append('git_submodule')144145return bld(**kw)146147def _post_fun(bld):148Logs.info('')149for name, t in _submodules_tasks.items():150if not getattr(t,'non_fast_forward',[]):151continue152Logs.warn("Submodule %s not updated: non-fastforward" % name)153154@conf155def git_submodule_post_fun(bld):156bld.add_post_fun(_post_fun)157158def _git_head_hash(ctx, path, short=False):159cmd = [ctx.env.get_flat('GIT'), 'rev-parse']160if short:161cmd.append('--short=8')162cmd.append('HEAD')163out = ctx.cmd_and_log(cmd, quiet=Context.BOTH, cwd=path)164return out.strip()165166@conf167def git_submodule_head_hash(self, name, short=False):168module_node = self.srcnode.make_node(os.path.join('modules', name))169return _git_head_hash(self, module_node.abspath(), short=short)170171@conf172def git_head_hash(self, short=False):173return _git_head_hash(self, self.srcnode.abspath(), short=short)174175176