Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / telemetry / third_party / gsutilz / gslib / commands / version.py
blobf07be031bb61e99fa9ee93991950255d3aea0a31
1 # -*- coding: utf-8 -*-
2 # Copyright 2011 Google Inc. All Rights Reserved.
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
8 # http://www.apache.org/licenses/LICENSE-2.0
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 """Implementation of gsutil version command."""
17 from __future__ import absolute_import
19 from hashlib import md5
20 import os
21 import platform
22 import re
23 import sys
25 import boto
26 import crcmod
27 import gslib
28 from gslib.command import Command
29 from gslib.util import GetConfigFilePath
30 from gslib.util import MultiprocessingIsAvailable
31 from gslib.util import UsingCrcmodExtension
34 _SYNOPSIS = """
35 gsutil version
36 """
38 _DETAILED_HELP_TEXT = ("""
39 <B>SYNOPSIS</B>
40 """ + _SYNOPSIS + """
43 <B>DESCRIPTION</B>
44 Prints information about the version of gsutil.
46 <B>OPTIONS</B>
47 -l Prints additional information, such as the version of Python
48 being used, the version of the Boto library, a checksum of the
49 code, the path to gsutil, and the path to gsutil's configuration
50 file.
51 """)
54 class VersionCommand(Command):
55 """Implementation of gsutil version command."""
57 # Command specification. See base class for documentation.
58 command_spec = Command.CreateCommandSpec(
59 'version',
60 command_name_aliases=['ver'],
61 usage_synopsis=_SYNOPSIS,
62 min_args=0,
63 max_args=0,
64 supported_sub_args='l',
65 file_url_ok=False,
66 provider_url_ok=False,
67 urls_start_arg=0,
69 # Help specification. See help_provider.py for documentation.
70 help_spec = Command.HelpSpec(
71 help_name='version',
72 help_name_aliases=['ver'],
73 help_type='command_help',
74 help_one_line_summary='Print version info about gsutil',
75 help_text=_DETAILED_HELP_TEXT,
76 subcommand_help_text={},
79 def RunCommand(self):
80 """Command entry point for the version command."""
81 long_form = False
82 if self.sub_opts:
83 for o, _ in self.sub_opts:
84 if o == '-l':
85 long_form = True
87 config_path = GetConfigFilePath()
89 shipped_checksum = gslib.CHECKSUM
90 try:
91 cur_checksum = self._ComputeCodeChecksum()
92 except IOError:
93 cur_checksum = 'MISSING FILES'
94 if shipped_checksum == cur_checksum:
95 checksum_ok_str = 'OK'
96 else:
97 checksum_ok_str = '!= %s' % shipped_checksum
99 sys.stdout.write('gsutil version: %s\n' % gslib.VERSION)
101 if long_form:
103 long_form_output = (
104 'checksum: {checksum} ({checksum_ok})\n'
105 'boto version: {boto_version}\n'
106 'python version: {python_version}\n'
107 'OS: {os_version}\n'
108 'multiprocessing available: {multiprocessing_available}\n'
109 'using cloud sdk: {cloud_sdk}\n'
110 'config path: {config_path}\n'
111 'gsutil path: {gsutil_path}\n'
112 'compiled crcmod: {compiled_crcmod}\n'
113 'installed via package manager: {is_package_install}\n'
114 'editable install: {is_editable_install}\n'
117 sys.stdout.write(long_form_output.format(
118 checksum=cur_checksum,
119 checksum_ok=checksum_ok_str,
120 boto_version=boto.__version__,
121 python_version=sys.version.replace('\n', ''),
122 os_version='%s %s' % (platform.system(), platform.release()),
123 multiprocessing_available=MultiprocessingIsAvailable()[0],
124 cloud_sdk=(os.environ.get('CLOUDSDK_WRAPPER') == '1'),
125 config_path=config_path,
126 gsutil_path=gslib.GSUTIL_PATH,
127 compiled_crcmod=UsingCrcmodExtension(crcmod),
128 is_package_install=gslib.IS_PACKAGE_INSTALL,
129 is_editable_install=gslib.IS_EDITABLE_INSTALL,
132 return 0
134 def _ComputeCodeChecksum(self):
135 """Computes a checksum of gsutil code.
137 This checksum can be used to determine if users locally modified
138 gsutil when requesting support. (It's fine for users to make local mods,
139 but when users ask for support we ask them to run a stock version of
140 gsutil so we can reduce possible variables.)
142 Returns:
143 MD5 checksum of gsutil code.
145 if gslib.IS_PACKAGE_INSTALL:
146 return 'PACKAGED_GSUTIL_INSTALLS_DO_NOT_HAVE_CHECKSUMS'
147 m = md5()
148 # Checksum gsutil and all .py files under gslib directory.
149 files_to_checksum = [gslib.GSUTIL_PATH]
150 for root, _, files in os.walk(gslib.GSLIB_DIR):
151 for filepath in files:
152 if filepath.endswith('.py'):
153 files_to_checksum.append(os.path.join(root, filepath))
154 # Sort to ensure consistent checksum build, no matter how os.walk
155 # orders the list.
156 for filepath in sorted(files_to_checksum):
157 f = open(filepath, 'r')
158 content = f.read()
159 content = re.sub(r'(\r\n|\r|\n)', '\n', content)
160 m.update(content)
161 f.close()
162 return m.hexdigest()