Mercurial > libervia-backend
comparison src/tools/utils.py @ 1858:06e13ae616cf
tools (utils): improved repository version detection:
- getRepositoryData has 2 new option: is_path to give absolute path instead of module name, and save_dir_path to save the repository data in a pickled dictionnary
- if "hg" executable doesn't work, a .hg_data dictionnary is checked if present in module root path
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 28 Feb 2016 13:42:31 +0100 |
parents | 2d2617930f97 |
children | 2daf7b4c6756 |
comparison
equal
deleted
inserted
replaced
1857:2d2617930f97 | 1858:06e13ae616cf |
---|---|
51 template_time = u"%H:%M:%SZ" | 51 template_time = u"%H:%M:%SZ" |
52 template = u"{}T{}".format(template_date, template_time) if with_time else template_date | 52 template = u"{}T{}".format(template_date, template_time) if with_time else template_date |
53 return datetime.datetime.utcfromtimestamp(time.time() if timestamp is None else timestamp).strftime(template) | 53 return datetime.datetime.utcfromtimestamp(time.time() if timestamp is None else timestamp).strftime(template) |
54 | 54 |
55 | 55 |
56 def getRepositoryData(module, as_string=True): | 56 def getRepositoryData(module, as_string=True, is_path=False, save_dir_path=None): |
57 """Retrieve info on current mecurial repository | 57 """Retrieve info on current mecurial repository |
58 | 58 |
59 @param module: module to look for (e.g. sat, libervia) | 59 Data is gotten by using the following methods, in order: |
60 - using "hg" executable | |
61 - looking for a ".hg_data" file in the root of the module | |
62 this file must contain the data dictionnary serialized with pickle | |
63 - looking for a .hg/dirstate in parent directory of module (or in module/.hg if | |
64 is_path is True), and parse dirstate file to get revision | |
65 @param module(unicode): module to look for (e.g. sat, libervia) | |
66 module can be a path if is_path is True (see below) | |
60 @param as_string(bool): if True return a string, else return a dictionary | 67 @param as_string(bool): if True return a string, else return a dictionary |
68 @param is_path(bool): if True "module" is not handled as a module name, but as an | |
69 absolute path to the parent of a ".hg" directory | |
70 @param save_path(str, None): if not None, the value will be saved to given path as a pickled dict | |
71 /!\\ the .hg_data file in the given directory will be overwritten | |
61 @return (unicode, dictionary): retrieved info in a nice string, | 72 @return (unicode, dictionary): retrieved info in a nice string, |
62 or a dictionary with retrieved data (key is not present if data is not found), | 73 or a dictionary with retrieved data (key is not present if data is not found), |
63 key can be: | 74 key can be: |
64 - node: full revision number (40 bits) | 75 - node: full revision number (40 bits) |
65 - branch: branch name | 76 - branch: branch name |
67 - tag: latest tag used in hierarchie | 78 - tag: latest tag used in hierarchie |
68 """ | 79 """ |
69 from distutils.spawn import find_executable | 80 from distutils.spawn import find_executable |
70 import subprocess | 81 import subprocess |
71 KEYS=("node", "node_short", "branch", "date", "tag") | 82 KEYS=("node", "node_short", "branch", "date", "tag") |
72 repos_root = os.path.dirname(module.__file__) | 83 ori_cwd = os.getcwd() |
84 | |
85 if is_path: | |
86 repos_root = module | |
87 else: | |
88 repos_root = os.path.dirname(module.__file__) | |
89 | |
73 hg_path = find_executable('hg') | 90 hg_path = find_executable('hg') |
74 | 91 |
75 if hg_path is not None: | 92 if hg_path is not None: |
76 os.chdir(repos_root) | 93 os.chdir(repos_root) |
77 try: | 94 try: |
86 pass | 103 pass |
87 else: | 104 else: |
88 hg_data = {} | 105 hg_data = {} |
89 | 106 |
90 if not hg_data: | 107 if not hg_data: |
91 log.debug(u"Mercurial not available or working, trying to get data from dirstate") | 108 # .hg_data pickle method |
92 os.chdir(os.path.relpath('..', repos_root)) | 109 log.debug(u"Mercurial not available or working, trying other methods") |
110 if save_dir_path is None: | |
111 log.debug(u"trying .hg_data method") | |
112 | |
113 try: | |
114 with open(os.path.join(repos_root, '.hg_data')) as f: | |
115 import cPickle as pickle | |
116 hg_data = pickle.load(f) | |
117 except IOError as e: | |
118 log.debug(u"Can't access .hg_data file: {}".format(e)) | |
119 except pickle.UnpicklingError: | |
120 log.warning(u"Error while reading {}, can't get repos data".format(f.name)) | |
121 | |
122 if not hg_data: | |
123 # .hg/dirstate method | |
124 log.debug(u"trying dirstate method") | |
125 if is_path: | |
126 os.chdir(repos_root) | |
127 else: | |
128 os.chdir(os.path.relpath('..', repos_root)) | |
93 try: | 129 try: |
94 with open('.hg/dirstate') as hg_dirstate: | 130 with open('.hg/dirstate') as hg_dirstate: |
95 hg_data['node'] = hg_dirstate.read(20).encode('hex') | 131 hg_data['node'] = hg_dirstate.read(20).encode('hex') |
96 hg_data['node_short'] = hg_data['node'][:12] | 132 hg_data['node_short'] = hg_data['node'][:12] |
97 except IOError: | 133 except IOError: |
98 log.warning(u"Can't access repository data") | 134 log.warning(u"Can't access repository data") |
135 | |
136 # we restore original working dir | |
137 os.chdir(ori_cwd) | |
138 | |
139 # data saving | |
140 if save_dir_path is not None and hg_data: | |
141 if not os.path.isdir(save_dir_path): | |
142 log.warning(u"Given path is not a directory, can't save data") | |
143 else: | |
144 import cPickle as pickle | |
145 dest_path = os.path.join(save_dir_path, ".hg_data") | |
146 try: | |
147 with open(dest_path, 'w') as f: | |
148 pickle.dump(hg_data, f, 2) | |
149 except IOError as e: | |
150 log.warning(u"Can't save file to {path}: {reason}".format( | |
151 path=dest_path, reason=e)) | |
152 else: | |
153 log.debug(u"repository data saved to {}".format(dest_path)) | |
99 | 154 |
100 if as_string: | 155 if as_string: |
101 if not hg_data: | 156 if not hg_data: |
102 return u'repository data unknown' | 157 return u'repository data unknown' |
103 strings = [u'rev', hg_data['node_short']] | 158 strings = [u'rev', hg_data['node_short']] |