def build(self, path): """Prepare, lock and store the task. Check if not already locked. Touch (link in children, save chilren to .caf/children). Check if needed children are already sealed. Check if children are already locked. Prepare task. Get hashes. Lock task with hashes. Check if a task has been already stored previously and if not, store it and relink children. """ with timing('task init'): if not path.is_dir(): mkdir(path) self.path = Path(path).resolve() if self.is_locked(): warn('{} already locked'.format(self)) return if not self.is_touched(): self.touch() for linkname, link in self.links.items(): if link.needed and not link.task.is_sealed(): warn('{}: dependency "{}" not sealed'.format(self, linkname)) return if not all(child.is_locked() for child in self.children): return with timing('prepare'): self.prepare() with timing('hash'): hashes = self.get_hashes() with timing('lock'): self.lock(hashes) myhash = get_file_hash(self.path/'.caf/lock') with timing('storing'): cellarpath = self.ctx.cellar/str_to_path(myhash) if cellarpath.is_dir(): env_file = Path(self.path/'.caf/env') if env_file.is_file(): env_file.rename(cellarpath/'.caf/env') shutil.rmtree(str(self.path)) else: info('Stored new task {}'.format(self)) mkdir(cellarpath.parent, parents=True, exist_ok=True) self.path.rename(cellarpath) relink(cellarpath, self.path) self.path = cellarpath with timing('linking deps'): self.link_deps()
def build(caf, dry: '--dry', do_init: 'init'): """ Prepare tasks and targets defined in cscript. Usage: caf [init] build [--dry] Options: -n, --dry Dry run (do not write to disk). Tasks are created in .caf/db/Brewery/Latest and if their preparation does not depened on unfinished tasks, they are prepared and stored in .caf/db/Cellar based on their SHA1 hash. Targets (collections of symlinks to tasks) are created in ./build. """ if not hasattr(caf.cscript, 'build'): error('cscript has to contain function build(ctx)') if do_init: init(['caf', 'init'], caf) ctx = Context(caf.cache/cellar, caf.top, caf.libpath) with timing('dependency tree'): caf.cscript.build(ctx) if not dry: timestamp = get_timestamp() mkdir(caf.brewery/timestamp) relink(timestamp, caf.brewery/latest, relative=False) with timing('build'): ctx.build(caf.brewery/latest) if caf.out.is_dir(): shutil.rmtree(str(caf.out)) mkdir(caf.out) with timing('targets'): ctx.make_targets(caf.out, caf.cache) if hasattr(caf.cscript, 'json'): warn('Make sure json is not printing dictionaries in features') with open(os.devnull, 'w') as null: sp.call(['git', 'add', '--all', 'build'], stdout=null) sp.call(['git', 'commit', '-a', '-m', '#build'], stdout=null)