You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@falcon.apache.org by aj...@apache.org on 2016/01/27 21:32:30 UTC
[1/3] falcon git commit: FALCON-1771 Tool to merge pull requests.
Contributed by Ajay Yadava.
Repository: falcon
Updated Branches:
refs/heads/master 36d45e99a -> 3b8d32ffd
FALCON-1771 Tool to merge pull requests. Contributed by Ajay Yadava.
Project: http://git-wip-us.apache.org/repos/asf/falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/falcon/commit/ba8dab98
Tree: http://git-wip-us.apache.org/repos/asf/falcon/tree/ba8dab98
Diff: http://git-wip-us.apache.org/repos/asf/falcon/diff/ba8dab98
Branch: refs/heads/master
Commit: ba8dab98a96a1cfa3014530ca23c0450727848cf
Parents: 36d45e9
Author: Ajay Yadava <aj...@gmail.com>
Authored: Thu Jan 28 01:10:34 2016 +0530
Committer: Ajay Yadava <aj...@gmail.com>
Committed: Thu Jan 28 01:10:34 2016 +0530
----------------------------------------------------------------------
CHANGES.txt | 2 +
falcon_merge_pr.py | 503 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 505 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/falcon/blob/ba8dab98/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 62655ad..f36de10 100755
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -10,6 +10,8 @@ Trunk
FALCON-1230 Data based notification Service to notify execution instances when data becomes available(Pavan Kumar Kolamuri via Ajay Yadava)
IMPROVEMENTS
+ FALCON-1771 Tool to merge pull requests (Ajay Yadava)
+
FALCON-1770 Update README file (Ajay Yadava)
BUG FIXES
http://git-wip-us.apache.org/repos/asf/falcon/blob/ba8dab98/falcon_merge_pr.py
----------------------------------------------------------------------
diff --git a/falcon_merge_pr.py b/falcon_merge_pr.py
new file mode 100644
index 0000000..0eccb33
--- /dev/null
+++ b/falcon_merge_pr.py
@@ -0,0 +1,503 @@
+#!/usr/bin/env python
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Utility for creating well-formed pull request merges and pushing them to Apache. This script is a modified version
+# of the one created by the Kafka project (https://github.com/apache/spark/blob/master/dev/kafka-merge-pr.py).
+#
+# Usage: ./falcon_merge_pr.py (see config env vars below)
+#
+# This utility assumes you already have a local falcon git folder and that you
+# have added remotes corresponding to both:
+# (i) the github apache falcon mirror and
+# (ii) the apache falcon git repo.
+# Please refer to the https://cwiki.apache.org/confluence/display/FALCON/How+to+merge+pull+requests
+#
+
+import json
+import os
+import re
+import subprocess
+import sys
+import urllib2
+import getpass
+
+try:
+ import jira.client
+ JIRA_IMPORTED = True
+except ImportError:
+ JIRA_IMPORTED = False
+
+PROJECT_NAME = "falcon"
+
+CAPITALIZED_PROJECT_NAME = "falcon".upper()
+
+# Location of the local git repository
+REPO_HOME = os.environ.get("%s_HOME" % CAPITALIZED_PROJECT_NAME, os.getcwd())
+# Remote name which points to the GitHub site
+PR_REMOTE_NAME = os.environ.get("PR_REMOTE_NAME", "apache-github")
+# Remote name which points to Apache git
+PUSH_REMOTE_NAME = os.environ.get("PUSH_REMOTE_NAME", "apache")
+# ASF JIRA username
+JIRA_USERNAME = os.environ.get("JIRA_USERNAME", "")
+# ASF JIRA password
+JIRA_PASSWORD = os.environ.get("JIRA_PASSWORD", "")
+# OAuth key used for issuing requests against the GitHub API. If this is not defined, then requests
+# will be unauthenticated. You should only need to configure this if you find yourself regularly
+# exceeding your IP's unauthenticated request rate limit. You can create an OAuth key at
+# https://github.com/settings/tokens. This script only requires the "public_repo" scope.
+GITHUB_OAUTH_KEY = os.environ.get("GITHUB_OAUTH_KEY")
+
+GITHUB_USER = os.environ.get("GITHUB_USER", "apache")
+GITHUB_BASE = "https://github.com/%s/%s/pull" % (GITHUB_USER, PROJECT_NAME)
+GITHUB_API_BASE = "https://api.github.com/repos/%s/%s" % (GITHUB_USER, PROJECT_NAME)
+JIRA_BASE = "https://issues.apache.org/jira/browse"
+JIRA_API_BASE = "https://issues.apache.org/jira"
+# Prefix added to temporary branches
+TEMP_BRANCH_PREFIX = "PR_TOOL"
+# TODO Introduce a convention as this is too brittle
+RELEASE_BRANCH_PREFIX = "0."
+
+DEV_BRANCH_NAME = "master"
+
+DEFAULT_FIX_VERSION = os.environ.get("DEFAULT_FIX_VERSION", "trunk")
+
+def get_json(url):
+ try:
+ request = urllib2.Request(url)
+ if GITHUB_OAUTH_KEY:
+ request.add_header('Authorization', 'token %s' % GITHUB_OAUTH_KEY)
+ return json.load(urllib2.urlopen(request))
+ except urllib2.HTTPError as e:
+ if "X-RateLimit-Remaining" in e.headers and e.headers["X-RateLimit-Remaining"] == '0':
+ print "Exceeded the GitHub API rate limit; see the instructions in " + \
+ "falcon_merge_pr.py to configure an OAuth token for making authenticated " + \
+ "GitHub requests."
+ else:
+ print "Unable to fetch URL, exiting: %s" % url
+ sys.exit(-1)
+
+
+def fail(msg):
+ print msg
+ clean_up()
+ sys.exit(-1)
+
+
+def run_cmd(cmd):
+ print cmd
+ if isinstance(cmd, list):
+ return subprocess.check_output(cmd)
+ else:
+ return subprocess.check_output(cmd.split(" "))
+
+
+def continue_maybe(prompt):
+ result = raw_input("\n%s (y/n): " % prompt)
+ if result.lower() != "y":
+ fail("Okay, exiting")
+
+def clean_up():
+ if original_head != get_current_branch():
+ print "Restoring head pointer to %s" % original_head
+ run_cmd("git checkout %s" % original_head)
+
+ branches = run_cmd("git branch").replace(" ", "").split("\n")
+
+ for branch in filter(lambda x: x.startswith(TEMP_BRANCH_PREFIX), branches):
+ print "Deleting local branch %s" % branch
+ run_cmd("git branch -D %s" % branch)
+
+def get_current_branch():
+ return run_cmd("git rev-parse --abbrev-ref HEAD").replace("\n", "")
+
+# merge the requested PR and return the merge hash
+def merge_pr(pr_num, target_ref, title, body, pr_repo_desc):
+ pr_branch_name = "%s_MERGE_PR_%s" % (TEMP_BRANCH_PREFIX, pr_num)
+ target_branch_name = "%s_MERGE_PR_%s_%s" % (TEMP_BRANCH_PREFIX, pr_num, target_ref.upper())
+ run_cmd("git fetch %s pull/%s/head:%s" % (PR_REMOTE_NAME, pr_num, pr_branch_name))
+ run_cmd("git fetch %s %s:%s" % (PUSH_REMOTE_NAME, target_ref, target_branch_name))
+ run_cmd("git checkout %s" % target_branch_name)
+
+ had_conflicts = False
+ try:
+ run_cmd(['git', 'merge', pr_branch_name, '--squash'])
+ except Exception as e:
+ msg = "Error merging: %s\nWould you like to manually fix-up this merge?" % e
+ continue_maybe(msg)
+ msg = "Okay, please fix any conflicts and 'git add' conflicting files... Finished?"
+ continue_maybe(msg)
+ had_conflicts = True
+
+ commit_authors = run_cmd(['git', 'log', 'HEAD..%s' % pr_branch_name,
+ '--pretty=format:%an <%ae>']).split("\n")
+ distinct_authors = sorted(set(commit_authors),
+ key=lambda x: commit_authors.count(x), reverse=True)
+ primary_author = raw_input(
+ "Enter primary author in the format of \"name <email>\" [%s]: " %
+ distinct_authors[0])
+ if primary_author == "":
+ primary_author = distinct_authors[0]
+
+ reviewers = raw_input(
+ "Enter reviewers in the format of \"name1 <email1>, name2 <email2>\": ").strip()
+
+ commits = run_cmd(['git', 'log', 'HEAD..%s' % pr_branch_name,
+ '--pretty=format:%h [%an] %s']).split("\n")
+
+ if len(commits) > 1:
+ result = raw_input("List pull request commits in squashed commit message? (y/n): ")
+ if result.lower() == "y":
+ should_list_commits = True
+ else:
+ should_list_commits = False
+ else:
+ should_list_commits = False
+
+ merge_message_flags = []
+
+ merge_message_flags += ["-m", title]
+ if body is not None:
+ # We remove @ symbols from the body to avoid triggering e-mails
+ # to people every time someone creates a public fork of the project.
+ merge_message_flags += ["-m", body.replace("@", "")]
+
+ authors = "\n".join(["Author: %s" % a for a in distinct_authors])
+
+ merge_message_flags += ["-m", authors]
+
+ if (reviewers != ""):
+ merge_message_flags += ["-m", "Reviewers: %s" % reviewers]
+
+ if had_conflicts:
+ committer_name = run_cmd("git config --get user.name").strip()
+ committer_email = run_cmd("git config --get user.email").strip()
+ message = "This patch had conflicts when merged, resolved by\nCommitter: %s <%s>" % (
+ committer_name, committer_email)
+ merge_message_flags += ["-m", message]
+
+ # The string "Closes #%s" string is required for GitHub to correctly close the PR
+ close_line = "Closes #%s from %s" % (pr_num, pr_repo_desc)
+ if should_list_commits:
+ close_line += " and squashes the following commits:"
+ merge_message_flags += ["-m", close_line]
+
+ if should_list_commits:
+ merge_message_flags += ["-m", "\n".join(commits)]
+
+ run_cmd(['git', 'commit', '--author="%s"' % primary_author] + merge_message_flags)
+
+ continue_maybe("Merge complete (local ref %s). Push to %s?" % (
+ target_branch_name, PUSH_REMOTE_NAME))
+
+ try:
+ run_cmd('git push %s %s:%s' % (PUSH_REMOTE_NAME, target_branch_name, target_ref))
+ except Exception as e:
+ clean_up()
+ fail("Exception while pushing: %s" % e)
+
+ merge_hash = run_cmd("git rev-parse %s" % target_branch_name)[:8]
+ clean_up()
+ print("Pull request #%s merged!" % pr_num)
+ print("Merge hash: %s" % merge_hash)
+ return merge_hash
+
+
+def cherry_pick(pr_num, merge_hash, default_branch):
+ pick_ref = raw_input("Enter a branch name [%s]: " % default_branch)
+ if pick_ref == "":
+ pick_ref = default_branch
+
+ pick_branch_name = "%s_PICK_PR_%s_%s" % (TEMP_BRANCH_PREFIX, pr_num, pick_ref.upper())
+
+ run_cmd("git fetch %s %s:%s" % (PUSH_REMOTE_NAME, pick_ref, pick_branch_name))
+ run_cmd("git checkout %s" % pick_branch_name)
+
+ try:
+ run_cmd("git cherry-pick -sx %s" % merge_hash)
+ except Exception as e:
+ msg = "Error cherry-picking: %s\nWould you like to manually fix-up this merge?" % e
+ continue_maybe(msg)
+ msg = "Okay, please fix any conflicts and finish the cherry-pick. Finished?"
+ continue_maybe(msg)
+
+ continue_maybe("Pick complete (local ref %s). Push to %s?" % (
+ pick_branch_name, PUSH_REMOTE_NAME))
+
+ try:
+ run_cmd('git push %s %s:%s' % (PUSH_REMOTE_NAME, pick_branch_name, pick_ref))
+ except Exception as e:
+ clean_up()
+ fail("Exception while pushing: %s" % e)
+
+ pick_hash = run_cmd("git rev-parse %s" % pick_branch_name)[:8]
+ clean_up()
+
+ print("Pull request #%s picked into %s!" % (pr_num, pick_ref))
+ print("Pick hash: %s" % pick_hash)
+ return pick_ref
+
+
+def fix_version_from_branch(branch, versions):
+ # Note: Assumes this is a sorted (newest->oldest) list of un-released versions
+ if branch == DEV_BRANCH_NAME:
+ versions = filter(lambda x: x == DEFAULT_FIX_VERSION, versions)
+ if len(versions) > 0:
+ return versions[0]
+ else:
+ return None
+ else:
+ versions = filter(lambda x: x.startswith(branch), versions)
+ if len(versions) > 0:
+ return versions[-1]
+ else:
+ return None
+
+def get_jira_credentials():
+ global JIRA_USERNAME, JIRA_PASSWORD
+ if not JIRA_USERNAME:
+ JIRA_USERNAME = raw_input("JIRA_USERNAME environment variable is not set. Please enter your JIRA username:")
+ if not JIRA_PASSWORD:
+ JIRA_PASSWORD = getpass.getpass()
+
+
+
+def resolve_jira_issue(merge_branches, comment, default_jira_id=""):
+ asf_jira = jira.client.JIRA({'server': JIRA_API_BASE},
+ basic_auth=(JIRA_USERNAME, JIRA_PASSWORD))
+
+ jira_id = raw_input("Enter a JIRA id [%s]: " % default_jira_id)
+ if jira_id == "":
+ jira_id = default_jira_id
+ try:
+ issue = asf_jira.issue(jira_id)
+ except Exception as e:
+ fail("ASF JIRA could not find %s\n%s" % (jira_id, e))
+
+ cur_status = issue.fields.status.name
+ cur_summary = issue.fields.summary
+ cur_assignee = issue.fields.assignee
+ if cur_assignee is None:
+ cur_assignee = "NOT ASSIGNED!!!"
+ else:
+ cur_assignee = cur_assignee.displayName
+
+ if cur_status == "Resolved" or cur_status == "Closed":
+ fail("JIRA issue %s already has status '%s'" % (jira_id, cur_status))
+ print ("=== JIRA %s ===" % jira_id)
+ print ("summary\t\t%s\nassignee\t%s\nstatus\t\t%s\nurl\t\t%s/%s\n" % (
+ cur_summary, cur_assignee, cur_status, JIRA_BASE, jira_id))
+
+ versions = asf_jira.project_versions(CAPITALIZED_PROJECT_NAME)
+ versions = sorted(versions, key=lambda x: x.name, reverse=True)
+ versions = filter(lambda x: x.raw['released'] is False, versions)
+
+ version_names = map(lambda x: x.name, versions)
+ default_fix_versions = map(lambda x: fix_version_from_branch(x, version_names), merge_branches)
+ default_fix_versions = filter(lambda x: x != None, default_fix_versions)
+ default_fix_versions = ",".join(default_fix_versions)
+
+ fix_versions = raw_input("Enter comma-separated fix version(s) [%s]: " % default_fix_versions)
+ if fix_versions == "":
+ fix_versions = default_fix_versions
+ fix_versions = fix_versions.replace(" ", "").split(",")
+
+ def get_version_json(version_str):
+ return filter(lambda v: v.name == version_str, versions)[0].raw
+
+ jira_fix_versions = map(lambda v: get_version_json(v), fix_versions)
+
+ resolve = filter(lambda a: a['name'] == "Resolve Issue", asf_jira.transitions(jira_id))[0]
+ resolution = filter(lambda r: r.raw['name'] == "Fixed", asf_jira.resolutions())[0]
+ asf_jira.transition_issue(
+ jira_id, resolve["id"], fixVersions = jira_fix_versions,
+ comment = comment, resolution = {'id': resolution.raw['id']})
+
+ print "Successfully resolved %s with fixVersions=%s!" % (jira_id, fix_versions)
+
+def resolve_jira_issues(title, merge_branches, comment):
+ jira_ids = re.findall("%s-[0-9]{4,5}" % CAPITALIZED_PROJECT_NAME, title)
+
+ if len(jira_ids) == 0:
+ resolve_jira_issue(merge_branches, comment)
+ for jira_id in jira_ids:
+ resolve_jira_issue(merge_branches, comment, jira_id)
+
+
+def standardize_jira_ref(text):
+ """
+ Standardize the jira reference commit message prefix to "PROJECT_NAME-XXX Issue"
+
+ >>> standardize_jira_ref("%s-1563 Old feed instances get deleted from SLA monitoring on feed update" % CAPITALIZED_PROJECT_NAME)
+ 'FALCON-1563 Old feed instances get deleted from SLA monitoring on feed update'
+ >>> standardize_jira_ref("%s-1032. Test message with dot after id and ellipsis, ..." % PROJECT_NAME)
+ 'FALCON-1032 Test message with dot after id and ellipsis, ...'
+ >>> standardize_jira_ref("%s-6250 %s-6146 %s-5911: Test multiple commit messages." % (PROJECT_NAME, PROJECT_NAME, CAPITALIZED_PROJECT_NAME))
+ 'FALCON-6250 FALCON-6146 FALCON-5911 Test multiple commit messages.'
+ >>> standardize_jira_ref("Message without JIRA id")
+ 'Message without JIRA id'
+ >>> standardize_jira_ref("[FALCON-1009] id in brackets")
+ 'FALCON-1009 id in brackets'
+ """
+ jira_refs = []
+ components = []
+
+ # Extract JIRA ref(s):
+ pattern = re.compile(r'(%s[-\s]*[0-9]{3,6})+' % CAPITALIZED_PROJECT_NAME, re.IGNORECASE)
+ for ref in pattern.findall(text):
+ # Add brackets, replace spaces with a dash, & convert to uppercase
+ jira_refs.append(re.sub(r'\s+', '-', ref.upper()))
+ text = text.replace(ref, '')
+
+ # Extract project name component(s):
+ # Look for alphanumeric chars, spaces, dashes, periods, and/or commas
+ pattern = re.compile(r'(\[[\w\s,-\.]+\])', re.IGNORECASE)
+ for component in pattern.findall(text):
+ components.append(component.upper())
+ text = text.replace(component, '')
+
+ # Cleanup any remaining symbols:
+ pattern = re.compile(r'^\W+(.*)', re.IGNORECASE)
+ if (pattern.search(text) is not None):
+ text = pattern.search(text).groups()[0]
+
+ # Assemble full text (JIRA ref(s), module(s), remaining text)
+ jira_prefix = ' '.join(jira_refs).strip()
+ if jira_prefix:
+ jira_prefix = jira_prefix + " "
+ clean_text = jira_prefix + ' '.join(components).strip() + " " + text.strip()
+
+ # Replace multiple spaces with a single space, e.g. if no jira refs and/or components were included
+ clean_text = re.sub(r'\s+', ' ', clean_text.strip())
+
+ return clean_text
+
+def assert_remotes():
+ remotes = run_cmd("git remote -v").split()
+ status = 0
+ if "apache" not in remotes:
+ print "You don't have remote 'apache' configured. Please run this command:\n" + \
+ "git remote add apache https://git-wip-us.apache.org/repos/asf/falcon.git\n"
+ status = -1
+
+ if "apache-github" not in remotes:
+ print "You don't have remote 'apache-github' configured. Please run this command:\n" + \
+ "git remote add apache-github https://github.com/apache/falcon.git\n"
+ status = -1
+
+ if status != 0:
+ sys.exit(-1)
+
+def main():
+ assert_remotes()
+ global original_head
+
+ original_head = get_current_branch()
+
+ branches = get_json("%s/branches" % GITHUB_API_BASE)
+ branch_names = filter(lambda x: x.startswith(RELEASE_BRANCH_PREFIX), [x['name'] for x in branches])
+ # Assumes branch names can be sorted lexicographically
+ latest_branch = sorted(branch_names, reverse=True)[0]
+
+ pr_num = raw_input("Which pull request would you like to merge? (e.g. 34): ")
+ pr = get_json("%s/pulls/%s" % (GITHUB_API_BASE, pr_num))
+ pr_events = get_json("%s/issues/%s/events" % (GITHUB_API_BASE, pr_num))
+
+ url = pr["url"]
+
+ pr_title = pr["title"]
+ commit_title = raw_input("Commit title [%s]: " % pr_title.encode("utf-8")).decode("utf-8")
+ if commit_title == "":
+ commit_title = pr_title
+
+ # Decide whether to use the modified title or not
+ modified_title = standardize_jira_ref(commit_title)
+ if modified_title != commit_title:
+ print "I've re-written the title as follows to match the standard format:"
+ print "Original: %s" % commit_title
+ print "Modified: %s" % modified_title
+ result = raw_input("Would you like to use the modified title? (y/n): ")
+ if result.lower() == "y":
+ commit_title = modified_title
+ print "Using modified title:"
+ else:
+ print "Using original title:"
+ print commit_title
+
+ body = pr["body"]
+ target_ref = pr["base"]["ref"]
+ user_login = pr["user"]["login"]
+ base_ref = pr["head"]["ref"]
+ pr_repo_desc = "%s/%s" % (user_login, base_ref)
+
+ # Merged pull requests don't appear as merged in the GitHub API;
+ # Instead, they're closed by asfgit.
+ merge_commits = \
+ [e for e in pr_events if e["actor"]["login"] == "asfgit" and e["event"] == "closed"]
+
+ if merge_commits:
+ merge_hash = merge_commits[0]["commit_id"]
+ message = get_json("%s/commits/%s" % (GITHUB_API_BASE, merge_hash))["commit"]["message"]
+
+ print "Pull request %s has already been merged, assuming you want to backport" % pr_num
+ commit_is_downloaded = run_cmd(['git', 'rev-parse', '--quiet', '--verify',
+ "%s^{commit}" % merge_hash]).strip() != ""
+ if not commit_is_downloaded:
+ fail("Couldn't find any merge commit for #%s, you may need to update HEAD." % pr_num)
+
+ print "Found commit %s:\n%s" % (merge_hash, message)
+ cherry_pick(pr_num, merge_hash, latest_branch)
+ sys.exit(0)
+
+ if not bool(pr["mergeable"]):
+ msg = "Pull request %s is not mergeable in its current form.\n" % pr_num + \
+ "Continue? (experts only!)"
+ continue_maybe(msg)
+
+ print ("\n=== Pull Request #%s ===" % pr_num)
+ print ("PR title\t%s\nCommit title\t%s\nSource\t\t%s\nTarget\t\t%s\nURL\t\t%s" % (
+ pr_title, commit_title, pr_repo_desc, target_ref, url))
+ continue_maybe("Proceed with merging pull request #%s?" % pr_num)
+
+ merged_refs = [target_ref]
+
+ merge_hash = merge_pr(pr_num, target_ref, commit_title, body, pr_repo_desc)
+
+ pick_prompt = "Would you like to pick %s into another branch?" % merge_hash
+ while raw_input("\n%s (y/n): " % pick_prompt).lower() == "y":
+ merged_refs = merged_refs + [cherry_pick(pr_num, merge_hash, latest_branch)]
+
+ if JIRA_IMPORTED:
+ continue_maybe("Would you like to update an associated JIRA?")
+ get_jira_credentials()
+ if JIRA_USERNAME and JIRA_PASSWORD:
+ jira_comment = "Issue resolved by pull request %s\n[%s/%s]" % (pr_num, GITHUB_BASE, pr_num)
+ resolve_jira_issues(commit_title, merged_refs, jira_comment)
+ else:
+ print "JIRA_USERNAME and JIRA_PASSWORD not set"
+ print "Exiting without trying to close the associated JIRA."
+ else:
+ print "Could not find jira-python library. Run 'sudo pip install jira' to install."
+ print "Exiting without trying to close the associated JIRA."
+
+if __name__ == "__main__":
+ import doctest
+ failure_count, test_count = doctest.testmod()
+ if failure_count:
+ exit(-1)
+
+ main()
[2/3] falcon git commit: FALCON-1756 Remove PID files on service
stop. Contributed by Deepak Barr.
Posted by aj...@apache.org.
FALCON-1756 Remove PID files on service stop. Contributed by Deepak Barr.
Project: http://git-wip-us.apache.org/repos/asf/falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/falcon/commit/a30a1acd
Tree: http://git-wip-us.apache.org/repos/asf/falcon/tree/a30a1acd
Diff: http://git-wip-us.apache.org/repos/asf/falcon/diff/a30a1acd
Branch: refs/heads/master
Commit: a30a1acd648f8bb4e2ac5849ef663af7f4569e38
Parents: ba8dab9
Author: Ajay Yadava <aj...@gmail.com>
Authored: Thu Jan 28 01:16:25 2016 +0530
Committer: Ajay Yadava <aj...@gmail.com>
Committed: Thu Jan 28 01:16:25 2016 +0530
----------------------------------------------------------------------
CHANGES.txt | 2 ++
src/bin/service-stop.sh | 17 ++++++++++++++++-
2 files changed, 18 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/falcon/blob/a30a1acd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index f36de10..9fb66ef 100755
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -10,6 +10,8 @@ Trunk
FALCON-1230 Data based notification Service to notify execution instances when data becomes available(Pavan Kumar Kolamuri via Ajay Yadava)
IMPROVEMENTS
+ FALCON-1756 Remove PID files on service stop(Deepak Barr via Ajay Yadava)
+
FALCON-1771 Tool to merge pull requests (Ajay Yadava)
FALCON-1770 Update README file (Ajay Yadava)
http://git-wip-us.apache.org/repos/asf/falcon/blob/a30a1acd/src/bin/service-stop.sh
----------------------------------------------------------------------
diff --git a/src/bin/service-stop.sh b/src/bin/service-stop.sh
index 5c08c29..e9dcc07 100755
--- a/src/bin/service-stop.sh
+++ b/src/bin/service-stop.sh
@@ -32,9 +32,24 @@ BASEDIR=`cd ${BASEDIR}/..;pwd`
APP_TYPE=$1
. ${BASEDIR}/bin/falcon-config.sh 'server' "$APP_TYPE"
+STOP_TIMEOUT=10
if [ -f $FALCON_PID_FILE ]
then
- kill -15 `cat $FALCON_PID_FILE`
+ PID=`cat $FALCON_PID_FILE`
+ echo "Stopping $APP_TYPE running as $PID"
+ kill -15 $PID
+ WAIT=0
+ while [ $(ps -p$PID -o pid=) > /dev/null ] && [ $WAIT -lt $STOP_TIMEOUT ]; do
+ echo -n "."
+ sleep 1
+ (( WAIT++ ))
+ done
+ if [ $(ps -p$PID -o pid=) > /dev/null ]; then
+ echo -e "\nWARN: $APP_TYPE did not stop after $STOP_TIMEOUT seconds : Killing with kill -9"
+ kill -9 $PID
+ fi
+ rm -f $FALCON_PID_FILE
+ echo "Stopped $APP_TYPE !"
else
echo "pid file $FALCON_PID_FILE not present"
fi
[3/3] falcon git commit: Remove temporary folder "localhost" created
during tests. Contributed by Praveen Adlakha.
Posted by aj...@apache.org.
Remove temporary folder "localhost" created during tests. Contributed by Praveen Adlakha.
Project: http://git-wip-us.apache.org/repos/asf/falcon/repo
Commit: http://git-wip-us.apache.org/repos/asf/falcon/commit/3b8d32ff
Tree: http://git-wip-us.apache.org/repos/asf/falcon/tree/3b8d32ff
Diff: http://git-wip-us.apache.org/repos/asf/falcon/diff/3b8d32ff
Branch: refs/heads/master
Commit: 3b8d32ffdc3451f5ec11c90cfdb7e4ea2c2940b2
Parents: a30a1ac
Author: Ajay Yadava <aj...@gmail.com>
Authored: Thu Jan 28 01:20:13 2016 +0530
Committer: Ajay Yadava <aj...@gmail.com>
Committed: Thu Jan 28 01:20:13 2016 +0530
----------------------------------------------------------------------
CHANGES.txt | 2 ++
webapp/src/test/java/org/apache/falcon/lifecycle/FeedImportIT.java | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/falcon/blob/3b8d32ff/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 9fb66ef..b92d88d 100755
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -10,6 +10,8 @@ Trunk
FALCON-1230 Data based notification Service to notify execution instances when data becomes available(Pavan Kumar Kolamuri via Ajay Yadava)
IMPROVEMENTS
+ FALCON-1764 Remove temporary folder "localhost" created during tests(Praveen Adlakha via Ajay Yadava)
+
FALCON-1756 Remove PID files on service stop(Deepak Barr via Ajay Yadava)
FALCON-1771 Tool to merge pull requests (Ajay Yadava)
http://git-wip-us.apache.org/repos/asf/falcon/blob/3b8d32ff/webapp/src/test/java/org/apache/falcon/lifecycle/FeedImportIT.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/falcon/lifecycle/FeedImportIT.java b/webapp/src/test/java/org/apache/falcon/lifecycle/FeedImportIT.java
index 1fbad88..b55d660 100644
--- a/webapp/src/test/java/org/apache/falcon/lifecycle/FeedImportIT.java
+++ b/webapp/src/test/java/org/apache/falcon/lifecycle/FeedImportIT.java
@@ -52,7 +52,7 @@ public class FeedImportIT {
@AfterClass
public void tearDown() throws Exception {
HsqldbTestUtils.tearDown();
- FileUtils.deleteDirectory(new File("webapp/localhost/"));
+ FileUtils.deleteDirectory(new File("../localhost/"));
FileUtils.deleteDirectory(new File("localhost"));
}