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

Side by Side Diff: chrome/common/extensions/docs/server2/app_yaml_helper.py

Issue 14247024: Devserver: allow SubversionFileSystem to be pinned to a specific rev on construction (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import logging
6
7 _APP_YAML_CONTAINER = '''
8 application: chrome-apps-doc
9 version: %s
10 runtime: python27
11 api_version: 1
12 threadsafe: false
13 '''
14
15 class AppYamlHelper(object):
16 '''Parses the app.yaml file, and is able to step back in the host file
17 system's revision history to find when it changed to some given version.
18 '''
19 class Delegate(object):
20 def GetHostFileSystemForRevision(self, revision):
21 '''Revision may not be None.
22 '''
23 raise NotImplementedError()
24
25 def __init__(self,
26 app_yaml_path,
27 file_system_at_head,
28 delegate,
29 object_store_creator):
30 self._app_yaml_path = app_yaml_path
31 self._file_system_at_head = file_system_at_head
32 self._delegate = delegate
33 self._store = object_store_creator.Create(
34 AppYamlHelper,
35 category=file_system_at_head.GetIdentity(),
36 start_empty=False)
37
38 @staticmethod
39 def ExtractVersion(app_yaml, key='version'):
40 '''Extracts the 'version' key from the contents of an app.yaml file.
41 Allow overriding the key to parse e.g. the cron file ('target').
42 '''
43 # We could properly parse this using a yaml library but Python doesn't have
44 # one built in so whatevs.
45 key_colon = '%s:' % key
46 versions = [line.strip()[len(key_colon):].strip()
47 for line in app_yaml.split('\n')
48 if line.strip().startswith(key_colon)]
49 if not versions:
50 raise ValueError('No versions found for %s in %s' % (
51 key, app_yaml))
52 if len(set(versions)) > 1:
53 raise ValueError('Inconsistent versions found for %s in %s: %s' % (
54 key, app_yaml, versions))
55 return versions[0]
56
57 @staticmethod
58 def IsGreater(lhs, rhs):
59 '''Return whether the app.yaml version |lhs| > |rhs|. This is tricky
60 because versions are typically not numbers but rather 2-0-9, 2-0-12,
61 2-1-0, etc - and 2-1-0 > 2-0-10 > 2-0-9.
62 '''
63 lhs_parts = lhs.replace('-', '.').split('.')
64 rhs_parts = rhs.replace('-', '.').split('.')
65 while lhs_parts and rhs_parts:
66 lhs_msb = int(lhs_parts.pop(0))
67 rhs_msb = int(rhs_parts.pop(0))
68 if lhs_msb != rhs_msb:
69 return lhs_msb > rhs_msb
70 return len(lhs) > len(rhs)
71
72 @staticmethod
73 def GenerateAppYaml(version):
74 '''Probably only useful for tests.
75 '''
76 return _APP_YAML_CONTAINER % version
77
78 def IsUpToDate(self, app_version):
79 '''Returns True if the |app_version| is up to date with respect to the one
80 checked into the host file system.
81 '''
82 checked_in_app_version = AppYamlHelper.ExtractVersion(
83 self._file_system_at_head.ReadSingle(self._app_yaml_path))
84 if app_version == checked_in_app_version:
85 return True
86 if AppYamlHelper.IsGreater(app_version, checked_in_app_version):
87 logging.warning(
88 'Server is too new! Checked in %s < currently running %s' % (
89 checked_in_app_version, app_version))
90 return True
91 return False
92
93 def GetFirstRevisionGreaterThan(self, app_version):
94 '''Finds the first revision that the version in app.yaml was greater than
95 |app_version|.
96
97 WARNING: if there is no such revision (e.g. the app is up to date, or
98 *oops* the app is even newer) then this will throw a ValueError. Use
99 IsUpToDate to validate the input before calling this method.
100 '''
101 stored = self._store.Get(app_version).Get()
102 if stored is None:
103 stored = self._GetFirstRevisionGreaterThanImpl(app_version)
104 assert stored is not None
105 self._store.Set(app_version, stored)
106 return stored
107
108 def _GetFirstRevisionGreaterThanImpl(self, app_version):
109 def get_app_yaml_revision(file_system):
110 return int(file_system.Stat(self._app_yaml_path).version)
111
112 def has_greater_app_version(file_system):
113 app_version_in_file_system = AppYamlHelper.ExtractVersion(
114 file_system.ReadSingle(self._app_yaml_path))
115 return AppYamlHelper.IsGreater(app_version_in_file_system, app_version)
116
117 found = None
118 next_file_system = self._file_system_at_head
119
120 while has_greater_app_version(next_file_system):
121 found = get_app_yaml_revision(next_file_system)
122 # Back up a revision then find when app.yaml was last updated before then.
123 if found == 0:
124 logging.warning('All revisions are greater than %s' % app_version)
125 return 0
126 next_file_system = self._delegate.GetHostFileSystemForRevision(
127 found - 1)
128
129 if found is None:
130 raise ValueError('All revisions are less than %s' % app_version)
131 return found
OLDNEW
« no previous file with comments | « chrome/common/extensions/docs/server2/app.yaml ('k') | chrome/common/extensions/docs/server2/app_yaml_helper_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698