Index: third_party/gsutil/gslib/commands/version.py |
diff --git a/third_party/gsutil/gslib/commands/version.py b/third_party/gsutil/gslib/commands/version.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a396372a73ea3ce2d58d2bd1c8b41b2d7e1fa94f |
--- /dev/null |
+++ b/third_party/gsutil/gslib/commands/version.py |
@@ -0,0 +1,150 @@ |
+# Copyright 2011 Google Inc. All Rights Reserved. |
+# |
+# Licensed under the Apache License, Version 2.0 (the "License"); |
+# you may not use this file except in compliance with the License. |
+# You may obtain a copy of the License at |
+# |
+# http://www.apache.org/licenses/LICENSE-2.0 |
+# |
+# Unless required by applicable law or agreed to in writing, software |
+# distributed under the License is distributed on an "AS IS" BASIS, |
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+# See the License for the specific language governing permissions and |
+# limitations under the License. |
+ |
+import boto |
+import os |
+import re |
+import sys |
+ |
+from boto.pyami.config import BotoConfigLocations |
+from gslib.command import Command |
+from gslib.command import COMMAND_NAME |
+from gslib.command import COMMAND_NAME_ALIASES |
+from gslib.command import CONFIG_REQUIRED |
+from gslib.command import FILE_URIS_OK |
+from gslib.command import MAX_ARGS |
+from gslib.command import MIN_ARGS |
+from gslib.command import PROVIDER_URIS_OK |
+from gslib.command import SUPPORTED_SUB_ARGS |
+from gslib.command import URIS_START_ARG |
+from gslib.help_provider import HELP_NAME |
+from gslib.help_provider import HELP_NAME_ALIASES |
+from gslib.help_provider import HELP_ONE_LINE_SUMMARY |
+from gslib.help_provider import HELP_TEXT |
+from gslib.help_provider import HelpType |
+from gslib.help_provider import HELP_TYPE |
+from hashlib import md5 |
+ |
+_detailed_help_text = (""" |
+<B>SYNOPSIS</B> |
+ gsutil version |
+ |
+ |
+<B>DESCRIPTION</B> |
+ Prints information about the version of gsutil, boto, and Python being |
+ run on your system. |
+""") |
+ |
+ |
+class VersionCommand(Command): |
+ """Implementation of gsutil version command.""" |
+ |
+ # Command specification (processed by parent class). |
+ command_spec = { |
+ # Name of command. |
+ COMMAND_NAME : 'version', |
+ # List of command name aliases. |
+ COMMAND_NAME_ALIASES : ['ver'], |
+ # Min number of args required by this command. |
+ MIN_ARGS : 0, |
+ # Max number of args required by this command, or NO_MAX. |
+ MAX_ARGS : 0, |
+ # Getopt-style string specifying acceptable sub args. |
+ SUPPORTED_SUB_ARGS : '', |
+ # True if file URIs acceptable for this command. |
+ FILE_URIS_OK : False, |
+ # True if provider-only URIs acceptable for this command. |
+ PROVIDER_URIS_OK : False, |
+ # Index in args of first URI arg. |
+ URIS_START_ARG : 0, |
+ # True if must configure gsutil before running command. |
+ CONFIG_REQUIRED : False, |
+ } |
+ help_spec = { |
+ # Name of command or auxiliary help info for which this help applies. |
+ HELP_NAME : 'version', |
+ # List of help name aliases. |
+ HELP_NAME_ALIASES : ['ver'], |
+ # Type of help: |
+ HELP_TYPE : HelpType.COMMAND_HELP, |
+ # One line summary of this help. |
+ HELP_ONE_LINE_SUMMARY : 'Print version info about gsutil', |
+ # The full help text. |
+ HELP_TEXT : _detailed_help_text, |
+ } |
+ |
+ # Command entry point. |
+ def RunCommand(self): |
+ for path in BotoConfigLocations: |
+ f = None |
+ try: |
+ f = open(path, 'r') |
+ break |
+ except IOError: |
+ pass |
+ finally: |
+ if f: |
+ f.close() |
+ else: |
+ path = "no config found" |
+ |
+ try: |
+ f = open(os.path.join(self.gsutil_bin_dir, 'CHECKSUM')) |
+ shipped_checksum = f.read().strip() |
+ f.close() |
+ except IOError: |
+ shipped_checksum = 'MISSING' |
+ try: |
+ cur_checksum = self._ComputeCodeChecksum() |
+ except IOError: |
+ cur_checksum = 'MISSING FILES' |
+ if shipped_checksum == cur_checksum: |
+ checksum_ok_str = 'OK' |
+ else: |
+ checksum_ok_str = '!= %s' % shipped_checksum |
+ sys.stderr.write( |
+ 'gsutil version %s\nchecksum %s (%s)\n' |
+ 'boto version %s\npython version %s\n' |
+ 'config path: %s\ngsutil path: %s\n' % ( |
+ self.gsutil_ver, cur_checksum, checksum_ok_str, |
+ boto.__version__, sys.version, path, os.path.realpath(sys.argv[0]))) |
+ |
+ return 0 |
+ |
+ def _ComputeCodeChecksum(self): |
+ """ |
+ Computes a checksum of gsutil code so we can see if users locally modified |
+ gsutil when requesting support. (It's fine for users to make local mods, |
+ but when users ask for support we ask them to run a stock version of |
+ gsutil so we can reduce possible variables.) |
+ """ |
+ m = md5() |
+ # Checksum gsutil and all .py files under gsutil bin (including bundled |
+ # libs). Although we will eventually make gsutil allow use of a centrally |
+ # installed boto (once boto shifts to more frequent releases), in that case |
+ # the local copies still should not have any user modifications. |
+ files_to_checksum = [os.path.join(self.gsutil_bin_dir, 'gsutil')] |
+ for root, sub_folders, files in os.walk(self.gsutil_bin_dir): |
+ for file in files: |
+ if file[-3:] == '.py': |
+ files_to_checksum.append(os.path.join(root, file)) |
+ # Sort to ensure consistent checksum build, no matter how os.walk |
+ # orders the list. |
+ for file in sorted(files_to_checksum): |
+ f = open(file, 'r') |
+ content = f.read() |
+ content = re.sub(r'(\r\n|\r|\n)', '\n', content) |
+ m.update(content) |
+ f.close() |
+ return m.hexdigest() |