Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: build/write_build_date_header.py

Issue 1846713002: Improve the error message in BuildTime.InThePast to help figure out the problem. (Closed) Base URL: https://chromium.googlesource.com/a/chromium/src.git@master
Patch Set: Rewrite Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/build_time_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2016 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2016 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 """Writes a file that contains a define that approximates the build date. 5 """Writes a file that contains a define that approximates the build date.
6 6
7 For unofficial builds, the build date is set to the most recent first Sunday 7 build_type impacts the timestamp generated:
8 of a month, in UTC time. 8 - default: the build date is set to the most recent first Sunday of a month at
9 9 5:00am. The reason is that it is a time where invalidating the build cache
10 For official builds, the build date is set to the current date (in UTC). 10 shouldn't have major reprecussions (due to lower load).
11 - official: the build date is set to the current date at 5:00am, or the day
12 before if the current time is before 5:00am.
13 Either way, it is guaranteed to be in the past and always in UTC.
11 14
12 It is also possible to explicitly set a build date to be used. 15 It is also possible to explicitly set a build date to be used.
13
14 The reason for using the first Sunday of a month for unofficial builds is that
15 it is a time where invalidating the build cache shouldn't have major
16 reprecussions (due to lower load).
17 """ 16 """
18 17
19 import argparse 18 import argparse
20 import calendar 19 import calendar
21 import datetime 20 import datetime
21 import doctest
22 import os 22 import os
23 import sys 23 import sys
24 24
25 25
26 def GetFirstSundayOfMonth(year, month): 26 def GetFirstSundayOfMonth(year, month):
27 """Returns the first sunday of the given month of the given year.""" 27 """Returns the first sunday of the given month of the given year.
28
29 >>> GetFirstSundayOfMonth(2016, 2)
lgarron 2016/04/04 17:43:24 Any reason these shouldn't stay asserts?
M-A Ruel 2016/04/04 18:05:01 because asserts will not print both values when it
30 7
31 >>> GetFirstSundayOfMonth(2016, 3)
32 6
33 >>> GetFirstSundayOfMonth(2000, 1)
34 2
35 """
28 weeks = calendar.Calendar().monthdays2calendar(year, month) 36 weeks = calendar.Calendar().monthdays2calendar(year, month)
29 # Return the first day in the first week that is a Sunday. 37 # Return the first day in the first week that is a Sunday.
30 return [date_day[0] for date_day in weeks[0] if date_day[1] == 6][0] 38 return [date_day[0] for date_day in weeks[0] if date_day[1] == 6][0]
31 39
32 40
33 # Validate that GetFirstSundayOfMonth works. 41 def GetBuildDate(build_type, utc_now):
34 assert GetFirstSundayOfMonth(2016, 2) == 7 42 """Gets the approximate build date given the specific build type.
35 assert GetFirstSundayOfMonth(2016, 3) == 6
36 assert GetFirstSundayOfMonth(2000, 1) == 2
37 43
38 44 >>> GetBuildDate('default', datetime.datetime(2016, 2, 6, 1, 2, 3))
39 def GetBuildDate(build_type, utc_now): 45 'Jan 03 2016 01:02:03'
40 """Gets the approximate build date given the specific build type.""" 46 >>> GetBuildDate('default', datetime.datetime(2016, 2, 7, 5))
47 'Feb 07 2016 05:00:00'
48 >>> GetBuildDate('default', datetime.datetime(2016, 2, 8, 5))
49 'Feb 07 2016 05:00:00'
50 """
41 day = utc_now.day 51 day = utc_now.day
42 month = utc_now.month 52 month = utc_now.month
43 year = utc_now.year 53 year = utc_now.year
44 if build_type != 'official': 54 if build_type != 'official':
45 first_sunday = GetFirstSundayOfMonth(year, month) 55 first_sunday = GetFirstSundayOfMonth(year, month)
46 # If our build is after the first Sunday, we've already refreshed our build 56 # If our build is after the first Sunday, we've already refreshed our build
47 # cache on a quiet day, so just use that day. 57 # cache on a quiet day, so just use that day.
48 # Otherwise, take the first Sunday of the previous month. 58 # Otherwise, take the first Sunday of the previous month.
49 if day >= first_sunday: 59 if day >= first_sunday:
50 day = first_sunday 60 day = first_sunday
51 else: 61 else:
52 month -= 1 62 month -= 1
53 if month == 0: 63 if month == 0:
54 month = 12 64 month = 12
55 year -= 1 65 year -= 1
56 day = GetFirstSundayOfMonth(year, month) 66 day = GetFirstSundayOfMonth(year, month)
57 return '{:%b %d %Y}'.format(datetime.date(year, month, day)) 67 now = datetime.datetime(
58 68 year, month, day, utc_now.hour, utc_now.minute, utc_now.second)
59 69 return '{:%b %d %Y %H:%M:%S}'.format(now)
60 # Validate that GetBuildDate works.
61 assert GetBuildDate('default', datetime.date(2016, 2, 6)) == 'Jan 03 2016'
62 assert GetBuildDate('default', datetime.date(2016, 2, 7)) == 'Feb 07 2016'
63 assert GetBuildDate('default', datetime.date(2016, 2, 8)) == 'Feb 07 2016'
64 70
65 71
66 def main(): 72 def main():
67 argument_parser = argparse.ArgumentParser() 73 if doctest.testmod()[0]:
Nico 2016/04/04 15:31:44 ^ mithro: see here for the doctest question
74 return 1
75 argument_parser = argparse.ArgumentParser(
76 description=sys.modules[__name__].__doc__,
77 formatter_class=argparse.RawDescriptionHelpFormatter)
68 argument_parser.add_argument('output_file', help='The file to write to') 78 argument_parser.add_argument('output_file', help='The file to write to')
69 argument_parser.add_argument('build_type', help='The type of build', 79 argument_parser.add_argument(
70 choices=('official', 'default')) 80 'build_type', help='The type of build', choices=('official', 'default'))
71 argument_parser.add_argument('build_date_override', nargs='?', 81 argument_parser.add_argument(
72 help='Optional override for the build date') 82 'build_date_override', nargs='?',
83 help='Optional override for the build date. Format must be '
84 '\'Mmm DD YYYY HH:MM:SS\'')
73 args = argument_parser.parse_args() 85 args = argument_parser.parse_args()
74 86
75 if args.build_date_override: 87 if args.build_date_override:
88 # Format is expected to be "Mmm DD YYYY HH:MM:SS".
76 build_date = args.build_date_override 89 build_date = args.build_date_override
77 else: 90 else:
78 build_date = GetBuildDate(args.build_type, datetime.datetime.utcnow()) 91 now = datetime.datetime.utcnow()
92 if now.hour < 5:
93 # The time is locked at 5:00 am in UTC to cause the build cache
94 # invalidation to not happen exactly at midnight. Take the day before.
lgarron 2016/04/04 17:43:24 Could you rephrase this to something like "Use the
M-A Ruel 2016/04/04 18:05:01 Done.
95 # See //base/build_time.cc.
96 now = now - datetime.timedelta(day=1)
97 now = datetime.datetime(now.year, now.month, now.day, 5, 0, 0)
98 build_date = GetBuildDate(args.build_type, now)
79 99
80 output = ('// Generated by //build/write_build_date_header.py\n' 100 output = ('// Generated by //build/write_build_date_header.py\n'
81 '#ifndef BUILD_DATE\n' 101 '#ifndef BUILD_DATE\n'
82 '#define BUILD_DATE "{}"\n' 102 '#define BUILD_DATE "{}"\n'
83 '#endif // BUILD_DATE\n'.format(build_date)) 103 '#endif // BUILD_DATE\n'.format(build_date))
84 104
85 current_contents = '' 105 current_contents = ''
86 if os.path.isfile(args.output_file): 106 if os.path.isfile(args.output_file):
87 with open(args.output_file, 'r') as current_file: 107 with open(args.output_file, 'r') as current_file:
88 current_contents = current_file.read() 108 current_contents = current_file.read()
89 109
90 if current_contents != output: 110 if current_contents != output:
91 with open(args.output_file, 'w') as output_file: 111 with open(args.output_file, 'w') as output_file:
92 output_file.write(output) 112 output_file.write(output)
93 return 0 113 return 0
94 114
95 115
96 if __name__ == '__main__': 116 if __name__ == '__main__':
97 sys.exit(main()) 117 sys.exit(main())
OLDNEW
« no previous file with comments | « base/build_time_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698