1#!/usr/bin/env python
2
3# Copyright 2015 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7import codecs
8import optparse
9import os
10import re
11import subprocess
12import sys
13
14_CATAPULT_PATH = os.path.abspath(
15    os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir))
16sys.path.append(os.path.join(_CATAPULT_PATH, 'tracing'))
17
18# this import needs to be after the change to sys.path above
19#pylint: disable=wrong-import-position
20from tracing_build import vulcanize_trace_viewer
21
22
23SYSTRACE_TRACE_VIEWER_HTML_FILE = os.path.join(
24    os.path.abspath(os.path.dirname(__file__)),
25    'systrace_trace_viewer.html')
26CATAPULT_REV_ = 'CATAPULT_REV'
27NO_AUTO_UPDATE_ = 'NO_AUTO_UPDATE'
28UNKNOWN_REVISION_ = 'UNKNOWN'
29
30
31def create_catapult_rev_str_(revision):
32  return '<!--' + CATAPULT_REV_ + '=' + str(revision) + '-->'
33
34
35def get_catapult_rev_in_file_(html_file):
36  assert os.path.exists(html_file)
37  rev = ''
38  with open(html_file, 'r') as f:
39    lines = f.readlines()
40    for line in lines[::-1]:
41      if CATAPULT_REV_ in line:
42        tokens = line.split(CATAPULT_REV_)
43        rev = re.sub(r'[=\->]', '', tokens[1]).strip()
44        break
45  return rev
46
47
48def get_catapult_rev_in_git_():
49  try:
50    catapult_rev = subprocess.check_output(
51        'git rev-parse HEAD',
52        shell=True, # Needed by Windows
53        cwd=os.path.dirname(os.path.abspath(__file__))).strip()
54  except (subprocess.CalledProcessError, OSError):
55    return None
56  if not catapult_rev:
57    return None
58  return catapult_rev
59
60
61def update(no_auto_update=False, no_min=False, force_update=False):
62  """Update the systrace trace viewer html file.
63
64  When the html file exists, do not update the file if
65  1. the revision is NO_AUTO_UPDATE_;
66  2. or the revision is not changed.
67
68  Args:
69    no_auto_update: If true, force updating the file with revision
70                    NO_AUTO_UPDATE_. Future auto-updates will be skipped.
71    no_min:         If true, skip minification when updating the file.
72    force_update:   If true, update the systrace trace viewer file no matter
73                    what.
74  """
75  if no_auto_update:
76    new_rev = NO_AUTO_UPDATE_
77  else:
78    new_rev = get_catapult_rev_in_git_()
79    if not new_rev:
80      # Source tree could be missing git metadata.
81      print >> sys.stderr, 'Warning: Couldn\'t determine current git revision.'
82      new_rev = UNKNOWN_REVISION_
83
84  need_update = False
85  if force_update:
86    need_update = True
87  elif no_auto_update:
88    need_update = True
89  elif not os.path.exists(SYSTRACE_TRACE_VIEWER_HTML_FILE):
90    need_update = True
91  else:
92    old_rev = get_catapult_rev_in_file_(SYSTRACE_TRACE_VIEWER_HTML_FILE)
93    if not old_rev or old_rev == UNKNOWN_REVISION_:
94      need_update = True
95    # If old_rev was set to NO_AUTO_UPDATE_ it should be skipped, since forced
96    # update cases have been already handled above.
97    if old_rev != new_rev and old_rev != NO_AUTO_UPDATE_:
98      need_update = True
99
100  if not need_update:
101    print 'Update skipped.'
102    return
103
104  print 'Generating viewer file %s with revision %s.' % (
105            SYSTRACE_TRACE_VIEWER_HTML_FILE, new_rev)
106
107  # Generate the vulcanized result.
108  with codecs.open(SYSTRACE_TRACE_VIEWER_HTML_FILE,
109                   encoding='utf-8', mode='w') as f:
110    vulcanize_trace_viewer.WriteTraceViewer(
111        f,
112        config_name='full',
113        minify=(not no_min),
114        output_html_head_and_body=False)
115    if not force_update:
116      f.write(create_catapult_rev_str_(new_rev))
117
118def main():
119  parser = optparse.OptionParser()
120  parser.add_option('--force-update', dest='force_update',
121                    default=False, action='store_true', help='force update the '
122                    'systrace trace viewer html file')
123  parser.add_option('--no-auto-update', dest='no_auto_update',
124                    default=False, action='store_true', help='force update the '
125                    'systrace trace viewer html file and disable auto-updates, '
126                    'delete \'systrace_trace_viewer.html\' to re-enable '
127                    'auto-updates')
128  parser.add_option('--no-min', dest='no_min', default=False,
129                    action='store_true', help='skip minification')
130  # pylint: disable=unused-variable
131  options, unused_args = parser.parse_args(sys.argv[1:])
132
133  update(no_auto_update=options.no_auto_update,
134         no_min=options.no_min,
135         force_update=options.force_update)
136
137if __name__ == '__main__':
138  main()
139