def generate_maintask(role): print "generating", role.tasks_path platforms = role.platforms tasks = [] if platforms: tasks.append({ "fail": { "msg": "unsupported platform -- please contact the role maintainer for support", }, "when": "ansible_distribution not in %s" % list(platform["name"] for platform in platforms), }) if role.is_legacy(): # backward-compatibility mode: update main task file with platform check print "handcrafted main task file, falling back to compatibility mode" for task in unmarshall(role.tasks_path): if platforms and "fail" in task and task["name"] == tasks[0]["name"]: continue # skip check else: tasks.append(task) # copy everything else else: # new mode: generate main task file for path in glob.glob(os.path.join(os.path.dirname(role.tasks_path), "*.yml")): if path == role.tasks_path: continue # skip tasks/main.yml if present name = os.path.basename(path) fckit.trace("including", name) tasks.append({ "name": "Taskfile %s is included" % name, "include": name, "when": role.include_when.get(name, True), }) marshall( obj = tasks, path = role.tasks_path)
def main(args = None): opts = docopt.docopt( doc = __doc__, argv = args) try: if opts["--no-color"]: fckit.disable_colors() if opts["--verbose"]: fckit.enable_tracing() if opts["--directory"]: fckit.chdir(opts["--directory"]) role = Role() targets = Targets( role = role, exclude = opts["--exclude"].split(","), warning_flags = opts["--warnings"].split(","), repository_url = opts["--repository"]) for key in opts["TARGETS"]: fckit.trace("at %s" % key) targets[key].build() if os.path.exists(targets["check"].path): with open(targets["check"].path, "r") as fp: print fckit.magenta(fp.read()) except fckit.Error as exc: raise SystemExit(fckit.red(exc))
def write_maintask(role): raise NotImplementedError platforms = role.platforms tasks = [] if platforms: tasks.append({ "name": "assert the target platform is supported", "fail": { "msg": "unsupported platform -- please contact %s for support" % self.author, }, "when": "ansible_distribution not in %s" % list(platform["name"] for platform in platforms), }) for path in filter(lambda path: path != role.MAINTASK_PATH, glob.glob(os.path.join(role.TASKSDIR, "*.yml"))): name = path[len(TASKSDIR) + 1:] fckit.trace("including", name) if name in self.inconditions: tasks.append({ "name": "%s is included" % name, "include": name, "when": self.inconditions[name], }) else: tasks.append({ "include": name, }) marshall( obj = tasks, path = role.MAINTASK_PATH)
def setup(toolid, settings, manifests): "render a tool configuration template" tools = {k: v for m in manifests for k, v in m.get("tools", {}).items()} if toolid == "help": name_width = max(map(len, tools)) path_width = max(map(lambda key: len(tools[key]["path"]), tools)) for key in tools: required = ", ".join(tools[key]["required_vars"]) optional = ", ".join("%s=%s" % (k, v) for k,v in tools[key]["defaults"].items()) print\ fckit.magenta(key.rjust(name_width)),\ tools[key]["path"].center(path_width),\ required,\ ("[%s]" % optional) if optional else "" else: suffix = ", call 'setup help' for details" if not toolid in tools: raise Error(toolid, "unknown tool", suffix) path = os.path.expanduser(tools[toolid]["path"]) if settings: settings = dict(tools[toolid]["defaults"], **(dict(map(lambda item: item.split("="), settings)))) else: settings = {} if not os.path.exists(path) or settings.get("overwrite", "no") == "yes": try: text = textwrap.dedent(tools[toolid]["template"]).lstrip() % settings except KeyError as exc: raise Error(" ".join(exc.args), "missing required variable" + suffix) with open(path, "w") as fp: fp.write(text) fckit.trace("%s: template instantiated" % path) else: raise Error(path, "file already exists, set overwrite=yes to force")
def get_source_paths(role, exclude): paths = [] for root, dirnames, filenames in os.walk("."): excluded = tuple(dirname for dirname in dirnames for pattern in exclude if fnmatch.fnmatch(dirname, pattern)) for dirname in excluded: dirnames.remove(dirname) for filename in filenames: if not any( fnmatch.fnmatch(filename, pattern) for pattern in exclude): path = os.path.normpath(os.path.join(root, filename)) fckit.trace("indexing", path) paths.append(path) return paths
def get_tasks(role): objects = {} for root, _, filenames in os.walk(os.path.dirname(role.tasks_path)): for filename in filenames: _, extname = os.path.splitext(filename) if extname == ".yml": path = os.path.join(root, filename) try: tasks = unmarshall(path, default = []) or [] for idx, task in enumerate(tasks): name = "%s[%s]" % (filename, task.get("name", "#%i" % (idx + 1))) objects["task '%s'" % name] = task except: fckit.trace("invalid task file %s, ignored" % path) return objects
def get_source_paths(role, exclude): paths = [] for root, dirnames, filenames in os.walk("."): excluded = tuple( dirname for dirname in dirnames for pattern in exclude if fnmatch.fnmatch(dirname, pattern)) for dirname in excluded: dirnames.remove(dirname) for filename in filenames: if not any(fnmatch.fnmatch(filename, pattern) for pattern in exclude): path = os.path.normpath(os.path.join(root, filename)) fckit.trace("indexing", path) paths.append(path) return paths
def get_tasks(role): objects = {} for root, _, filenames in os.walk(os.path.dirname(role.tasks_path)): for filename in filenames: _, extname = os.path.splitext(filename) if extname == ".yml": path = os.path.join(root, filename) try: tasks = unmarshall(path, default=[]) or [] for idx, task in enumerate(tasks): name = "%s[%s]" % (filename, task.get("name", "#%i" % (idx + 1))) objects["task '%s'" % name] = task except: fckit.trace("invalid task file %s, ignored" % path) return objects
def __init__(self, preferences = None, profileid = None, manifests = None, path = None): # resolve preferences: if preferences: self.preferences = preferences.get("all", {}) if profileid: self.preferences.update(preferences.get(profileid, {})) else: self.preferences = {} # resolve base directory: if path: path = fckit.Path(path) if os.path.isdir(path): dirname = path self.filename = None else: dirname, self.filename = os.path.split(path) if dirname: fckit.chdir(dirname) else: self.filename = None # resolve manifest: if self.filename: candidates = {manifest["name"]: (manifest, self.filename) for manifest in manifests for pattern in manifest["filenames"] if fnmatch.fnmatch(self.filename, pattern)} else: candidates = {manifest["name"]: (manifest, filename) for manifest in manifests for pattern in reversed(manifest["filenames"]) for filename in glob.glob(pattern)[:1]} if not candidates: raise Error("no known manifest found") elif len(candidates) > 1: raise Error( [filename for manifest, filename in candidates.values()], "multiple candidate manifests found, use -f to select a manifest") self.manifest, self.filename = candidates.values()[0] fckit.trace("using %s build stack" % self.manifest["name"]) if not any(key.startswith("on_") for key in self.manifest): raise Error("this build stack is still under development, request support on github") self.targets = Targets() self.vcs = Vcs()
def main(args=None): opts = docopt.docopt(doc=__doc__, argv=args) try: if opts["--no-color"]: fckit.disable_colors() if opts["--verbose"]: fckit.enable_tracing() if opts["--directory"]: fckit.chdir(opts["--directory"]) role = Role() targets = Targets(role=role, exclude=opts["--exclude"].split(","), warning_flags=opts["--warnings"].split(","), repository_url=opts["--repository"]) for key in opts["TARGETS"]: fckit.trace("at %s" % key) targets[key].build() if os.path.exists(targets["check"].path): with open(targets["check"].path, "r") as fp: print fckit.magenta(fp.read()) except fckit.Error as exc: raise SystemExit(fckit.red(exc))
def generate_maintask(role): print "generating", role.tasks_path platforms = role.platforms tasks = [] if platforms: tasks.append({ "fail": { "msg": "unsupported platform -- please contact the role maintainer for support", }, "when": "ansible_distribution not in %s" % list(platform["name"] for platform in platforms), }) if role.is_legacy(): # backward-compatibility mode: update main task file with platform check print "handcrafted main task file, falling back to compatibility mode" for task in unmarshall(role.tasks_path): if platforms and "fail" in task and task["name"] == tasks[0][ "name"]: continue # skip check else: tasks.append(task) # copy everything else else: # new mode: generate main task file for path in glob.glob( os.path.join(os.path.dirname(role.tasks_path), "*.yml")): if path == role.tasks_path: continue # skip tasks/main.yml if present name = os.path.basename(path) fckit.trace("including", name) tasks.append({ "name": "Taskfile %s is included" % name, "include": name, "when": role.include_when.get(name, True), }) marshall(obj=tasks, path=role.tasks_path)
def _handle_target(self, name, default = "stack", **kwargs): "generic target handler: call the custom handler if it exists, or fallback on default" fckit.trace(">>", "[", name, "]") handler = self.manifest.get("on_%s" % name, default) if handler is Exception: raise Error(self.manifest["name"], name, "unsupported target") elif handler is None: pass elif handler == "stack": # stack target and let the on_flush handler deal with it self.targets.append(name, **kwargs) elif callable(handler): for res in (handler)( filename = self.filename, targets = self.targets, **kwargs): if isinstance(res, (list, tuple)): if res[0] == "@try": try: self._check_call(res[1:]) except: fckit.trace("command failure ignored") elif res[0] == "@tag": self._check_call(self.vcs.tag(*res[1:])) elif res[0] == "@push": self._check_call(self.vcs.push()) elif res[0] == "@flush": assert name != "flush", "infinite recursion detected" self.flush() elif res[0] == "@trace": fckit.trace(*res[1:]) elif res[0] == "@purge": self._check_call(self.vcs.purge()) elif res[0] == "@commit": self._check_call(self.vcs.commit(*res[1:])) elif res[0] == "@remove": fckit.remove(*res[1:]) else: self._check_call(res) else: # res is an error object raise Error(self.manifest["name"], name, res) else: raise AssertionError("invalid target handler") fckit.trace("<<", "[", name, "]")
def main(args = None): opts = docopt.docopt( doc = __doc__, argv = args) try: if opts["--no-color"]: fckit.disable_colors() if opts["--verbose"]: fckit.enable_tracing() if opts["-E"]: def warning(*strings): raise Error(": ".join(strings)) globals()["warning"] = warning warning_flags = opts["--warnings"].split(",") if opts["--warnings"] else () role = Role(opts["--directory"]) ################## # show lifecycle # ################## show_phony_tgt = fckit.BuildTarget( path = "show", phony = True, callback = lambda sources: show(role)) ################## # init lifecycle # ################## manifest_file_tgt = fckit.BuildTarget( path = role.meta_path, callback = lambda path, sources: write_manifest(path)) ################### # clean lifecycle # ################### clean_phony_tgt = fckit.BuildTarget( path = "clean", phony = True, callback = lambda sources: clean(role)) ##################### # publish lifecycle # ##################### readme_file_tgt = fckit.BuildTarget( path = role.readme_path, sources = (manifest_file_tgt,), callback = lambda path, sources: write_readme(role)) maintask_file_tgt = fckit.BuildTarget( path = role.maintask_path, sources = (manifest_file_tgt,), callback = lambda path, sources: write_maintask(role)) dist_phony_tgt = fckit.BuildTarget( path = "dist", phony = True, sources = (readme_file_tgt, maintask_file_tgt), callback = lambda sources: None) check_phony_tgt = fckit.BuildTarget( path = "check", phony = True, sources = (dist_phony_tgt,), callback = lambda sources: check( role = role, warning_flags = warning_flags)) package_file_tgt = fckit.BuildTarget( path = role.package_path, callback = lambda path, sources: package(role)) publish_phony_tgt = fckit.BuildTarget( path = "publish", phony = True, sources = (package_file_tgt,), callback = lambda sources: publish(sources[0], opts["--repository"])) switch = { "show": show_phony_tgt, "init": manifest_file_tgt, "dist": dist_phony_tgt, "clean": clean_phony_tgt, "check": check_phony_tgt, "package": package_file_tgt, "publish": publish_phony_tgt, } for target in opts["TARGETS"]: if target in switch: fckit.trace("at", target) switch[target].build() else: raise Error(target, "no such target") except fckit.Error as exc: raise SystemExit(fckit.red(exc))