Example #1
0
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)
Example #2
0
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))
Example #3
0
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)
Example #4
0
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")
Example #5
0
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
Example #6
0
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
Example #7
0
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
Example #8
0
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
Example #9
0
	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()
Example #10
0
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))
Example #11
0
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)
Example #12
0
	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, "]")
Example #13
0
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))