def post(self, path, data, check_status_code=True): self.api_log("POST {} {}".format(path, data)) path = self.path(path) r = requests.post(path, headers=self.headers, json=data) log.debug("RESPONSE {}".format(r.status_code)) if check_status_code: assert r.status_code >= 200 and r.status_code < 300, r.text data = r.json() log.debug(pretty(data)) return data
def post(self, path, data, check_status_code=True): if os.getenv("TOM") == "PASSIVE": print("Would post: " + path) return None self.api_log("POST {} {}".format(path, data)) path = self.path(path) r = requests.post(path, headers=self.headers, json=data) log.debug("RESPONSE {}".format(r.status_code)) if check_status_code: assert r.status_code >= 200 and r.status_code < 300, r.text data = r.json() log.debug(pretty(data)) return data
def wait_for_queue(self, url): log.debug("Queue URL: {}".format(url)) queue_item = {} while "executable" not in queue_item: log.info("Waiting for jenkins build in queue") sleep(1) r = requests.get(url + "api/json", headers=self.headers, auth=self.auth) assert r.status_code >= 200 and r.status_code < 300 queue_item = r.json() log.debug(pretty(queue_item)) num = queue_item["executable"]["number"] url = queue_item["executable"]["url"] return num, url
def create_pr( self, target_repo, target_branch, source_user, source_branch, title, text, simple_output=True): """Sends request to GitHub to create a pull request. Args: target_repo - repository where to create PR, for example 'cfengine/core' target_branch - branch to which to create PR, for example '3.12.x' source_user - user who forked target_repo - changes from his fork will be in PR. For example 'Lex-2008'. Note that we do NOT specify name of repo - github finds it automatically - looks like any given user can fork any repo only once. source_branch - branch in source_user's fork of target_repo from which to take changes title - title to assign to the PR (can be changed later by user) text - longer description of PR (can be changed later by user) simple_output - format of return value, see below Returns: Depending on simple_output, either: * String 'PR: <url>' if simple_output=True, or * nested dict based on JSON object representing the PR, shown at https://developer.github.com/v3/pulls/#response-2 """ data = { "title": title, "head": source_user + ':' + source_branch, "base": target_branch, "body": text, "maintainer_can_modify": True } pr = self.post("/repos/{}/pulls".format(target_repo), data, False) if not simple_output: return pr if not 'html_url' in pr: return 'PR creation failed with error:\n```\n{}\n```\n'\ .format(pretty(pr)) else: return 'PR: {}'.format(pr['html_url'])
def talk(self): if not self.slack: sys.exit("Cannot start talk mode, Slack credentials missing") message = json.load(sys.stdin) log.debug(pretty(message)) if 'token' not in message or message['token'] != self.slack_read_token: log.warning('Unauthorized message - ignoring') return if 'authed_users' in message and len(message['authed_users']) > 0: self.slack.my_username = message['authed_users'][0] message = message['event'] if not 'user' in message: # not a user-generated message # probably a bot-generated message log.warning('Not a user message - ignoring') return self.slack.set_reply_to(message) self.dispatcher.parse_text(message['text'])
def get(self, path): log.debug("GET {}".format(path)) path = self.path(path) if path in self.get_cache: log.debug("Found in cache") return self.get_cache[path] r = requests.get(path, headers=self.headers) log.debug("RESPONSE {}".format(r.status_code)) assert r.status_code >= 200 and r.status_code < 300 data = r.json() log.debug(pretty(data)) self.get_cache[path] = data if (not isinstance(data, list) or 'link' not in r.headers or 'rel="next"' not in r.headers['link']): # no need to paginate return data all_links = r.headers['link'].split(',') next_link = [link for link in all_links if 'rel="next"' in link] next_link = re.search('<(.*)>', next_link[0]).group(1) log.debug('paginating from {} to {}'.format(path, next_link)) return data + self.get(next_link)
def get_deps_list(self, branch='master'): """Get list of dependencies for given branch. Assumes proper branch checked out by `self.buildscripts` repo. Returns a list, like this: ["lcov", "pthreads-w32", "libgnurx"] """ # TODO: get value of $EMBEDDED_DB from file embedded_db = 'lmdb' if branch == '3.7.x': options_file = self.buildscripts.get_file( 'build-scripts/install-dependencies') else: options_file = self.buildscripts.get_file( 'build-scripts/compile-options') options_lines = options_file.splitlines() if branch == '3.7.x': filtered_lines = (x for x in options_lines if re.match('\s*DEPS=".*\\$DEPS', x)) only_deps = (re.sub('\\$?DEPS', '', x) for x in filtered_lines) only_deps = (re.sub('[=";]', '', x) for x in only_deps) only_deps = (x.strip() for x in only_deps) else: filtered_lines = (x for x in options_lines if 'var_append DEPS' in x) only_deps = (re.sub('.*DEPS "(.*)".*', "\\1", x) for x in filtered_lines) # currently only_deps is generator of space-separated deps, # i.e. each item can contain several items, like this: # list(only_deps) = ["lcov", "pthreads-w32 libgnurx"] # to "flattern" it we first join using spaces and then split on spaces # in the middle we also do some clean-ups only_deps = ' '.join(only_deps)\ .replace('$EMBEDDED_DB', embedded_db)\ .replace('libgcc ','')\ .split(' ') # now only_deps looks like this: ["lcov", "pthreads-w32", "libgnurx"] log.debug(pretty(only_deps)) return only_deps
def dump_to_file(self, path="tmp_pr.json"): with open(path, "w") as f: f.write(pretty(self.data))