gcloud 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. data.tar.gz.sig +2 -3
  2. data/CHANGELOG +4 -0
  3. data/LICENSE +674 -0
  4. data/Manifest +111 -0
  5. data/README.md +4 -3
  6. data/bin/gcutil +53 -0
  7. data/gcloud.gemspec +4 -3
  8. data/packages/gcutil-1.7.1/CHANGELOG +197 -0
  9. data/packages/gcutil-1.7.1/LICENSE +202 -0
  10. data/packages/gcutil-1.7.1/VERSION +1 -0
  11. data/packages/gcutil-1.7.1/gcutil +53 -0
  12. data/packages/gcutil-1.7.1/lib/google_api_python_client/LICENSE +23 -0
  13. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/__init__.py +1 -0
  14. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/discovery.py +743 -0
  15. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/errors.py +123 -0
  16. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/ext/__init__.py +0 -0
  17. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/http.py +1443 -0
  18. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/mimeparse.py +172 -0
  19. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/model.py +385 -0
  20. data/packages/gcutil-1.7.1/lib/google_api_python_client/apiclient/schema.py +303 -0
  21. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/__init__.py +1 -0
  22. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/anyjson.py +32 -0
  23. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/appengine.py +528 -0
  24. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/client.py +1139 -0
  25. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/clientsecrets.py +105 -0
  26. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/crypt.py +244 -0
  27. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/django_orm.py +124 -0
  28. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/file.py +107 -0
  29. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/locked_file.py +343 -0
  30. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/multistore_file.py +379 -0
  31. data/packages/gcutil-1.7.1/lib/google_api_python_client/oauth2client/tools.py +174 -0
  32. data/packages/gcutil-1.7.1/lib/google_api_python_client/uritemplate/__init__.py +147 -0
  33. data/packages/gcutil-1.7.1/lib/google_apputils/LICENSE +202 -0
  34. data/packages/gcutil-1.7.1/lib/google_apputils/google/__init__.py +3 -0
  35. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/__init__.py +3 -0
  36. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/app.py +356 -0
  37. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/appcommands.py +783 -0
  38. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/basetest.py +1260 -0
  39. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/datelib.py +421 -0
  40. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/debug.py +60 -0
  41. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/file_util.py +181 -0
  42. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/resources.py +67 -0
  43. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/run_script_module.py +217 -0
  44. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/setup_command.py +159 -0
  45. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/shellutil.py +49 -0
  46. data/packages/gcutil-1.7.1/lib/google_apputils/google/apputils/stopwatch.py +204 -0
  47. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/__init__.py +0 -0
  48. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auth_helper.py +140 -0
  49. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auth_helper_test.py +149 -0
  50. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auto_auth.py +130 -0
  51. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/auto_auth_test.py +75 -0
  52. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/basic_cmds.py +128 -0
  53. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/basic_cmds_test.py +111 -0
  54. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/command_base.py +1808 -0
  55. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/command_base_test.py +1651 -0
  56. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/compute/v1beta13.json +2851 -0
  57. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/compute/v1beta14.json +3361 -0
  58. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/disk_cmds.py +342 -0
  59. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/disk_cmds_test.py +474 -0
  60. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/firewall_cmds.py +344 -0
  61. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/firewall_cmds_test.py +231 -0
  62. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/flags_cache.py +274 -0
  63. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/gcutil +89 -0
  64. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/gcutil_logging.py +69 -0
  65. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/image_cmds.py +262 -0
  66. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/image_cmds_test.py +172 -0
  67. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/instance_cmds.py +1506 -0
  68. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/instance_cmds_test.py +1904 -0
  69. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/kernel_cmds.py +91 -0
  70. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/kernel_cmds_test.py +56 -0
  71. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/machine_type_cmds.py +106 -0
  72. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/machine_type_cmds_test.py +59 -0
  73. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata.py +96 -0
  74. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata_lib.py +357 -0
  75. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/metadata_test.py +84 -0
  76. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/mock_api.py +420 -0
  77. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/mock_metadata.py +58 -0
  78. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/move_cmds.py +824 -0
  79. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/move_cmds_test.py +307 -0
  80. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/network_cmds.py +178 -0
  81. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/network_cmds_test.py +133 -0
  82. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/operation_cmds.py +181 -0
  83. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/operation_cmds_test.py +196 -0
  84. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/path_initializer.py +38 -0
  85. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/project_cmds.py +173 -0
  86. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/project_cmds_test.py +111 -0
  87. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/scopes.py +61 -0
  88. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/scopes_test.py +50 -0
  89. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/snapshot_cmds.py +276 -0
  90. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/snapshot_cmds_test.py +260 -0
  91. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/ssh_keys.py +266 -0
  92. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/ssh_keys_test.py +128 -0
  93. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/table_formatter.py +563 -0
  94. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/thread_pool.py +188 -0
  95. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/thread_pool_test.py +88 -0
  96. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/utils.py +208 -0
  97. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/utils_test.py +193 -0
  98. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version.py +17 -0
  99. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version_checker.py +246 -0
  100. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/version_checker_test.py +271 -0
  101. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/zone_cmds.py +151 -0
  102. data/packages/gcutil-1.7.1/lib/google_compute_engine/gcutil/zone_cmds_test.py +60 -0
  103. data/packages/gcutil-1.7.1/lib/httplib2/LICENSE +21 -0
  104. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/__init__.py +1630 -0
  105. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/cacerts.txt +714 -0
  106. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/iri2uri.py +110 -0
  107. data/packages/gcutil-1.7.1/lib/httplib2/httplib2/socks.py +438 -0
  108. data/packages/gcutil-1.7.1/lib/iso8601/LICENSE +20 -0
  109. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/__init__.py +1 -0
  110. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/iso8601.py +102 -0
  111. data/packages/gcutil-1.7.1/lib/iso8601/iso8601/test_iso8601.py +111 -0
  112. data/packages/gcutil-1.7.1/lib/python_gflags/AUTHORS +2 -0
  113. data/packages/gcutil-1.7.1/lib/python_gflags/LICENSE +28 -0
  114. data/packages/gcutil-1.7.1/lib/python_gflags/gflags.py +2862 -0
  115. data/packages/gcutil-1.7.1/lib/python_gflags/gflags2man.py +544 -0
  116. data/packages/gcutil-1.7.1/lib/python_gflags/gflags_validators.py +187 -0
  117. metadata +118 -5
  118. metadata.gz.sig +0 -0
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env python
2
+ # Copyright 2007 Google Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS-IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ """Simple file system utilities."""
17
+
18
+ __author__ = ('elaforge@google.com (Evan LaForge)',
19
+ 'matthewb@google.com (Matthew Blecker)')
20
+
21
+ import errno
22
+ import os
23
+ import pwd
24
+ import shutil
25
+ import stat
26
+ import tempfile
27
+
28
+
29
+ class PasswdError(Exception):
30
+ """Exception class for errors loading a password from a file."""
31
+
32
+
33
+ def ListDirPath(dir_name):
34
+ """Like os.listdir with prepended dir_name, which is often more convenient."""
35
+ return [os.path.join(dir_name, fn) for fn in os.listdir(dir_name)]
36
+
37
+
38
+ def Read(filename):
39
+ """Read entire contents of file with name 'filename'."""
40
+ fp = open(filename)
41
+ try:
42
+ return fp.read()
43
+ finally:
44
+ fp.close()
45
+
46
+
47
+ def Write(filename, contents, overwrite_existing=True, mode=0666):
48
+ """Create a file 'filename' with 'contents', with the mode given in 'mode'.
49
+
50
+ The 'mode' is modified by the umask, as in open(2). If
51
+ 'overwrite_existing' is False, the file will be opened in O_EXCL mode.
52
+
53
+ Args:
54
+ filename: str; the name of the file
55
+ contents: str; the data to write to the file
56
+ overwrite_existing: bool; whether or not to allow the write if the file
57
+ already exists
58
+ mode: int; permissions with which to create the file (default is 0666 octal)
59
+ """
60
+ flags = os.O_WRONLY | os.O_TRUNC | os.O_CREAT
61
+ if not overwrite_existing:
62
+ flags |= os.O_EXCL
63
+ fd = os.open(filename, flags, mode)
64
+ try:
65
+ os.write(fd, contents)
66
+ finally:
67
+ os.close(fd)
68
+
69
+
70
+ def AtomicWrite(filename, contents, mode=0666):
71
+ """Create a file 'filename' with 'contents' atomically.
72
+
73
+ As in Write, 'mode' is modified by the umask. This creates and moves
74
+ a temporary file, and errors doing the above will be propagated normally,
75
+ though it will try to clean up the temporary file in that case.
76
+
77
+ This is very similar to the prodlib function with the same name.
78
+
79
+ Args:
80
+ filename: str; the name of the file
81
+ contents: str; the data to write to the file
82
+ mode: int; permissions with which to create the file (default is 0666 octal)
83
+ """
84
+ (fd, tmp_filename) = tempfile.mkstemp(dir=os.path.dirname(filename))
85
+ try:
86
+ os.write(fd, contents)
87
+ finally:
88
+ os.close(fd)
89
+ try:
90
+ os.chmod(tmp_filename, mode)
91
+ os.rename(tmp_filename, filename)
92
+ except OSError, exc:
93
+ try:
94
+ os.remove(tmp_filename)
95
+ except OSError, e:
96
+ exc = OSError('%s. Additional errors cleaning up: %s' % (exc, e))
97
+ raise exc
98
+
99
+
100
+ def MkDirs(directory, force_mode=None):
101
+ """Makes a directory including its parent directories.
102
+
103
+ This function is equivalent to os.makedirs() but it avoids a race
104
+ condition that os.makedirs() has. The race is between os.mkdir() and
105
+ os.path.exists() which fail with errors when run in parallel.
106
+
107
+ Args:
108
+ directory: str; the directory to make
109
+ force_mode: optional octal, chmod dir to get rid of umask interaction
110
+ Raises:
111
+ Whatever os.mkdir() raises when it fails for any reason EXCLUDING
112
+ "dir already exists". If a directory already exists, it does not
113
+ raise anything. This behaviour is different than os.makedirs()
114
+ """
115
+ name = os.path.normpath(directory)
116
+ dirs = name.split(os.path.sep)
117
+ for i in range(0, len(dirs)):
118
+ path = os.path.sep.join(dirs[:i+1])
119
+ try:
120
+ if path:
121
+ os.mkdir(path)
122
+ # only chmod if we created
123
+ if force_mode is not None:
124
+ os.chmod(path, force_mode)
125
+ except OSError, exc:
126
+ if not (exc.errno == errno.EEXIST and os.path.isdir(path)):
127
+ raise
128
+
129
+
130
+ def RmDirs(dir_name):
131
+ """Removes dir_name and every non-empty directory in dir_name.
132
+
133
+ Unlike os.removedirs and shutil.rmtree, this function doesn't raise an error
134
+ if the directory does not exist.
135
+
136
+ Args:
137
+ dir_name: Directory to be removed.
138
+ """
139
+ try:
140
+ shutil.rmtree(dir_name)
141
+ except OSError, err:
142
+ if err.errno != errno.ENOENT:
143
+ raise
144
+
145
+ try:
146
+ parent_directory = os.path.dirname(dir_name)
147
+ while parent_directory:
148
+ try:
149
+ os.rmdir(parent_directory)
150
+ except OSError, err:
151
+ if err.errno != errno.ENOENT:
152
+ raise
153
+
154
+ parent_directory = os.path.dirname(parent_directory)
155
+ except OSError, err:
156
+ if err.errno not in (errno.EACCES, errno.ENOTEMPTY):
157
+ raise
158
+
159
+
160
+ def HomeDir(user=None):
161
+ """Find the home directory of a user.
162
+
163
+ Args:
164
+ user: int, str, or None - the uid or login of the user to query for,
165
+ or None (the default) to query for the current process' effective user
166
+
167
+ Returns:
168
+ str - the user's home directory
169
+
170
+ Raises:
171
+ TypeError: if user is not int, str, or None.
172
+ """
173
+ if user is None:
174
+ pw_struct = pwd.getpwuid(os.geteuid())
175
+ elif isinstance(user, int):
176
+ pw_struct = pwd.getpwuid(user)
177
+ elif isinstance(user, str):
178
+ pw_struct = pwd.getpwnam(user)
179
+ else:
180
+ raise TypeError('user must be None or an instance of int or str')
181
+ return pw_struct.pw_dir
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env python
2
+ # Copyright 2010 Google Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS-IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ """Wrapper around setuptools' pkg_resources with more Google-like names.
17
+
18
+ This module is not very useful on its own, but many Google open-source projects
19
+ are used to a different naming scheme, and this module makes the transition
20
+ easier.
21
+ """
22
+
23
+ __author__ = 'dborowitz@google.com (Dave Borowitz)'
24
+
25
+ import atexit
26
+
27
+ import pkg_resources
28
+
29
+
30
+ def _Call(func, name):
31
+ """Call a pkg_resources function.
32
+
33
+ Args:
34
+ func: A function from pkg_resources that takes the arguments
35
+ (package_or_requirement, resource_name); for more info,
36
+ see http://peak.telecommunity.com/DevCenter/PkgResources
37
+ name: A name of the form 'module.name:path/to/resource'; this should
38
+ generally be built from __name__ in the calling module.
39
+
40
+ Returns:
41
+ The result of calling the function on the split resource name.
42
+ """
43
+ pkg_name, resource_name = name.split(':', 1)
44
+ return func(pkg_name, resource_name)
45
+
46
+
47
+ def GetResource(name):
48
+ """Get a resource as a string; see _Call."""
49
+ return _Call(pkg_resources.resource_string, name)
50
+
51
+
52
+ def GetResourceAsFile(name):
53
+ """Get a resource as a file-like object; see _Call."""
54
+ return _Call(pkg_resources.resource_stream, name)
55
+
56
+
57
+ _extracted_files = False
58
+
59
+
60
+ def GetResourceFilename(name):
61
+ """Get a filename for a resource; see _Call."""
62
+ global _extracted_files # pylint: disable-msg=W0603
63
+ if not _extracted_files:
64
+ atexit.register(pkg_resources.cleanup_resources)
65
+ _extracted_files = True
66
+
67
+ return _Call(pkg_resources.resource_filename, name)
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env python
2
+ # Copyright 2010 Google Inc. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS-IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ """Script for running Google-style applications.
17
+
18
+ Unlike normal scripts run through setuptools console_script entry points,
19
+ Google-style applications must be run as top-level scripts.
20
+
21
+ Given an already-imported module, users can use the RunScriptModule function to
22
+ set up the appropriate executable environment to spawn a new Python process to
23
+ run the module as a script.
24
+
25
+ To use this technique in your project, first create a module called e.g.
26
+ stubs.py with contents like:
27
+
28
+ from google.apputils import run_script_module
29
+
30
+ def RunMyScript():
31
+ import my.script
32
+ run_script_module.RunScriptModule(my.script)
33
+
34
+ def RunMyOtherScript():
35
+ import my.other_script
36
+ run_script_module.RunScriptModule(my.other_script)
37
+
38
+ Then, set up entry points in your setup.py that point to the functions in your
39
+ stubs module:
40
+
41
+ setup(
42
+ ...
43
+ entry_points = {
44
+ 'console_scripts': [
45
+ 'my_script = my.stubs:RunMyScript',
46
+ 'my_other_script = my.stubs.RunMyOtherScript',
47
+ ],
48
+ },
49
+ )
50
+
51
+ When your project is installed, setuptools will generate minimal wrapper scripts
52
+ to call your stub functions, which in turn execv your script modules. That's it!
53
+ """
54
+
55
+ __author__ = 'dborowitz@google.com (Dave Borowitz)'
56
+
57
+ import os
58
+ import re
59
+ import sys
60
+
61
+
62
+ def FindEnv(progname):
63
+ """Find the program in the system path.
64
+
65
+ Args:
66
+ progname: The name of the program.
67
+
68
+ Returns:
69
+ The full pathname of the program.
70
+
71
+ Raises:
72
+ AssertionError: if the program was not found.
73
+ """
74
+ for path in os.environ['PATH'].split(':'):
75
+ fullname = os.path.join(path, progname)
76
+ if os.access(fullname, os.X_OK):
77
+ return fullname
78
+ raise AssertionError(
79
+ "Could not find an executable named '%s' in the system path" % progname)
80
+
81
+
82
+ def GetPdbArgs(python):
83
+ """Try to get the path to pdb.py and return it in a list.
84
+
85
+ Args:
86
+ python: The full path to a Python executable.
87
+
88
+ Returns:
89
+ A list of strings. If a relevant pdb.py was found, this will be
90
+ ['/path/to/pdb.py']; if not, return ['-m', 'pdb'] and hope for the best.
91
+ (This latter technique will fail for Python 2.2.)
92
+ """
93
+ # Usually, python is /usr/bin/pythonxx and pdb is /usr/lib/pythonxx/pdb.py
94
+ components = python.split('/')
95
+ if len(components) >= 2:
96
+ pdb_path = '/'.join(components[0:-2] + ['lib'] +
97
+ components[-1:] + ['pdb.py'])
98
+ if os.access(pdb_path, os.R_OK):
99
+ return [pdb_path]
100
+
101
+ # No pdb module found in the python path, default to -m pdb
102
+ return ['-m', 'pdb']
103
+
104
+
105
+ def StripDelimiters(s, beg, end):
106
+ if s[0] == beg:
107
+ assert s[-1] == end
108
+ return (s[1:-1], True)
109
+ else:
110
+ return (s, False)
111
+
112
+
113
+ def StripQuotes(s):
114
+ (s, stripped) = StripDelimiters(s, '"', '"')
115
+ if not stripped:
116
+ (s, stripped) = StripDelimiters(s, "'", "'")
117
+ return s
118
+
119
+
120
+ def PrintOurUsage():
121
+ """Print usage for the stub script."""
122
+ print 'Stub script %s (auto-generated). Options:' % sys.argv[0]
123
+ print ('--helpstub '
124
+ 'Show help for stub script.')
125
+ print ('--debug_binary '
126
+ 'Run python under debugger specified by --debugger.')
127
+ print ('--debugger=<debugger> '
128
+ "Debugger for --debug_binary. Default: 'gdb --args'.")
129
+ print ('--debug_script '
130
+ 'Run wrapped script with python debugger module (pdb).')
131
+ print ('--show_command_and_exit '
132
+ 'Print command which would be executed and exit.')
133
+ print ('These options must appear first in the command line, all others will '
134
+ 'be passed to the wrapped script.')
135
+
136
+
137
+ def RunScriptModule(module):
138
+ """Run a module as a script.
139
+
140
+ Locates the module's file and runs it in the current interpreter, or
141
+ optionally a debugger.
142
+
143
+ Args:
144
+ module: The module object to run.
145
+ """
146
+ args = sys.argv[1:]
147
+
148
+ debug_binary = False
149
+ debugger = 'gdb --args'
150
+ debug_script = False
151
+ show_command_and_exit = False
152
+
153
+ while args:
154
+ if args[0] == '--helpstub':
155
+ PrintOurUsage()
156
+ sys.exit(0)
157
+ if args[0] == '--debug_binary':
158
+ debug_binary = True
159
+ args = args[1:]
160
+ continue
161
+ if args[0] == '--debug_script':
162
+ debug_script = True
163
+ args = args[1:]
164
+ continue
165
+ if args[0] == '--show_command_and_exit':
166
+ show_command_and_exit = True
167
+ args = args[1:]
168
+ continue
169
+ matchobj = re.match('--debugger=(.+)', args[0])
170
+ if matchobj is not None:
171
+ debugger = StripQuotes(matchobj.group(1))
172
+ args = args[1:]
173
+ continue
174
+ break
175
+
176
+ # Now look for my main python source file
177
+ # TODO(dborowitz): This will fail if the module was zipimported, which means
178
+ # no egg depending on this script runner can be zip_safe.
179
+ main_filename = module.__file__
180
+ assert os.path.exists(main_filename), ('Cannot exec() %r: file not found.' %
181
+ main_filename)
182
+ assert os.access(main_filename, os.R_OK), ('Cannot exec() %r: file not'
183
+ ' readable.' % main_filename)
184
+
185
+ args = [main_filename] + args
186
+
187
+ if debug_binary:
188
+ debugger_args = debugger.split()
189
+ program = debugger_args[0]
190
+ # If pathname is not absolute, determine full path using PATH
191
+ if not os.path.isabs(program):
192
+ program = FindEnv(program)
193
+ python_path = sys.executable
194
+ command_vec = [python_path]
195
+ if debug_script:
196
+ command_vec.extend(GetPdbArgs(python_path))
197
+ args = [program] + debugger_args[1:] + command_vec + args
198
+
199
+ elif debug_script:
200
+ args = [sys.executable] + GetPdbArgs(program) + args
201
+
202
+ else:
203
+ program = sys.executable
204
+ args = [sys.executable] + args
205
+
206
+ if show_command_and_exit:
207
+ print 'program: "%s"' % program
208
+ print 'args:', args
209
+ sys.exit(0)
210
+
211
+ try:
212
+ sys.stdout.flush()
213
+ os.execv(program, args)
214
+ except EnvironmentError, e:
215
+ if not getattr(e, 'filename', None):
216
+ e.filename = program # Add info to error message
217
+ raise