def git_command(cmdline, repo_dir, error_messages=True): """ Runs the given git command line in the given directory. Returns stdout of the command. """ cmdline = ["git"] + cmdline io.debug(_("running '{}' in {}").format( " ".join(cmdline), repo_dir, )) git_process = Popen( cmdline, cwd=repo_dir, preexec_fn=setpgrp, stderr=PIPE, stdout=PIPE, ) stdout, stderr = git_process.communicate() # FIXME integrate this into Item._command_results if git_process.returncode != 0: if error_messages: io.stderr( _("{} failed command: {}").format(getpid(), " ".join(cmdline))) io.stderr(_("{} failed in dir: {}").format(getpid(), repo_dir)) io.stderr(_("{} stdout:\n{}").format(getpid(), stdout)) io.stderr(_("{} stderr:\n{}").format(getpid(), stderr)) raise RuntimeError( _("`git {command}` failed in {dir}").format( command=cmdline[1], dir=repo_dir, )) return stdout.decode('utf-8').strip()
def get_local_repo_path(bw_repo_path, repo_name): """ From the given BundleWrap repo, get the filesystem path to the git repo associated with the given internal repo name. """ repo_map_path = join(bw_repo_path, REPO_MAP_FILENAME) if not isfile(repo_map_path): io.stderr(_("missing repo map for git_deploy at {}").format(repo_map_path)) io.stderr(_("you must create this file with the following format:")) io.stderr(_(" <value of repo attribute on git_deploy item>: " "<absolute path to local git repo>")) io.stderr(_("since the path is local, you should also add the " "{} file to your gitignore").format(REPO_MAP_FILENAME)) raise RepositoryError(_("missing repo map for git_deploy")) with open(join(bw_repo_path, REPO_MAP_FILENAME)) as f: repo_map = f.readlines() for line in repo_map: if not line.strip() or line.startswith("#"): continue try: repo, path = line.split(":", 1) except: raise RepositoryError(_("unable to parse line from {path}: '{line}'").format( line=line, path=repo_map_path, )) if repo_name == repo: return path.strip() raise RepositoryError(_("no path found for repo '{repo}' in {path}").format( path=repo_map_path, repo=repo_name, ))
def get_local_repo_path(bw_repo_path, repo_name): """ From the given BundleWrap repo, get the filesystem path to the git repo associated with the given internal repo name. """ repo_map_path = join(bw_repo_path, REPO_MAP_FILENAME) if not isfile(repo_map_path): io.stderr(_("missing repo map for git_deploy at {}").format(repo_map_path)) io.stderr(_("you must create this file with the following format:")) io.stderr(_(" <value of repo attribute on git_deploy item>: " "<absolute path to local git repo>")) io.stderr(_("since the path is local, you should also add the " "{} file to your gitignore").format(REPO_MAP_FILENAME)) raise RepositoryError(_("missing repo map for git_deploy")) with open(join(bw_repo_path, REPO_MAP_FILENAME)) as f: repo_map = f.readlines() for line in repo_map: if not line.strip() or line.startswith("#"): continue try: repo, path = line.split(":", 1) except: raise RepositoryError(_("unable to parse line from {path}: '{line}'").format( line=line, path=repo_map_path, )) if repo_name == repo: return path.strip() raise RepositoryError(_("no path found for repo '{repo}' in {path}").format( path=repo_map_path, repo=repo_name, ))
def content_processor_mako(item): template = Template( item._template_content.encode('utf-8'), input_encoding='utf-8', lookup=TemplateLookup(directories=[item.item_data_dir, item.item_dir]), output_encoding=item.attributes['encoding'], ) io.debug("{node}:{bundle}:{item}: rendering with Mako...".format( bundle=item.bundle.name, item=item.id, node=item.node.name, )) start = datetime.now() try: content = template.render(item=item, bundle=item.bundle, node=item.node, repo=item.node.repo, **item.attributes['context']) except FaultUnavailable: raise except Exception as e: io.stderr("".join(format_exception(*exc_info()))) if isinstance(e, NameError) and str(e) == "Undefined": # Mako isn't very verbose here. Try to give a more useful # error message - even though we can't pinpoint the excat # location of the error. :/ e = _("Undefined variable (look for '${...}')") elif isinstance(e, KeyError): e = _("KeyError: {}").format(str(e)) raise TemplateError( _("Error while rendering template for {node}:{bundle}:{item}: {error}" ).format( bundle=item.bundle.name, error=e, item=item.id, node=item.node.name, )) duration = datetime.now() - start io.debug("{node}:{bundle}:{item}: rendered in {time}s".format( bundle=item.bundle.name, item=item.id, node=item.node.name, time=duration.total_seconds(), )) return content
def _notify(url, message=None, title=None, fallback=None, user=None, target=None, color="#000000"): payload = { "icon_url": "http://bundlewrap.org/img/icon.png", "username": "******", } if fallback: payload["attachments"] = [{ "color": color, "fallback": fallback, }] if message: payload["attachments"][0]["text"] = message if title: payload["attachments"][0]["title"] = title if target and user: payload["attachments"][0]["fields"] = [ { "short": True, "title": "User", "value": user, }, { "short": True, "title": "Target", "value": target, }, ] else: payload["text"] = message try: post( url, headers={ 'content-type': 'application/json', }, data=dumps(payload), ) except ConnectionError as e: io.stderr("Failed to submit Slack notification: {}".format(e))
def main(): io.activate() try: repo = Repository("") except NoSuchRepository: io.stderr("{} Not inside a bundlewrap repository".format(red("!"))) sys.exit(1) my_path = pathlib.Path(__file__).parent.absolute() relpath = my_path.relative_to(repo.path) if not str(relpath).startswith("collections/"): io.stderr( "{} Collection should be installed to <repo>/collections".format( yellow("!"))) sys.exit(1) install_dir(my_path / "hooks", repo.hooks_dir) install_dir(my_path / "libs", repo.libs_dir) install_dir(my_path / "items", repo.items_dir)
def _get_config(repo_path): config_path = join(repo_path, ".slack.cfg") if not exists(config_path): _create_config(config_path) config = SafeConfigParser() config.read(config_path) if config.get("configuration", "enabled", fallback="unconfigured") == "unconfigured": io.stderr("Slack notifications not configured. Please edit .slack.cfg " "(it has already been created) and set enabled to 'yes' " "(or 'no' to silence this message and disable Slack notifications).") return None elif config.get("configuration", "enabled").lower() not in ("yes", "true", "1"): io.debug("Slack notifications not enabled in .slack.cfg, skipping...") return None elif not REQUESTS: io.stderr("Slack notifications need the requests library. " "You can usually install it with `pip install requests`.") return None return config
def git_command(cmdline, repo_dir): """ Runs the given git command line in the given directory. Returns stdout of the command. """ cmdline = ["git"] + cmdline io.debug(_("running '{}' in {}").format( " ".join(cmdline), repo_dir, )) git_process = Popen( cmdline, cwd=repo_dir, stderr=PIPE, stdout=PIPE, ) stdout, stderr = git_process.communicate() if git_process.returncode != 0: io.stderr(_("failed command: {}").format(" ".join(cmdline))) io.stderr(_("stdout:\n{}").format(stdout)) io.stderr(_("stderr:\n{}").format(stderr)) raise RuntimeError(_("`git {command}` failed in {dir}").format( command=cmdline[1], dir=repo_dir, )) return stdout.decode('utf-8').strip()
def _notify(url, message=None, title=None, fallback=None, user=None, target=None, color="#000000"): payload = { "icon_url": "http://bundlewrap.org/img/icon.png", "username": "******", } if fallback: payload["attachments"] = [{ "color": color, "fallback": fallback, }] if message: payload["attachments"][0]["text"] = message if title: payload["attachments"][0]["title"] = title if target and user: payload["attachments"][0]["fields"] = [ { "short": True, "title": "User", "value": user, }, { "short": True, "title": "Target", "value": target, }, ] else: payload["text"] = message try: post( url, headers={ 'content-type': 'application/json', }, data=dumps(payload), ) except ConnectionError as e: io.stderr("Failed to submit Slack notification: {}".format(e))
def git_command(cmdline, repo_dir): """ Runs the given git command line in the given directory. Returns stdout of the command. """ cmdline = ["git"] + cmdline io.debug(_("running '{}' in {}").format( " ".join(cmdline), repo_dir, )) git_process = Popen( cmdline, cwd=repo_dir, preexec_fn=setpgrp, stderr=PIPE, stdout=PIPE, ) stdout, stderr = git_process.communicate() if git_process.returncode != 0: io.stderr(_("failed command: {}").format(" ".join(cmdline))) io.stderr(_("stdout:\n{}").format(stdout)) io.stderr(_("stderr:\n{}").format(stderr)) raise RuntimeError(_("`git {command}` failed in {dir}").format( command=cmdline[1], dir=repo_dir, )) return stdout.decode('utf-8').strip()
def content_processor_jinja2(item): loader = FileSystemLoader(searchpath=[item.item_data_dir, item.item_dir]) env = Environment(loader=loader) template = env.from_string(item._template_content) io.debug("{node}:{bundle}:{item}: rendering with Jinja2...".format( bundle=item.bundle.name, item=item.id, node=item.node.name, )) start = datetime.now() try: content = template.render(item=item, bundle=item.bundle, node=item.node, repo=item.node.repo, **item.attributes['context']) except FaultUnavailable: raise except Exception as e: io.stderr("".join(format_exception(*exc_info()))) raise TemplateError( _("Error while rendering template for {node}:{bundle}:{item}: {error}" ).format( bundle=item.bundle.name, error=e, item=item.id, node=item.node.name, )) duration = datetime.now() - start io.debug("{node}:{bundle}:{item}: rendered in {time}s".format( bundle=item.bundle.name, item=item.id, node=item.node.name, time=duration.total_seconds(), )) return content.encode(item.attributes['encoding'])
def _get_config(repo_path): config_path = join(repo_path, ".slack.cfg") if not exists(config_path): _create_config(config_path) config = SafeConfigParser() config.read(config_path) if config.get("configuration", "enabled", fallback="unconfigured") == "unconfigured": io.stderr( "Slack notifications not configured. Please edit .slack.cfg " "(it has already been created) and set enabled to 'yes' " "(or 'no' to silence this message and disable Slack notifications)." ) return None elif config.get("configuration", "enabled").lower() not in ("yes", "true", "1"): io.debug("Slack notifications not enabled in .slack.cfg, skipping...") return None elif not REQUESTS: io.stderr("Slack notifications need the requests library. " "You can usually install it with `pip install requests`.") return None return config
from bundlewrap.utils.text import bold, mark_for_translation as _, yellow from bundlewrap.utils.ui import io from passlib.hash import apr_md5_crypt, sha512_crypt from requests import Session CONFIG_PATH = expanduser( environ.get("BW_TEAMVAULT_SECRETS_FILE", "~/.bw_teamvault_secrets.cfg")) DUMMY_MODE = environ.get("BW_TEAMVAULT_DUMMY_MODE", "0") == "1" cache = {} config = SafeConfigParser() try: config.read([CONFIG_PATH]) except: io.stderr("{x} WARNING: Unable to read TeamVault config at {path}".format( path=CONFIG_PATH, x=yellow("!"), )) sessions = {} def _fetch_secret(site, secret_id): try: return cache[site][secret_id] except KeyError: pass session = sessions.setdefault(getpid(), Session()) try: full_url = "{}/api/secrets/{}/".format( config.get(site, "url"),
from bundlewrap.utils.text import bold, mark_for_translation as _, yellow from bundlewrap.utils.ui import io from passlib.hash import apr_md5_crypt, sha512_crypt from requests import Session CONFIG_PATH = expanduser( environ.get("BW_TEAMVAULT_SECRETS_FILE", "~/.bw_teamvault_secrets.cfg")) DUMMY_MODE = environ.get("BW_TEAMVAULT_DUMMY_MODE", "0") == "1" cache = {} config = ConfigParser() try: config.read([CONFIG_PATH]) except: io.stderr("{x} WARNING: Unable to read TeamVault config at {path}".format( path=CONFIG_PATH, x=yellow("!"), )) sessions = {} for site_name, site_config in config.items(): if (('password' not in site_config or not site_config['password']) and 'pass_command' in site_config): try: config[site_name]['password'] = check_output( site_config['pass_command'], shell=True).decode('UTF-8').splitlines()[0].strip() except (FileNotFoundError, CalledProcessError, IndexError) as e: io.stderr("{x} TeamVault pass_command for site {site} failed: {e}". format(x=yellow('!'), site=site_name, e=repr(e)))
from bundlewrap.utils import Fault from bundlewrap.utils.text import bold, mark_for_translation as _, yellow from bundlewrap.utils.ui import io from passlib.hash import apr_md5_crypt, sha512_crypt from requests import Session CONFIG_PATH = expanduser(environ.get("BW_TEAMVAULT_SECRETS_FILE", "~/.bw_teamvault_secrets.cfg")) DUMMY_MODE = environ.get("BW_TEAMVAULT_DUMMY_MODE", "0") == "1" cache = {} config = SafeConfigParser() try: config.read([CONFIG_PATH]) except: io.stderr("{x} WARNING: Unable to read TeamVault config at {path}".format( path=CONFIG_PATH, x=yellow("!"), )) sessions = {} def _fetch_secret(site, secret_id): try: return cache[site][secret_id] except KeyError: pass session = sessions.setdefault(getpid(), Session()) try: full_url = "{}/api/secrets/{}/".format( config.get(site, "url"),