We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
CircleCi tests are failing unexpectedly while downloading node modules
Screenshot:
![image](https://lh3.googleusercontent.com/-abvZp1fR4cs/Xbm0FK6XvVI/AAAAAAAADGo/sBcT85_wZIsAMWs3CxsFsFnHAMzEItAaACK8BGAsYHg/s0/2019-10-30.png)

Link:
https://circleci.com/gh/oppia/oppia/22306?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link

CircleCi tests are failing unexpectedly while downloading node modules
Screenshot:
![image](https://lh3.googleusercontent.com/-abvZp1fR4cs/Xbm0FK6XvVI/AAAAAAAADGo/sBcT85_wZIsAMWs3CxsFsFnHAMzEItAaACK8BGAsYHg/s0/2019-10-30.png)

Link:
https://circleci.com/gh/oppia/oppia/22306?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `scripts/setup.py`
Content:
```
1 # Copyright 2019 The Oppia Authors. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the 'License');
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an 'AS-IS' BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """Python execution environent set up for all scripts."""
16 
17 from __future__ import absolute_import  # pylint: disable=import-only-modules
18 from __future__ import unicode_literals  # pylint: disable=import-only-modules
19 
20 import argparse
21 import os
22 import sys
23 import tarfile
24 
25 import python_utils
26 
27 from . import clean
28 from . import common
29 
30 _PARSER = argparse.ArgumentParser(description="""
31 Python execution environent set up for all scripts.
32 """)
33 
34 
35 def create_directory(directory_path):
36     """Creates a new directory. Does not do anything if directory already
37     exists.
38 
39     Args:
40         directory_path: str. Directory path to be created.
41     """
42     if os.path.exists(directory_path):
43         return
44     os.makedirs(directory_path)
45 
46 
47 # This function takes a command for python as its only input.
48 # It checks this input for a specific version of python and returns false
49 # if it does not match the expected prefix.
50 def test_python_version():
51     running_python_version = '{0[0]}.{0[1]}'.format(sys.version_info)
52     if running_python_version != '2.7':
53         python_utils.PRINT('Please use Python2.7. Exiting...')
54         # If OS is Windows, print helpful error message about adding Python to
55         # path.
56         os_info = os.uname()
57         if os_info[0] != 'Darwin' and os_info[0] != 'Linux':
58             common.print_each_string_after_two_new_lines([
59                 'It looks like you are using Windows. If you have Python '
60                 'installed,',
61                 'make sure it is in your PATH and that PYTHONPATH is set.',
62                 'If you have two versions of Python (ie, Python 2.7 and 3), '
63                 'specify 2.7 before other versions of Python when setting the '
64                 'PATH.',
65                 'Here are some helpful articles:',
66                 'http://docs.python-guide.org/en/latest/starting/install/win/',
67                 'https://stackoverflow.com/questions/3701646/how-to-add-to-the-'
68                 'pythonpath-in-windows-7'])
69         # Exit when no suitable Python environment can be found.
70         raise Exception
71 
72 
73 def download_and_install_package(url_to_retrieve, filename):
74     """Downloads and installs package in Oppia tools directory.
75 
76     Args:
77         url_to_retrieve: string. The url from which package is to be
78             downloaded.
79         filename: string. The name of the tar file.
80     """
81     python_utils.url_retrieve(url_to_retrieve, filename=filename)
82     tar = tarfile.open(name=filename)
83     tar.extractall(path=common.OPPIA_TOOLS_DIR)
84     tar.close()
85     os.remove(filename)
86 
87 
88 def main(args=None):
89     """Runs the script to setup Oppia."""
90     unused_parsed_args = _PARSER.parse_args(args=args)
91     test_python_version()
92 
93     # The second option allows this script to also be run from deployment
94     # folders.
95     if not os.getcwd().endswith('oppia') and not os.getcwd().endswith(
96             'deploy-'):
97         python_utils.PRINT('')
98         python_utils.PRINT(
99             'WARNING   This script should be run from the oppia/ root folder.')
100         python_utils.PRINT('')
101         raise Exception
102 
103     # Set COMMON_DIR to the absolute path of the directory above OPPIA_DIR. This
104     # is necessary becaue COMMON_DIR (or subsequent variables which refer to it)
105     # may use it in a situation where relative paths won't work as expected(such
106     # as $PYTHONPATH).
107     create_directory(common.OPPIA_TOOLS_DIR)
108     create_directory(common.THIRD_PARTY_DIR)
109     create_directory(common.NODE_MODULES_PATH)
110 
111     os_info = os.uname()
112     if os_info[0] != 'Darwin' and os_info[0] != 'Linux':
113         # Node is a requirement for all installation scripts. Here, we check if
114         # the OS supports node.js installation; if not, we exit with an error.
115         common.print_each_string_after_two_new_lines([
116             'WARNING: Unsupported OS for installation of node.js.',
117             'If you are running this script on Windows, see the instructions',
118             'here regarding installation of node.js:',
119             'https://github.com/oppia/oppia/wiki/Installing-Oppia-%28Windows'
120             '%29',
121             'STATUS: Installation completed except for node.js. Exiting.'])
122         raise Exception
123 
124     # Download and install node.js.
125     python_utils.PRINT(
126         'Checking if node.js is installed in %s' % common.OPPIA_TOOLS_DIR)
127     if not os.path.exists(common.NODE_PATH):
128         python_utils.PRINT('Installing Node.js')
129         if os_info[0] == 'Darwin':
130             if os_info[4] == 'x86_64':
131                 node_file_name = 'node-v10.15.3-darwin-x64'
132             else:
133                 node_file_name = 'node-v10.15.3-darwin-x86'
134         elif os_info[0] == 'Linux':
135             if os_info[4] == 'x86_64':
136                 node_file_name = 'node-v10.15.3-linux-x64'
137             else:
138                 node_file_name = 'node-v10.15.3-linux-x86'
139 
140         download_and_install_package(
141             'https://nodejs.org/dist/v10.15.3/%s.tar.gz' % node_file_name,
142             'node-download.tgz')
143         os.rename(
144             os.path.join(common.OPPIA_TOOLS_DIR, node_file_name),
145             common.NODE_PATH)
146 
147     # Change ownership of node_modules.
148     # Note: on some machines, these commands seem to take quite a long time.
149     common.recursive_chown(common.NODE_MODULES_PATH, os.getuid(), -1)
150     common.recursive_chmod(common.NODE_MODULES_PATH, 0o744)
151 
152     # Download and install yarn.
153     python_utils.PRINT(
154         'Checking if yarn is installed in %s' % common.OPPIA_TOOLS_DIR)
155     if not os.path.exists(common.YARN_PATH):
156         python_utils.PRINT('Removing package-lock.json')
157         clean.delete_file('package-lock.json')
158         common.print_each_string_after_two_new_lines([
159             'Installing yarn',
160             'WARNING: Please note that Oppia uses Yarn to manage node packages',
161             'do *NOT* use npm. For more information on how to use yarn,',
162             'visit https://yarnpkg.com/en/docs/usage.'])
163 
164         # NB: Update .yarnrc if the yarn version below is changed.
165         yarn_version = 'v1.17.3'
166         yarn_file_name = 'yarn-%s.tar.gz' % yarn_version
167         download_and_install_package(
168             'https://github.com/yarnpkg/yarn/releases/download/%s/%s'
169             % (yarn_version, yarn_file_name), yarn_file_name)
170 
171     # Adjust path to support the default Chrome locations for Unix, Windows and
172     # Mac OS.
173     if os.environ.get('TRAVIS'):
174         chrome_bin = '/usr/bin/chromium-browser'
175     elif os.path.isfile('/usr/bin/google-chrome'):
176         # Unix.
177         chrome_bin = '/usr/bin/google-chrome'
178     elif os.path.isfile('/usr/bin/chromium-browser'):
179         # Unix.
180         chrome_bin = '/usr/bin/chromium-browser'
181     elif os.path.isfile(
182             '/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'):
183         # Windows.
184         chrome_bin = (
185             '/c/Program Files (x86)/Google/Chrome/Application/chrome.exe')
186     elif os.path.isfile(
187             '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'):
188         # WSL.
189         chrome_bin = (
190             '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe')
191     elif os.path.isfile(
192             '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'):
193         # Mac OS.
194         chrome_bin = (
195             '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome')
196     else:
197         python_utils.PRINT('Chrome is not found, stopping ...')
198         raise Exception
199 
200     os.environ['CHROME_BIN'] = chrome_bin
201     python_utils.PRINT('Environment setup completed.')
202 
203 
204 # The 'no coverage' pragma is used as this line is un-testable. This is because
205 # it will only be called when setup.py is used as a script.
206 if __name__ == '__main__': # pragma: no cover
207     main()
208
```
--- 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/scripts/setup.py b/scripts/setup.py
--- a/scripts/setup.py
+++ b/scripts/setup.py
@@ -19,6 +19,7 @@
 
 import argparse
 import os
+import subprocess
 import sys
 import tarfile
 
@@ -130,12 +131,12 @@
             if os_info[4] == 'x86_64':
                 node_file_name = 'node-v10.15.3-darwin-x64'
             else:
-                node_file_name = 'node-v10.15.3-darwin-x86'
+                node_file_name = 'node-v10.15.3'
         elif os_info[0] == 'Linux':
             if os_info[4] == 'x86_64':
                 node_file_name = 'node-v10.15.3-linux-x64'
             else:
-                node_file_name = 'node-v10.15.3-linux-x86'
+                node_file_name = 'node-v10.15.3'
 
         download_and_install_package(
             'https://nodejs.org/dist/v10.15.3/%s.tar.gz' % node_file_name,
@@ -144,6 +145,11 @@
             os.path.join(common.OPPIA_TOOLS_DIR, node_file_name),
             common.NODE_PATH)
 
+        if node_file_name == 'node-v10.15.3':
+            with common.CD(common.NODE_PATH):
+                subprocess.check_call(['./configure'])
+                subprocess.check_call(['make'])
+
     # Change ownership of node_modules.
     # Note: on some machines, these commands seem to take quite a long time.
     common.recursive_chown(common.NODE_MODULES_PATH, os.getuid(), -1)

{"golden_diff": "diff --git a/scripts/setup.py b/scripts/setup.py\n--- a/scripts/setup.py\n+++ b/scripts/setup.py\n@@ -19,6 +19,7 @@\n \n import argparse\n import os\n+import subprocess\n import sys\n import tarfile\n \n@@ -130,12 +131,12 @@\n             if os_info[4] == 'x86_64':\n                 node_file_name = 'node-v10.15.3-darwin-x64'\n             else:\n-                node_file_name = 'node-v10.15.3-darwin-x86'\n+                node_file_name = 'node-v10.15.3'\n         elif os_info[0] == 'Linux':\n             if os_info[4] == 'x86_64':\n                 node_file_name = 'node-v10.15.3-linux-x64'\n             else:\n-                node_file_name = 'node-v10.15.3-linux-x86'\n+                node_file_name = 'node-v10.15.3'\n \n         download_and_install_package(\n             'https://nodejs.org/dist/v10.15.3/%s.tar.gz' % node_file_name,\n@@ -144,6 +145,11 @@\n             os.path.join(common.OPPIA_TOOLS_DIR, node_file_name),\n             common.NODE_PATH)\n \n+        if node_file_name == 'node-v10.15.3':\n+            with common.CD(common.NODE_PATH):\n+                subprocess.check_call(['./configure'])\n+                subprocess.check_call(['make'])\n+\n     # Change ownership of node_modules.\n     # Note: on some machines, these commands seem to take quite a long time.\n     common.recursive_chown(common.NODE_MODULES_PATH, os.getuid(), -1)\n", "issue": "CircleCi tests are failing unexpectedly while downloading node modules\nScreenshot:\r\n![image](https://lh3.googleusercontent.com/-abvZp1fR4cs/Xbm0FK6XvVI/AAAAAAAADGo/sBcT85_wZIsAMWs3CxsFsFnHAMzEItAaACK8BGAsYHg/s0/2019-10-30.png)\r\n\r\nLink:\r\nhttps://circleci.com/gh/oppia/oppia/22306?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link\r\n\nCircleCi tests are failing unexpectedly while downloading node modules\nScreenshot:\r\n![image](https://lh3.googleusercontent.com/-abvZp1fR4cs/Xbm0FK6XvVI/AAAAAAAADGo/sBcT85_wZIsAMWs3CxsFsFnHAMzEItAaACK8BGAsYHg/s0/2019-10-30.png)\r\n\r\nLink:\r\nhttps://circleci.com/gh/oppia/oppia/22306?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link\r\n\n", "before_files": [{"content": "# Copyright 2019 The Oppia Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the 'License');\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an 'AS-IS' BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Python execution environent set up for all scripts.\"\"\"\n\nfrom __future__ import absolute_import  # pylint: disable=import-only-modules\nfrom __future__ import unicode_literals  # pylint: disable=import-only-modules\n\nimport argparse\nimport os\nimport sys\nimport tarfile\n\nimport python_utils\n\nfrom . import clean\nfrom . import common\n\n_PARSER = argparse.ArgumentParser(description=\"\"\"\nPython execution environent set up for all scripts.\n\"\"\")\n\n\ndef create_directory(directory_path):\n    \"\"\"Creates a new directory. Does not do anything if directory already\n    exists.\n\n    Args:\n        directory_path: str. Directory path to be created.\n    \"\"\"\n    if os.path.exists(directory_path):\n        return\n    os.makedirs(directory_path)\n\n\n# This function takes a command for python as its only input.\n# It checks this input for a specific version of python and returns false\n# if it does not match the expected prefix.\ndef test_python_version():\n    running_python_version = '{0[0]}.{0[1]}'.format(sys.version_info)\n    if running_python_version != '2.7':\n        python_utils.PRINT('Please use Python2.7. Exiting...')\n        # If OS is Windows, print helpful error message about adding Python to\n        # path.\n        os_info = os.uname()\n        if os_info[0] != 'Darwin' and os_info[0] != 'Linux':\n            common.print_each_string_after_two_new_lines([\n                'It looks like you are using Windows. If you have Python '\n                'installed,',\n                'make sure it is in your PATH and that PYTHONPATH is set.',\n                'If you have two versions of Python (ie, Python 2.7 and 3), '\n                'specify 2.7 before other versions of Python when setting the '\n                'PATH.',\n                'Here are some helpful articles:',\n                'http://docs.python-guide.org/en/latest/starting/install/win/',\n                'https://stackoverflow.com/questions/3701646/how-to-add-to-the-'\n                'pythonpath-in-windows-7'])\n        # Exit when no suitable Python environment can be found.\n        raise Exception\n\n\ndef download_and_install_package(url_to_retrieve, filename):\n    \"\"\"Downloads and installs package in Oppia tools directory.\n\n    Args:\n        url_to_retrieve: string. The url from which package is to be\n            downloaded.\n        filename: string. The name of the tar file.\n    \"\"\"\n    python_utils.url_retrieve(url_to_retrieve, filename=filename)\n    tar = tarfile.open(name=filename)\n    tar.extractall(path=common.OPPIA_TOOLS_DIR)\n    tar.close()\n    os.remove(filename)\n\n\ndef main(args=None):\n    \"\"\"Runs the script to setup Oppia.\"\"\"\n    unused_parsed_args = _PARSER.parse_args(args=args)\n    test_python_version()\n\n    # The second option allows this script to also be run from deployment\n    # folders.\n    if not os.getcwd().endswith('oppia') and not os.getcwd().endswith(\n            'deploy-'):\n        python_utils.PRINT('')\n        python_utils.PRINT(\n            'WARNING   This script should be run from the oppia/ root folder.')\n        python_utils.PRINT('')\n        raise Exception\n\n    # Set COMMON_DIR to the absolute path of the directory above OPPIA_DIR. This\n    # is necessary becaue COMMON_DIR (or subsequent variables which refer to it)\n    # may use it in a situation where relative paths won't work as expected(such\n    # as $PYTHONPATH).\n    create_directory(common.OPPIA_TOOLS_DIR)\n    create_directory(common.THIRD_PARTY_DIR)\n    create_directory(common.NODE_MODULES_PATH)\n\n    os_info = os.uname()\n    if os_info[0] != 'Darwin' and os_info[0] != 'Linux':\n        # Node is a requirement for all installation scripts. Here, we check if\n        # the OS supports node.js installation; if not, we exit with an error.\n        common.print_each_string_after_two_new_lines([\n            'WARNING: Unsupported OS for installation of node.js.',\n            'If you are running this script on Windows, see the instructions',\n            'here regarding installation of node.js:',\n            'https://github.com/oppia/oppia/wiki/Installing-Oppia-%28Windows'\n            '%29',\n            'STATUS: Installation completed except for node.js. Exiting.'])\n        raise Exception\n\n    # Download and install node.js.\n    python_utils.PRINT(\n        'Checking if node.js is installed in %s' % common.OPPIA_TOOLS_DIR)\n    if not os.path.exists(common.NODE_PATH):\n        python_utils.PRINT('Installing Node.js')\n        if os_info[0] == 'Darwin':\n            if os_info[4] == 'x86_64':\n                node_file_name = 'node-v10.15.3-darwin-x64'\n            else:\n                node_file_name = 'node-v10.15.3-darwin-x86'\n        elif os_info[0] == 'Linux':\n            if os_info[4] == 'x86_64':\n                node_file_name = 'node-v10.15.3-linux-x64'\n            else:\n                node_file_name = 'node-v10.15.3-linux-x86'\n\n        download_and_install_package(\n            'https://nodejs.org/dist/v10.15.3/%s.tar.gz' % node_file_name,\n            'node-download.tgz')\n        os.rename(\n            os.path.join(common.OPPIA_TOOLS_DIR, node_file_name),\n            common.NODE_PATH)\n\n    # Change ownership of node_modules.\n    # Note: on some machines, these commands seem to take quite a long time.\n    common.recursive_chown(common.NODE_MODULES_PATH, os.getuid(), -1)\n    common.recursive_chmod(common.NODE_MODULES_PATH, 0o744)\n\n    # Download and install yarn.\n    python_utils.PRINT(\n        'Checking if yarn is installed in %s' % common.OPPIA_TOOLS_DIR)\n    if not os.path.exists(common.YARN_PATH):\n        python_utils.PRINT('Removing package-lock.json')\n        clean.delete_file('package-lock.json')\n        common.print_each_string_after_two_new_lines([\n            'Installing yarn',\n            'WARNING: Please note that Oppia uses Yarn to manage node packages',\n            'do *NOT* use npm. For more information on how to use yarn,',\n            'visit https://yarnpkg.com/en/docs/usage.'])\n\n        # NB: Update .yarnrc if the yarn version below is changed.\n        yarn_version = 'v1.17.3'\n        yarn_file_name = 'yarn-%s.tar.gz' % yarn_version\n        download_and_install_package(\n            'https://github.com/yarnpkg/yarn/releases/download/%s/%s'\n            % (yarn_version, yarn_file_name), yarn_file_name)\n\n    # Adjust path to support the default Chrome locations for Unix, Windows and\n    # Mac OS.\n    if os.environ.get('TRAVIS'):\n        chrome_bin = '/usr/bin/chromium-browser'\n    elif os.path.isfile('/usr/bin/google-chrome'):\n        # Unix.\n        chrome_bin = '/usr/bin/google-chrome'\n    elif os.path.isfile('/usr/bin/chromium-browser'):\n        # Unix.\n        chrome_bin = '/usr/bin/chromium-browser'\n    elif os.path.isfile(\n            '/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'):\n        # Windows.\n        chrome_bin = (\n            '/c/Program Files (x86)/Google/Chrome/Application/chrome.exe')\n    elif os.path.isfile(\n            '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'):\n        # WSL.\n        chrome_bin = (\n            '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe')\n    elif os.path.isfile(\n            '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'):\n        # Mac OS.\n        chrome_bin = (\n            '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome')\n    else:\n        python_utils.PRINT('Chrome is not found, stopping ...')\n        raise Exception\n\n    os.environ['CHROME_BIN'] = chrome_bin\n    python_utils.PRINT('Environment setup completed.')\n\n\n# The 'no coverage' pragma is used as this line is un-testable. This is because\n# it will only be called when setup.py is used as a script.\nif __name__ == '__main__': # pragma: no cover\n    main()\n", "path": "scripts/setup.py"}], "after_files": [{"content": "# Copyright 2019 The Oppia Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the 'License');\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an 'AS-IS' BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Python execution environent set up for all scripts.\"\"\"\n\nfrom __future__ import absolute_import  # pylint: disable=import-only-modules\nfrom __future__ import unicode_literals  # pylint: disable=import-only-modules\n\nimport argparse\nimport os\nimport subprocess\nimport sys\nimport tarfile\n\nimport python_utils\n\nfrom . import clean\nfrom . import common\n\n_PARSER = argparse.ArgumentParser(description=\"\"\"\nPython execution environent set up for all scripts.\n\"\"\")\n\n\ndef create_directory(directory_path):\n    \"\"\"Creates a new directory. Does not do anything if directory already\n    exists.\n\n    Args:\n        directory_path: str. Directory path to be created.\n    \"\"\"\n    if os.path.exists(directory_path):\n        return\n    os.makedirs(directory_path)\n\n\n# This function takes a command for python as its only input.\n# It checks this input for a specific version of python and returns false\n# if it does not match the expected prefix.\ndef test_python_version():\n    running_python_version = '{0[0]}.{0[1]}'.format(sys.version_info)\n    if running_python_version != '2.7':\n        python_utils.PRINT('Please use Python2.7. Exiting...')\n        # If OS is Windows, print helpful error message about adding Python to\n        # path.\n        os_info = os.uname()\n        if os_info[0] != 'Darwin' and os_info[0] != 'Linux':\n            common.print_each_string_after_two_new_lines([\n                'It looks like you are using Windows. If you have Python '\n                'installed,',\n                'make sure it is in your PATH and that PYTHONPATH is set.',\n                'If you have two versions of Python (ie, Python 2.7 and 3), '\n                'specify 2.7 before other versions of Python when setting the '\n                'PATH.',\n                'Here are some helpful articles:',\n                'http://docs.python-guide.org/en/latest/starting/install/win/',\n                'https://stackoverflow.com/questions/3701646/how-to-add-to-the-'\n                'pythonpath-in-windows-7'])\n        # Exit when no suitable Python environment can be found.\n        raise Exception\n\n\ndef download_and_install_package(url_to_retrieve, filename):\n    \"\"\"Downloads and installs package in Oppia tools directory.\n\n    Args:\n        url_to_retrieve: string. The url from which package is to be\n            downloaded.\n        filename: string. The name of the tar file.\n    \"\"\"\n    python_utils.url_retrieve(url_to_retrieve, filename=filename)\n    tar = tarfile.open(name=filename)\n    tar.extractall(path=common.OPPIA_TOOLS_DIR)\n    tar.close()\n    os.remove(filename)\n\n\ndef main(args=None):\n    \"\"\"Runs the script to setup Oppia.\"\"\"\n    unused_parsed_args = _PARSER.parse_args(args=args)\n    test_python_version()\n\n    # The second option allows this script to also be run from deployment\n    # folders.\n    if not os.getcwd().endswith('oppia') and not os.getcwd().endswith(\n            'deploy-'):\n        python_utils.PRINT('')\n        python_utils.PRINT(\n            'WARNING   This script should be run from the oppia/ root folder.')\n        python_utils.PRINT('')\n        raise Exception\n\n    # Set COMMON_DIR to the absolute path of the directory above OPPIA_DIR. This\n    # is necessary becaue COMMON_DIR (or subsequent variables which refer to it)\n    # may use it in a situation where relative paths won't work as expected(such\n    # as $PYTHONPATH).\n    create_directory(common.OPPIA_TOOLS_DIR)\n    create_directory(common.THIRD_PARTY_DIR)\n    create_directory(common.NODE_MODULES_PATH)\n\n    os_info = os.uname()\n    if os_info[0] != 'Darwin' and os_info[0] != 'Linux':\n        # Node is a requirement for all installation scripts. Here, we check if\n        # the OS supports node.js installation; if not, we exit with an error.\n        common.print_each_string_after_two_new_lines([\n            'WARNING: Unsupported OS for installation of node.js.',\n            'If you are running this script on Windows, see the instructions',\n            'here regarding installation of node.js:',\n            'https://github.com/oppia/oppia/wiki/Installing-Oppia-%28Windows'\n            '%29',\n            'STATUS: Installation completed except for node.js. Exiting.'])\n        raise Exception\n\n    # Download and install node.js.\n    python_utils.PRINT(\n        'Checking if node.js is installed in %s' % common.OPPIA_TOOLS_DIR)\n    if not os.path.exists(common.NODE_PATH):\n        python_utils.PRINT('Installing Node.js')\n        if os_info[0] == 'Darwin':\n            if os_info[4] == 'x86_64':\n                node_file_name = 'node-v10.15.3-darwin-x64'\n            else:\n                node_file_name = 'node-v10.15.3'\n        elif os_info[0] == 'Linux':\n            if os_info[4] == 'x86_64':\n                node_file_name = 'node-v10.15.3-linux-x64'\n            else:\n                node_file_name = 'node-v10.15.3'\n\n        download_and_install_package(\n            'https://nodejs.org/dist/v10.15.3/%s.tar.gz' % node_file_name,\n            'node-download.tgz')\n        os.rename(\n            os.path.join(common.OPPIA_TOOLS_DIR, node_file_name),\n            common.NODE_PATH)\n\n        if node_file_name == 'node-v10.15.3':\n            with common.CD(common.NODE_PATH):\n                subprocess.check_call(['./configure'])\n                subprocess.check_call(['make'])\n\n    # Change ownership of node_modules.\n    # Note: on some machines, these commands seem to take quite a long time.\n    common.recursive_chown(common.NODE_MODULES_PATH, os.getuid(), -1)\n    common.recursive_chmod(common.NODE_MODULES_PATH, 0o744)\n\n    # Download and install yarn.\n    python_utils.PRINT(\n        'Checking if yarn is installed in %s' % common.OPPIA_TOOLS_DIR)\n    if not os.path.exists(common.YARN_PATH):\n        python_utils.PRINT('Removing package-lock.json')\n        clean.delete_file('package-lock.json')\n        common.print_each_string_after_two_new_lines([\n            'Installing yarn',\n            'WARNING: Please note that Oppia uses Yarn to manage node packages',\n            'do *NOT* use npm. For more information on how to use yarn,',\n            'visit https://yarnpkg.com/en/docs/usage.'])\n\n        # NB: Update .yarnrc if the yarn version below is changed.\n        yarn_version = 'v1.17.3'\n        yarn_file_name = 'yarn-%s.tar.gz' % yarn_version\n        download_and_install_package(\n            'https://github.com/yarnpkg/yarn/releases/download/%s/%s'\n            % (yarn_version, yarn_file_name), yarn_file_name)\n\n    # Adjust path to support the default Chrome locations for Unix, Windows and\n    # Mac OS.\n    if os.environ.get('TRAVIS'):\n        chrome_bin = '/usr/bin/chromium-browser'\n    elif os.path.isfile('/usr/bin/google-chrome'):\n        # Unix.\n        chrome_bin = '/usr/bin/google-chrome'\n    elif os.path.isfile('/usr/bin/chromium-browser'):\n        # Unix.\n        chrome_bin = '/usr/bin/chromium-browser'\n    elif os.path.isfile(\n            '/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'):\n        # Windows.\n        chrome_bin = (\n            '/c/Program Files (x86)/Google/Chrome/Application/chrome.exe')\n    elif os.path.isfile(\n            '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'):\n        # WSL.\n        chrome_bin = (\n            '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe')\n    elif os.path.isfile(\n            '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'):\n        # Mac OS.\n        chrome_bin = (\n            '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome')\n    else:\n        python_utils.PRINT('Chrome is not found, stopping ...')\n        raise Exception\n\n    os.environ['CHROME_BIN'] = chrome_bin\n    python_utils.PRINT('Environment setup completed.')\n\n\n# The 'no coverage' pragma is used as this line is un-testable. This is because\n# it will only be called when setup.py is used as a script.\nif __name__ == '__main__': # pragma: no cover\n    main()\n", "path": "scripts/setup.py"}]}