We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add falcon


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `.CI/create_feedstocks.py`
Content:
```
1 #!/usr/bin/env python
2 """
3 Convert all recipes into feedstocks.
4 
5 This script is to be run in a TravisCI context, with all secret environment variables defined (BINSTAR_TOKEN, GH_TOKEN)
6 Such as:
7 
8     export GH_TOKEN=$(cat ~/.conda-smithy/github.token)
9 
10 """
11 from __future__ import print_function
12 
13 from conda_build.metadata import MetaData
14 from conda_smithy.github import gh_token
15 from contextlib import contextmanager
16 from datetime import datetime
17 from github import Github, GithubException, Team
18 import os.path
19 from random import choice
20 import shutil
21 import subprocess
22 import tempfile
23 
24 
25 # Enable DEBUG to run the diagnostics, without actually creating new feedstocks.
26 DEBUG = False
27 
28 
29 superlative = ['awesome', 'slick', 'formidable', 'awe-inspiring', 'breathtaking',
30                'magnificent', 'wonderous', 'stunning', 'astonishing', 'superb',
31                'splendid', 'impressive', 'unbeatable', 'excellent', 'top', 'outstanding',
32                'exalted', 'standout', 'smashing']
33 
34 
35 def list_recipes():
36     recipe_directory_name = 'recipes'
37     if os.path.isdir(recipe_directory_name):
38         recipes = os.listdir(recipe_directory_name)
39     else:
40         recipes = []
41 
42     for recipe_dir in recipes:
43         # We don't list the "example" feedstock. It is an example, and is there
44         # to be helpful.
45         if recipe_dir.startswith('example'):
46             continue
47         path = os.path.abspath(os.path.join(recipe_directory_name, recipe_dir))
48         yield path, recipe_dir
49 
50 
51 @contextmanager
52 def tmp_dir(*args, **kwargs):
53     temp_dir = tempfile.mkdtemp(*args, **kwargs)
54     try:
55         yield temp_dir
56     finally:
57         shutil.rmtree(temp_dir)
58 
59 
60 def repo_exists(organization, name):
61     token = gh_token()
62     gh = Github(token)
63     # Use the organization provided.
64     org = gh.get_organization(organization)
65     try:
66         org.get_repo(name)
67         return True
68     except GithubException as e:
69         if e.status == 404:
70             return False
71         raise
72 
73 
74 def create_team(org, name, description, repo_names):
75     # PyGithub creates secret teams, and has no way of turning that off! :(
76     post_parameters = {
77         "name": name,
78         "description": description,
79         "privacy": "closed",
80         "permission": "push",
81         "repo_names": repo_names
82     }
83     headers, data = org._requester.requestJsonAndCheck(
84         "POST",
85         org.url + "/teams",
86         input=post_parameters
87     )
88     return Team.Team(org._requester, headers, data, completed=True)
89 
90 def print_rate_limiting_info(gh):
91     # Compute some info about our GitHub API Rate Limit.
92     # Note that it doesn't count against our limit to
93     # get this info. So, we should be doing this regularly
94     # to better know when it is going to run out. Also,
95     # this will help us better understand where we are
96     # spending it and how to better optimize it.
97 
98     # Get GitHub API Rate Limit usage and total
99     gh_api_remaining, gh_api_total = gh.rate_limiting
100 
101     # Compute time until GitHub API Rate Limit reset
102     gh_api_reset_time = gh.rate_limiting_resettime
103     gh_api_reset_time = datetime.utcfromtimestamp(gh_api_reset_time)
104     gh_api_reset_time -= datetime.utcnow()
105 
106     print("")
107     print("GitHub API Rate Limit Info:")
108     print("---------------------------")
109     print("Currently remaining {remaining} out of {total}.".format(remaining=gh_api_remaining, total=gh_api_total))
110     print("Will reset in {time}.".format(time=gh_api_reset_time))
111     print("")
112 
113 
114 
115 if __name__ == '__main__':
116     is_merged_pr = (os.environ.get('TRAVIS_BRANCH') == 'master' and os.environ.get('TRAVIS_PULL_REQUEST') == 'false')
117 
118     smithy_conf = os.path.expanduser('~/.conda-smithy')
119     if not os.path.exists(smithy_conf):
120         os.mkdir(smithy_conf)
121 
122     def write_token(name, token):
123         with open(os.path.join(smithy_conf, name + '.token'), 'w') as fh:
124             fh.write(token)
125     if 'APPVEYOR_TOKEN' in os.environ:
126         write_token('appveyor', os.environ['APPVEYOR_TOKEN'])
127     if 'CIRCLE_TOKEN' in os.environ:
128         write_token('circle', os.environ['CIRCLE_TOKEN'])
129     gh = None
130     if 'GH_TOKEN' in os.environ:
131         write_token('github', os.environ['GH_TOKEN'])
132         gh = Github(os.environ['GH_TOKEN'])
133 
134         # Get our initial rate limit info.
135         print_rate_limiting_info(gh)
136 
137 
138     owner_info = ['--organization', 'conda-forge']
139 
140     print('Calculating the recipes which need to be turned into feedstocks.')
141     removed_recipes = []
142     with tmp_dir('__feedstocks') as feedstocks_dir:
143         feedstock_dirs = []
144         for recipe_dir, name in list_recipes():
145             feedstock_dir = os.path.join(feedstocks_dir, name + '-feedstock')
146             os.mkdir(feedstock_dir)
147             print('Making feedstock for {}'.format(name))
148 
149             subprocess.check_call(['conda', 'smithy', 'init', recipe_dir,
150                                    '--feedstock-directory', feedstock_dir])
151             if not is_merged_pr:
152                 # We just want to check that conda-smithy is doing its thing without having any metadata issues.
153                 continue
154 
155             feedstock_dirs.append([feedstock_dir, name, recipe_dir])
156 
157             subprocess.check_call(['git', 'remote', 'add', 'upstream_with_token',
158                                    'https://conda-forge-manager:{}@github.com/conda-forge/{}'.format(os.environ['GH_TOKEN'],
159                                                                                                      os.path.basename(feedstock_dir))],
160                                   cwd=feedstock_dir)
161 
162             # Sometimes we already have the feedstock created. We need to deal with that case.
163             if repo_exists('conda-forge', os.path.basename(feedstock_dir)):
164                 subprocess.check_call(['git', 'fetch', 'upstream_with_token'], cwd=feedstock_dir)
165                 subprocess.check_call(['git', 'branch', '-m', 'master', 'old'], cwd=feedstock_dir)
166                 try:
167                     subprocess.check_call(['git', 'checkout', '-b', 'master', 'upstream_with_token/master'], cwd=feedstock_dir)
168                 except subprocess.CalledProcessError:
169                     # Sometimes, we have a repo, but there are no commits on it! Just catch that case.
170                     subprocess.check_call(['git', 'checkout', '-b' 'master'], cwd=feedstock_dir)
171             else:
172                 subprocess.check_call(['conda', 'smithy', 'register-github', feedstock_dir] + owner_info)
173 
174         conda_forge = None
175         teams = None
176         if gh:
177             # Only get the org and teams if there is stuff to add.
178             if feedstock_dirs:
179                 conda_forge = gh.get_organization('conda-forge')
180                 teams = {team.name: team for team in conda_forge.get_teams()}
181 
182         # Break the previous loop to allow the TravisCI registering to take place only once per function call.
183         # Without this, intermittent failiures to synch the TravisCI repos ensue.
184         all_maintainers = set()
185         for feedstock_dir, name, recipe_dir in feedstock_dirs:
186             subprocess.check_call(['conda', 'smithy', 'register-ci', '--feedstock_directory', feedstock_dir] + owner_info)
187 
188             subprocess.check_call(['conda', 'smithy', 'rerender'], cwd=feedstock_dir)
189             subprocess.check_call(['git', 'commit', '-am', "Re-render the feedstock after CI registration."], cwd=feedstock_dir)
190             # Capture the output, as it may contain the GH_TOKEN.
191             out = subprocess.check_output(['git', 'push', 'upstream_with_token', 'master'], cwd=feedstock_dir,
192                                           stderr=subprocess.STDOUT)
193 
194             # Add team members as maintainers.
195             if conda_forge:
196                 meta = MetaData(recipe_dir)
197                 maintainers = set(meta.meta.get('extra', {}).get('recipe-maintainers', []))
198                 all_maintainers.update(maintainers)
199                 team_name = name.lower()
200                 repo_name = 'conda-forge/{}'.format(os.path.basename(feedstock_dir))
201 
202                 # Try to get team or create it if it doesn't exist.
203                 team = teams.get(team_name)
204                 if not team:
205                     team = create_team(
206                         conda_forge,
207                         team_name,
208                         'The {} {} contributors!'.format(choice(superlative), team_name),
209                         repo_names=[repo_name]
210                     )
211                     teams[team_name] = team
212                     current_maintainers = []
213                 else:
214                     current_maintainers = team.get_members()
215 
216                 # Add only the new maintainers to the team.
217                 current_maintainers_handles = set([each_maintainers.login.lower() for each_maintainers in current_maintainers])
218                 for new_maintainer in maintainers - current_maintainers_handles:
219                     headers, data = team._requester.requestJsonAndCheck(
220                         "PUT",
221                         team.url + "/memberships/" + new_maintainer
222                     )
223                 # Mention any maintainers that need to be removed (unlikely here).
224                 for old_maintainer in current_maintainers_handles - maintainers:
225                     print("AN OLD MEMBER ({}) NEEDS TO BE REMOVED FROM {}".format(old_maintainer, repo_name))
226 
227             # Remove this recipe from the repo.
228             removed_recipes.append(name)
229             if is_merged_pr:
230                 subprocess.check_call(['git', 'rm', '-r', recipe_dir])
231 
232     # Add new conda-forge members to all-members team. Welcome! :)
233     if conda_forge:
234         team_name = 'all-members'
235         team = teams.get(team_name)
236         if not team:
237             team = create_team(
238                 conda_forge,
239                 team_name,
240                 'All of the awesome conda-forge contributors!',
241                 []
242             )
243             teams[team_name] = team
244             current_members = []
245         else:
246             current_members = team.get_members()
247 
248         # Add only the new members to the team.
249         current_members_handles = set([each_member.login.lower() for each_member in current_members])
250         for new_member in all_maintainers - current_members_handles:
251             print("Adding a new member ({}) to conda-forge. Welcome! :)".format(new_member))
252             headers, data = team._requester.requestJsonAndCheck(
253                 "PUT",
254                 team.url + "/memberships/" + new_member
255             )
256 
257     # Commit any removed packages.
258     subprocess.check_call(['git', 'status'])
259     if removed_recipes:
260         subprocess.check_call(['git', 'checkout', os.environ.get('TRAVIS_BRANCH')])
261         msg = ('Removed recipe{s} ({}) after converting into feedstock{s}. '
262                '[ci skip]'.format(', '.join(removed_recipes),
263                          s=('s' if len(removed_recipes) > 1 else '')))
264         if is_merged_pr:
265             # Capture the output, as it may contain the GH_TOKEN.
266             out = subprocess.check_output(['git', 'remote', 'add', 'upstream_with_token',
267                                            'https://conda-forge-manager:{}@github.com/conda-forge/staged-recipes'.format(os.environ['GH_TOKEN'])],
268                                           stderr=subprocess.STDOUT)
269             subprocess.check_call(['git', 'commit', '-m', msg])
270             # Capture the output, as it may contain the GH_TOKEN.
271             out = subprocess.check_output(['git', 'push', 'upstream_with_token', os.environ.get('TRAVIS_BRANCH')],
272                                           stderr=subprocess.STDOUT)
273         else:
274             print('Would git commit, with the following message: \n   {}'.format(msg))
275 
276     if gh:
277         # Get our final rate limit info.
278         print_rate_limiting_info(gh)
279
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/.CI/create_feedstocks.py b/.CI/create_feedstocks.py
--- a/.CI/create_feedstocks.py
+++ b/.CI/create_feedstocks.py
@@ -32,8 +32,8 @@
                'exalted', 'standout', 'smashing']
 
 
+recipe_directory_name = 'recipes'
 def list_recipes():
-    recipe_directory_name = 'recipes'
     if os.path.isdir(recipe_directory_name):
         recipes = os.listdir(recipe_directory_name)
     else:
@@ -138,7 +138,6 @@
     owner_info = ['--organization', 'conda-forge']
 
     print('Calculating the recipes which need to be turned into feedstocks.')
-    removed_recipes = []
     with tmp_dir('__feedstocks') as feedstocks_dir:
         feedstock_dirs = []
         for recipe_dir, name in list_recipes():
@@ -180,7 +179,7 @@
                 teams = {team.name: team for team in conda_forge.get_teams()}
 
         # Break the previous loop to allow the TravisCI registering to take place only once per function call.
-        # Without this, intermittent failiures to synch the TravisCI repos ensue.
+        # Without this, intermittent failures to synch the TravisCI repos ensue.
         all_maintainers = set()
         for feedstock_dir, name, recipe_dir in feedstock_dirs:
             subprocess.check_call(['conda', 'smithy', 'register-ci', '--feedstock_directory', feedstock_dir] + owner_info)
@@ -225,7 +224,6 @@
                     print("AN OLD MEMBER ({}) NEEDS TO BE REMOVED FROM {}".format(old_maintainer, repo_name))
 
             # Remove this recipe from the repo.
-            removed_recipes.append(name)
             if is_merged_pr:
                 subprocess.check_call(['git', 'rm', '-r', recipe_dir])
 
@@ -254,10 +252,34 @@
                 team.url + "/memberships/" + new_member
             )
 
+    # Update status based on the remote.
+    subprocess.check_call(['git', 'stash', '--keep-index', '--include-untracked'])
+    subprocess.check_call(['git', 'fetch'])
+    subprocess.check_call(['git', 'rebase', '--autostash'])
+    subprocess.check_call(['git', 'add', '.'])
+    try:
+        subprocess.check_call(['git', 'stash', 'pop'])
+    except subprocess.CalledProcessError:
+        # In case there was nothing to stash.
+        # Finish quietly.
+        pass
+
+    # Generate a fresh listing of recipes removed.
+    # This gets pretty ugly as we parse `git status --porcelain`.
+    #
+    # * Each line we get back is a change to a file in the recipe directory.
+    # * We narrow the list down to recipes that are staged for deletion (ignores examples).
+    # * Then we clean up the list so that it only has the recipe names.
+    removed_recipes = subprocess.check_output(['git', 'status', '--porcelain', recipe_directory_name],
+                                              universal_newlines=True)
+    removed_recipes = removed_recipes.splitlines()
+    removed_recipes = filter(lambda _: _.startswith("D "), removed_recipes)
+    removed_recipes = list(map(lambda _ : _.replace("D", "", 1).lstrip(), removed_recipes))
+    removed_recipes = list(set(map(lambda _ : os.path.basename(os.path.dirname(_)), removed_recipes)))
+
     # Commit any removed packages.
     subprocess.check_call(['git', 'status'])
     if removed_recipes:
-        subprocess.check_call(['git', 'checkout', os.environ.get('TRAVIS_BRANCH')])
         msg = ('Removed recipe{s} ({}) after converting into feedstock{s}. '
                '[ci skip]'.format(', '.join(removed_recipes),
                          s=('s' if len(removed_recipes) > 1 else '')))

{"golden_diff": "diff --git a/.CI/create_feedstocks.py b/.CI/create_feedstocks.py\n--- a/.CI/create_feedstocks.py\n+++ b/.CI/create_feedstocks.py\n@@ -32,8 +32,8 @@\n                'exalted', 'standout', 'smashing']\n \n \n+recipe_directory_name = 'recipes'\n def list_recipes():\n-    recipe_directory_name = 'recipes'\n     if os.path.isdir(recipe_directory_name):\n         recipes = os.listdir(recipe_directory_name)\n     else:\n@@ -138,7 +138,6 @@\n     owner_info = ['--organization', 'conda-forge']\n \n     print('Calculating the recipes which need to be turned into feedstocks.')\n-    removed_recipes = []\n     with tmp_dir('__feedstocks') as feedstocks_dir:\n         feedstock_dirs = []\n         for recipe_dir, name in list_recipes():\n@@ -180,7 +179,7 @@\n                 teams = {team.name: team for team in conda_forge.get_teams()}\n \n         # Break the previous loop to allow the TravisCI registering to take place only once per function call.\n-        # Without this, intermittent failiures to synch the TravisCI repos ensue.\n+        # Without this, intermittent failures to synch the TravisCI repos ensue.\n         all_maintainers = set()\n         for feedstock_dir, name, recipe_dir in feedstock_dirs:\n             subprocess.check_call(['conda', 'smithy', 'register-ci', '--feedstock_directory', feedstock_dir] + owner_info)\n@@ -225,7 +224,6 @@\n                     print(\"AN OLD MEMBER ({}) NEEDS TO BE REMOVED FROM {}\".format(old_maintainer, repo_name))\n \n             # Remove this recipe from the repo.\n-            removed_recipes.append(name)\n             if is_merged_pr:\n                 subprocess.check_call(['git', 'rm', '-r', recipe_dir])\n \n@@ -254,10 +252,34 @@\n                 team.url + \"/memberships/\" + new_member\n             )\n \n+    # Update status based on the remote.\n+    subprocess.check_call(['git', 'stash', '--keep-index', '--include-untracked'])\n+    subprocess.check_call(['git', 'fetch'])\n+    subprocess.check_call(['git', 'rebase', '--autostash'])\n+    subprocess.check_call(['git', 'add', '.'])\n+    try:\n+        subprocess.check_call(['git', 'stash', 'pop'])\n+    except subprocess.CalledProcessError:\n+        # In case there was nothing to stash.\n+        # Finish quietly.\n+        pass\n+\n+    # Generate a fresh listing of recipes removed.\n+    # This gets pretty ugly as we parse `git status --porcelain`.\n+    #\n+    # * Each line we get back is a change to a file in the recipe directory.\n+    # * We narrow the list down to recipes that are staged for deletion (ignores examples).\n+    # * Then we clean up the list so that it only has the recipe names.\n+    removed_recipes = subprocess.check_output(['git', 'status', '--porcelain', recipe_directory_name],\n+                                              universal_newlines=True)\n+    removed_recipes = removed_recipes.splitlines()\n+    removed_recipes = filter(lambda _: _.startswith(\"D \"), removed_recipes)\n+    removed_recipes = list(map(lambda _ : _.replace(\"D\", \"\", 1).lstrip(), removed_recipes))\n+    removed_recipes = list(set(map(lambda _ : os.path.basename(os.path.dirname(_)), removed_recipes)))\n+\n     # Commit any removed packages.\n     subprocess.check_call(['git', 'status'])\n     if removed_recipes:\n-        subprocess.check_call(['git', 'checkout', os.environ.get('TRAVIS_BRANCH')])\n         msg = ('Removed recipe{s} ({}) after converting into feedstock{s}. '\n                '[ci skip]'.format(', '.join(removed_recipes),\n                          s=('s' if len(removed_recipes) > 1 else '')))\n", "issue": "Add falcon\n\n", "before_files": [{"content": "#!/usr/bin/env python\n\"\"\"\nConvert all recipes into feedstocks.\n\nThis script is to be run in a TravisCI context, with all secret environment variables defined (BINSTAR_TOKEN, GH_TOKEN)\nSuch as:\n\n    export GH_TOKEN=$(cat ~/.conda-smithy/github.token)\n\n\"\"\"\nfrom __future__ import print_function\n\nfrom conda_build.metadata import MetaData\nfrom conda_smithy.github import gh_token\nfrom contextlib import contextmanager\nfrom datetime import datetime\nfrom github import Github, GithubException, Team\nimport os.path\nfrom random import choice\nimport shutil\nimport subprocess\nimport tempfile\n\n\n# Enable DEBUG to run the diagnostics, without actually creating new feedstocks.\nDEBUG = False\n\n\nsuperlative = ['awesome', 'slick', 'formidable', 'awe-inspiring', 'breathtaking',\n               'magnificent', 'wonderous', 'stunning', 'astonishing', 'superb',\n               'splendid', 'impressive', 'unbeatable', 'excellent', 'top', 'outstanding',\n               'exalted', 'standout', 'smashing']\n\n\ndef list_recipes():\n    recipe_directory_name = 'recipes'\n    if os.path.isdir(recipe_directory_name):\n        recipes = os.listdir(recipe_directory_name)\n    else:\n        recipes = []\n\n    for recipe_dir in recipes:\n        # We don't list the \"example\" feedstock. It is an example, and is there\n        # to be helpful.\n        if recipe_dir.startswith('example'):\n            continue\n        path = os.path.abspath(os.path.join(recipe_directory_name, recipe_dir))\n        yield path, recipe_dir\n\n\n@contextmanager\ndef tmp_dir(*args, **kwargs):\n    temp_dir = tempfile.mkdtemp(*args, **kwargs)\n    try:\n        yield temp_dir\n    finally:\n        shutil.rmtree(temp_dir)\n\n\ndef repo_exists(organization, name):\n    token = gh_token()\n    gh = Github(token)\n    # Use the organization provided.\n    org = gh.get_organization(organization)\n    try:\n        org.get_repo(name)\n        return True\n    except GithubException as e:\n        if e.status == 404:\n            return False\n        raise\n\n\ndef create_team(org, name, description, repo_names):\n    # PyGithub creates secret teams, and has no way of turning that off! :(\n    post_parameters = {\n        \"name\": name,\n        \"description\": description,\n        \"privacy\": \"closed\",\n        \"permission\": \"push\",\n        \"repo_names\": repo_names\n    }\n    headers, data = org._requester.requestJsonAndCheck(\n        \"POST\",\n        org.url + \"/teams\",\n        input=post_parameters\n    )\n    return Team.Team(org._requester, headers, data, completed=True)\n\ndef print_rate_limiting_info(gh):\n    # Compute some info about our GitHub API Rate Limit.\n    # Note that it doesn't count against our limit to\n    # get this info. So, we should be doing this regularly\n    # to better know when it is going to run out. Also,\n    # this will help us better understand where we are\n    # spending it and how to better optimize it.\n\n    # Get GitHub API Rate Limit usage and total\n    gh_api_remaining, gh_api_total = gh.rate_limiting\n\n    # Compute time until GitHub API Rate Limit reset\n    gh_api_reset_time = gh.rate_limiting_resettime\n    gh_api_reset_time = datetime.utcfromtimestamp(gh_api_reset_time)\n    gh_api_reset_time -= datetime.utcnow()\n\n    print(\"\")\n    print(\"GitHub API Rate Limit Info:\")\n    print(\"---------------------------\")\n    print(\"Currently remaining {remaining} out of {total}.\".format(remaining=gh_api_remaining, total=gh_api_total))\n    print(\"Will reset in {time}.\".format(time=gh_api_reset_time))\n    print(\"\")\n\n\n\nif __name__ == '__main__':\n    is_merged_pr = (os.environ.get('TRAVIS_BRANCH') == 'master' and os.environ.get('TRAVIS_PULL_REQUEST') == 'false')\n\n    smithy_conf = os.path.expanduser('~/.conda-smithy')\n    if not os.path.exists(smithy_conf):\n        os.mkdir(smithy_conf)\n\n    def write_token(name, token):\n        with open(os.path.join(smithy_conf, name + '.token'), 'w') as fh:\n            fh.write(token)\n    if 'APPVEYOR_TOKEN' in os.environ:\n        write_token('appveyor', os.environ['APPVEYOR_TOKEN'])\n    if 'CIRCLE_TOKEN' in os.environ:\n        write_token('circle', os.environ['CIRCLE_TOKEN'])\n    gh = None\n    if 'GH_TOKEN' in os.environ:\n        write_token('github', os.environ['GH_TOKEN'])\n        gh = Github(os.environ['GH_TOKEN'])\n\n        # Get our initial rate limit info.\n        print_rate_limiting_info(gh)\n\n\n    owner_info = ['--organization', 'conda-forge']\n\n    print('Calculating the recipes which need to be turned into feedstocks.')\n    removed_recipes = []\n    with tmp_dir('__feedstocks') as feedstocks_dir:\n        feedstock_dirs = []\n        for recipe_dir, name in list_recipes():\n            feedstock_dir = os.path.join(feedstocks_dir, name + '-feedstock')\n            os.mkdir(feedstock_dir)\n            print('Making feedstock for {}'.format(name))\n\n            subprocess.check_call(['conda', 'smithy', 'init', recipe_dir,\n                                   '--feedstock-directory', feedstock_dir])\n            if not is_merged_pr:\n                # We just want to check that conda-smithy is doing its thing without having any metadata issues.\n                continue\n\n            feedstock_dirs.append([feedstock_dir, name, recipe_dir])\n\n            subprocess.check_call(['git', 'remote', 'add', 'upstream_with_token',\n                                   'https://conda-forge-manager:{}@github.com/conda-forge/{}'.format(os.environ['GH_TOKEN'],\n                                                                                                     os.path.basename(feedstock_dir))],\n                                  cwd=feedstock_dir)\n\n            # Sometimes we already have the feedstock created. We need to deal with that case.\n            if repo_exists('conda-forge', os.path.basename(feedstock_dir)):\n                subprocess.check_call(['git', 'fetch', 'upstream_with_token'], cwd=feedstock_dir)\n                subprocess.check_call(['git', 'branch', '-m', 'master', 'old'], cwd=feedstock_dir)\n                try:\n                    subprocess.check_call(['git', 'checkout', '-b', 'master', 'upstream_with_token/master'], cwd=feedstock_dir)\n                except subprocess.CalledProcessError:\n                    # Sometimes, we have a repo, but there are no commits on it! Just catch that case.\n                    subprocess.check_call(['git', 'checkout', '-b' 'master'], cwd=feedstock_dir)\n            else:\n                subprocess.check_call(['conda', 'smithy', 'register-github', feedstock_dir] + owner_info)\n\n        conda_forge = None\n        teams = None\n        if gh:\n            # Only get the org and teams if there is stuff to add.\n            if feedstock_dirs:\n                conda_forge = gh.get_organization('conda-forge')\n                teams = {team.name: team for team in conda_forge.get_teams()}\n\n        # Break the previous loop to allow the TravisCI registering to take place only once per function call.\n        # Without this, intermittent failiures to synch the TravisCI repos ensue.\n        all_maintainers = set()\n        for feedstock_dir, name, recipe_dir in feedstock_dirs:\n            subprocess.check_call(['conda', 'smithy', 'register-ci', '--feedstock_directory', feedstock_dir] + owner_info)\n\n            subprocess.check_call(['conda', 'smithy', 'rerender'], cwd=feedstock_dir)\n            subprocess.check_call(['git', 'commit', '-am', \"Re-render the feedstock after CI registration.\"], cwd=feedstock_dir)\n            # Capture the output, as it may contain the GH_TOKEN.\n            out = subprocess.check_output(['git', 'push', 'upstream_with_token', 'master'], cwd=feedstock_dir,\n                                          stderr=subprocess.STDOUT)\n\n            # Add team members as maintainers.\n            if conda_forge:\n                meta = MetaData(recipe_dir)\n                maintainers = set(meta.meta.get('extra', {}).get('recipe-maintainers', []))\n                all_maintainers.update(maintainers)\n                team_name = name.lower()\n                repo_name = 'conda-forge/{}'.format(os.path.basename(feedstock_dir))\n\n                # Try to get team or create it if it doesn't exist.\n                team = teams.get(team_name)\n                if not team:\n                    team = create_team(\n                        conda_forge,\n                        team_name,\n                        'The {} {} contributors!'.format(choice(superlative), team_name),\n                        repo_names=[repo_name]\n                    )\n                    teams[team_name] = team\n                    current_maintainers = []\n                else:\n                    current_maintainers = team.get_members()\n\n                # Add only the new maintainers to the team.\n                current_maintainers_handles = set([each_maintainers.login.lower() for each_maintainers in current_maintainers])\n                for new_maintainer in maintainers - current_maintainers_handles:\n                    headers, data = team._requester.requestJsonAndCheck(\n                        \"PUT\",\n                        team.url + \"/memberships/\" + new_maintainer\n                    )\n                # Mention any maintainers that need to be removed (unlikely here).\n                for old_maintainer in current_maintainers_handles - maintainers:\n                    print(\"AN OLD MEMBER ({}) NEEDS TO BE REMOVED FROM {}\".format(old_maintainer, repo_name))\n\n            # Remove this recipe from the repo.\n            removed_recipes.append(name)\n            if is_merged_pr:\n                subprocess.check_call(['git', 'rm', '-r', recipe_dir])\n\n    # Add new conda-forge members to all-members team. Welcome! :)\n    if conda_forge:\n        team_name = 'all-members'\n        team = teams.get(team_name)\n        if not team:\n            team = create_team(\n                conda_forge,\n                team_name,\n                'All of the awesome conda-forge contributors!',\n                []\n            )\n            teams[team_name] = team\n            current_members = []\n        else:\n            current_members = team.get_members()\n\n        # Add only the new members to the team.\n        current_members_handles = set([each_member.login.lower() for each_member in current_members])\n        for new_member in all_maintainers - current_members_handles:\n            print(\"Adding a new member ({}) to conda-forge. Welcome! :)\".format(new_member))\n            headers, data = team._requester.requestJsonAndCheck(\n                \"PUT\",\n                team.url + \"/memberships/\" + new_member\n            )\n\n    # Commit any removed packages.\n    subprocess.check_call(['git', 'status'])\n    if removed_recipes:\n        subprocess.check_call(['git', 'checkout', os.environ.get('TRAVIS_BRANCH')])\n        msg = ('Removed recipe{s} ({}) after converting into feedstock{s}. '\n               '[ci skip]'.format(', '.join(removed_recipes),\n                         s=('s' if len(removed_recipes) > 1 else '')))\n        if is_merged_pr:\n            # Capture the output, as it may contain the GH_TOKEN.\n            out = subprocess.check_output(['git', 'remote', 'add', 'upstream_with_token',\n                                           'https://conda-forge-manager:{}@github.com/conda-forge/staged-recipes'.format(os.environ['GH_TOKEN'])],\n                                          stderr=subprocess.STDOUT)\n            subprocess.check_call(['git', 'commit', '-m', msg])\n            # Capture the output, as it may contain the GH_TOKEN.\n            out = subprocess.check_output(['git', 'push', 'upstream_with_token', os.environ.get('TRAVIS_BRANCH')],\n                                          stderr=subprocess.STDOUT)\n        else:\n            print('Would git commit, with the following message: \\n   {}'.format(msg))\n\n    if gh:\n        # Get our final rate limit info.\n        print_rate_limiting_info(gh)\n", "path": ".CI/create_feedstocks.py"}], "after_files": [{"content": "#!/usr/bin/env python\n\"\"\"\nConvert all recipes into feedstocks.\n\nThis script is to be run in a TravisCI context, with all secret environment variables defined (BINSTAR_TOKEN, GH_TOKEN)\nSuch as:\n\n    export GH_TOKEN=$(cat ~/.conda-smithy/github.token)\n\n\"\"\"\nfrom __future__ import print_function\n\nfrom conda_build.metadata import MetaData\nfrom conda_smithy.github import gh_token\nfrom contextlib import contextmanager\nfrom datetime import datetime\nfrom github import Github, GithubException, Team\nimport os.path\nfrom random import choice\nimport shutil\nimport subprocess\nimport tempfile\n\n\n# Enable DEBUG to run the diagnostics, without actually creating new feedstocks.\nDEBUG = False\n\n\nsuperlative = ['awesome', 'slick', 'formidable', 'awe-inspiring', 'breathtaking',\n               'magnificent', 'wonderous', 'stunning', 'astonishing', 'superb',\n               'splendid', 'impressive', 'unbeatable', 'excellent', 'top', 'outstanding',\n               'exalted', 'standout', 'smashing']\n\n\nrecipe_directory_name = 'recipes'\ndef list_recipes():\n    if os.path.isdir(recipe_directory_name):\n        recipes = os.listdir(recipe_directory_name)\n    else:\n        recipes = []\n\n    for recipe_dir in recipes:\n        # We don't list the \"example\" feedstock. It is an example, and is there\n        # to be helpful.\n        if recipe_dir.startswith('example'):\n            continue\n        path = os.path.abspath(os.path.join(recipe_directory_name, recipe_dir))\n        yield path, recipe_dir\n\n\n@contextmanager\ndef tmp_dir(*args, **kwargs):\n    temp_dir = tempfile.mkdtemp(*args, **kwargs)\n    try:\n        yield temp_dir\n    finally:\n        shutil.rmtree(temp_dir)\n\n\ndef repo_exists(organization, name):\n    token = gh_token()\n    gh = Github(token)\n    # Use the organization provided.\n    org = gh.get_organization(organization)\n    try:\n        org.get_repo(name)\n        return True\n    except GithubException as e:\n        if e.status == 404:\n            return False\n        raise\n\n\ndef create_team(org, name, description, repo_names):\n    # PyGithub creates secret teams, and has no way of turning that off! :(\n    post_parameters = {\n        \"name\": name,\n        \"description\": description,\n        \"privacy\": \"closed\",\n        \"permission\": \"push\",\n        \"repo_names\": repo_names\n    }\n    headers, data = org._requester.requestJsonAndCheck(\n        \"POST\",\n        org.url + \"/teams\",\n        input=post_parameters\n    )\n    return Team.Team(org._requester, headers, data, completed=True)\n\ndef print_rate_limiting_info(gh):\n    # Compute some info about our GitHub API Rate Limit.\n    # Note that it doesn't count against our limit to\n    # get this info. So, we should be doing this regularly\n    # to better know when it is going to run out. Also,\n    # this will help us better understand where we are\n    # spending it and how to better optimize it.\n\n    # Get GitHub API Rate Limit usage and total\n    gh_api_remaining, gh_api_total = gh.rate_limiting\n\n    # Compute time until GitHub API Rate Limit reset\n    gh_api_reset_time = gh.rate_limiting_resettime\n    gh_api_reset_time = datetime.utcfromtimestamp(gh_api_reset_time)\n    gh_api_reset_time -= datetime.utcnow()\n\n    print(\"\")\n    print(\"GitHub API Rate Limit Info:\")\n    print(\"---------------------------\")\n    print(\"Currently remaining {remaining} out of {total}.\".format(remaining=gh_api_remaining, total=gh_api_total))\n    print(\"Will reset in {time}.\".format(time=gh_api_reset_time))\n    print(\"\")\n\n\n\nif __name__ == '__main__':\n    is_merged_pr = (os.environ.get('TRAVIS_BRANCH') == 'master' and os.environ.get('TRAVIS_PULL_REQUEST') == 'false')\n\n    smithy_conf = os.path.expanduser('~/.conda-smithy')\n    if not os.path.exists(smithy_conf):\n        os.mkdir(smithy_conf)\n\n    def write_token(name, token):\n        with open(os.path.join(smithy_conf, name + '.token'), 'w') as fh:\n            fh.write(token)\n    if 'APPVEYOR_TOKEN' in os.environ:\n        write_token('appveyor', os.environ['APPVEYOR_TOKEN'])\n    if 'CIRCLE_TOKEN' in os.environ:\n        write_token('circle', os.environ['CIRCLE_TOKEN'])\n    gh = None\n    if 'GH_TOKEN' in os.environ:\n        write_token('github', os.environ['GH_TOKEN'])\n        gh = Github(os.environ['GH_TOKEN'])\n\n        # Get our initial rate limit info.\n        print_rate_limiting_info(gh)\n\n\n    owner_info = ['--organization', 'conda-forge']\n\n    print('Calculating the recipes which need to be turned into feedstocks.')\n    with tmp_dir('__feedstocks') as feedstocks_dir:\n        feedstock_dirs = []\n        for recipe_dir, name in list_recipes():\n            feedstock_dir = os.path.join(feedstocks_dir, name + '-feedstock')\n            os.mkdir(feedstock_dir)\n            print('Making feedstock for {}'.format(name))\n\n            subprocess.check_call(['conda', 'smithy', 'init', recipe_dir,\n                                   '--feedstock-directory', feedstock_dir])\n            if not is_merged_pr:\n                # We just want to check that conda-smithy is doing its thing without having any metadata issues.\n                continue\n\n            feedstock_dirs.append([feedstock_dir, name, recipe_dir])\n\n            subprocess.check_call(['git', 'remote', 'add', 'upstream_with_token',\n                                   'https://conda-forge-manager:{}@github.com/conda-forge/{}'.format(os.environ['GH_TOKEN'],\n                                                                                                     os.path.basename(feedstock_dir))],\n                                  cwd=feedstock_dir)\n\n            # Sometimes we already have the feedstock created. We need to deal with that case.\n            if repo_exists('conda-forge', os.path.basename(feedstock_dir)):\n                subprocess.check_call(['git', 'fetch', 'upstream_with_token'], cwd=feedstock_dir)\n                subprocess.check_call(['git', 'branch', '-m', 'master', 'old'], cwd=feedstock_dir)\n                try:\n                    subprocess.check_call(['git', 'checkout', '-b', 'master', 'upstream_with_token/master'], cwd=feedstock_dir)\n                except subprocess.CalledProcessError:\n                    # Sometimes, we have a repo, but there are no commits on it! Just catch that case.\n                    subprocess.check_call(['git', 'checkout', '-b' 'master'], cwd=feedstock_dir)\n            else:\n                subprocess.check_call(['conda', 'smithy', 'register-github', feedstock_dir] + owner_info)\n\n        conda_forge = None\n        teams = None\n        if gh:\n            # Only get the org and teams if there is stuff to add.\n            if feedstock_dirs:\n                conda_forge = gh.get_organization('conda-forge')\n                teams = {team.name: team for team in conda_forge.get_teams()}\n\n        # Break the previous loop to allow the TravisCI registering to take place only once per function call.\n        # Without this, intermittent failures to synch the TravisCI repos ensue.\n        all_maintainers = set()\n        for feedstock_dir, name, recipe_dir in feedstock_dirs:\n            subprocess.check_call(['conda', 'smithy', 'register-ci', '--feedstock_directory', feedstock_dir] + owner_info)\n\n            subprocess.check_call(['conda', 'smithy', 'rerender'], cwd=feedstock_dir)\n            subprocess.check_call(['git', 'commit', '-am', \"Re-render the feedstock after CI registration.\"], cwd=feedstock_dir)\n            # Capture the output, as it may contain the GH_TOKEN.\n            out = subprocess.check_output(['git', 'push', 'upstream_with_token', 'master'], cwd=feedstock_dir,\n                                          stderr=subprocess.STDOUT)\n\n            # Add team members as maintainers.\n            if conda_forge:\n                meta = MetaData(recipe_dir)\n                maintainers = set(meta.meta.get('extra', {}).get('recipe-maintainers', []))\n                all_maintainers.update(maintainers)\n                team_name = name.lower()\n                repo_name = 'conda-forge/{}'.format(os.path.basename(feedstock_dir))\n\n                # Try to get team or create it if it doesn't exist.\n                team = teams.get(team_name)\n                if not team:\n                    team = create_team(\n                        conda_forge,\n                        team_name,\n                        'The {} {} contributors!'.format(choice(superlative), team_name),\n                        repo_names=[repo_name]\n                    )\n                    teams[team_name] = team\n                    current_maintainers = []\n                else:\n                    current_maintainers = team.get_members()\n\n                # Add only the new maintainers to the team.\n                current_maintainers_handles = set([each_maintainers.login.lower() for each_maintainers in current_maintainers])\n                for new_maintainer in maintainers - current_maintainers_handles:\n                    headers, data = team._requester.requestJsonAndCheck(\n                        \"PUT\",\n                        team.url + \"/memberships/\" + new_maintainer\n                    )\n                # Mention any maintainers that need to be removed (unlikely here).\n                for old_maintainer in current_maintainers_handles - maintainers:\n                    print(\"AN OLD MEMBER ({}) NEEDS TO BE REMOVED FROM {}\".format(old_maintainer, repo_name))\n\n            # Remove this recipe from the repo.\n            if is_merged_pr:\n                subprocess.check_call(['git', 'rm', '-r', recipe_dir])\n\n    # Add new conda-forge members to all-members team. Welcome! :)\n    if conda_forge:\n        team_name = 'all-members'\n        team = teams.get(team_name)\n        if not team:\n            team = create_team(\n                conda_forge,\n                team_name,\n                'All of the awesome conda-forge contributors!',\n                []\n            )\n            teams[team_name] = team\n            current_members = []\n        else:\n            current_members = team.get_members()\n\n        # Add only the new members to the team.\n        current_members_handles = set([each_member.login.lower() for each_member in current_members])\n        for new_member in all_maintainers - current_members_handles:\n            print(\"Adding a new member ({}) to conda-forge. Welcome! :)\".format(new_member))\n            headers, data = team._requester.requestJsonAndCheck(\n                \"PUT\",\n                team.url + \"/memberships/\" + new_member\n            )\n\n    # Update status based on the remote.\n    subprocess.check_call(['git', 'stash', '--keep-index', '--include-untracked'])\n    subprocess.check_call(['git', 'fetch'])\n    subprocess.check_call(['git', 'rebase', '--autostash'])\n    subprocess.check_call(['git', 'add', '.'])\n    try:\n        subprocess.check_call(['git', 'stash', 'pop'])\n    except subprocess.CalledProcessError:\n        # In case there was nothing to stash.\n        # Finish quietly.\n        pass\n\n    # Generate a fresh listing of recipes removed.\n    # This gets pretty ugly as we parse `git status --porcelain`.\n    #\n    # * Each line we get back is a change to a file in the recipe directory.\n    # * We narrow the list down to recipes that are staged for deletion (ignores examples).\n    # * Then we clean up the list so that it only has the recipe names.\n    removed_recipes = subprocess.check_output(['git', 'status', '--porcelain', recipe_directory_name],\n                                              universal_newlines=True)\n    removed_recipes = removed_recipes.splitlines()\n    removed_recipes = filter(lambda _: _.startswith(\"D \"), removed_recipes)\n    removed_recipes = list(map(lambda _ : _.replace(\"D\", \"\", 1).lstrip(), removed_recipes))\n    removed_recipes = list(set(map(lambda _ : os.path.basename(os.path.dirname(_)), removed_recipes)))\n\n    # Commit any removed packages.\n    subprocess.check_call(['git', 'status'])\n    if removed_recipes:\n        msg = ('Removed recipe{s} ({}) after converting into feedstock{s}. '\n               '[ci skip]'.format(', '.join(removed_recipes),\n                         s=('s' if len(removed_recipes) > 1 else '')))\n        if is_merged_pr:\n            # Capture the output, as it may contain the GH_TOKEN.\n            out = subprocess.check_output(['git', 'remote', 'add', 'upstream_with_token',\n                                           'https://conda-forge-manager:{}@github.com/conda-forge/staged-recipes'.format(os.environ['GH_TOKEN'])],\n                                          stderr=subprocess.STDOUT)\n            subprocess.check_call(['git', 'commit', '-m', msg])\n            # Capture the output, as it may contain the GH_TOKEN.\n            out = subprocess.check_output(['git', 'push', 'upstream_with_token', os.environ.get('TRAVIS_BRANCH')],\n                                          stderr=subprocess.STDOUT)\n        else:\n            print('Would git commit, with the following message: \\n   {}'.format(msg))\n\n    if gh:\n        # Get our final rate limit info.\n        print_rate_limiting_info(gh)\n", "path": ".CI/create_feedstocks.py"}]}