|
1 # |
|
2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # |
|
16 |
|
17 import os.path |
|
18 import sys |
|
19 import logging |
|
20 from optparse import OptionParser, OptionGroup |
|
21 import cone_common |
|
22 from cone.public import api |
|
23 from conesub_merge import get_active_root_if_necessary |
|
24 |
|
25 VERSION = '1.0' |
|
26 |
|
27 logger = logging.getLogger('cone') |
|
28 |
|
29 def find_variant_layers(source_config): |
|
30 """ |
|
31 Find all layers in the configuration that contain custvariant* in |
|
32 their path name and return a list containing source->target mappings. |
|
33 @param target_config: The target configuration object. |
|
34 @param new_name: The new name to replace custvariant* in the |
|
35 target path name with. |
|
36 @return: A list of (source_layer, target_layer) tuples. |
|
37 """ |
|
38 import re |
|
39 pattern = re.compile(r'.*/(custvariant[^/]*)/.*') |
|
40 result = [] |
|
41 |
|
42 for src in source_config.list_configurations(): |
|
43 m = pattern.match(src) |
|
44 if m: |
|
45 result.append(src) |
|
46 |
|
47 return result |
|
48 |
|
49 def get_metadatas_as_convertprojectml(configuration_root): |
|
50 """ |
|
51 Creates lines for convertprojectml file from metadata items and also adds |
|
52 version info to correct place. |
|
53 @param configuration_root: Configuration root object which contains metadatas. |
|
54 @return: A list of metadata lines for convertprojectml. |
|
55 """ |
|
56 metadatas = configuration_root.get_meta() |
|
57 metadata_line = [] |
|
58 |
|
59 for metadata in metadatas: |
|
60 if metadata.ns == "http://www.s60.com/xml/confml/1" or metadata.ns == "http://www.s60.com/xml/confml/2": |
|
61 if metadata.tag == 'release': |
|
62 metadata_line.append("<" + metadata.tag + ">${convertproject.versioninfo}</" + metadata.tag + ">") |
|
63 elif metadata.tag == 'version': |
|
64 metadata_line.append("<" + metadata.tag + ">001</" + metadata.tag + ">") |
|
65 else: |
|
66 metadata_line.append("<" + metadata.tag + ">" + metadata.value + "</" + metadata.tag + ">") |
|
67 |
|
68 if metadata.ns == "http://www.nokia.com/xml/cpf-id/1": |
|
69 if metadata.attrs['name'] == 'sw_version': |
|
70 metadata_line.append('<cv:configuration-property name="' + metadata.attrs['name'] + '" value="${convertproject.versioninfo}" />') |
|
71 else: |
|
72 metadata_line.append('<cv:configuration-property name="' + metadata.attrs['name'] + '" value="' + metadata.attrs['value'] + '" />') |
|
73 |
|
74 return metadata_line |
|
75 |
|
76 def get_layerlist_as_convertprojectml(configuration_root): |
|
77 """ |
|
78 Creates lines for convertprojectml file from layer items in configurtion root |
|
79 @param configuration_root: Configuration root object |
|
80 @return: A list of layer lines for convertprojectml. |
|
81 """ |
|
82 layer_line = [] |
|
83 layer_list = configuration_root.list_configurations() |
|
84 |
|
85 for layer_item in layer_list: |
|
86 layer_line.append('<filter action="include_layer" data="' + layer_item + '"/>') |
|
87 |
|
88 return layer_line |
|
89 |
|
90 def create_convertprojectml_file(conf_filename, conv_proj_filename, filepath,layerlist, metadatas, root_name): |
|
91 """ |
|
92 Creates convertprojectml file for package |
|
93 @param conf_filename: configuration root filename |
|
94 @param conv_proj_filename: convertprojectml filename |
|
95 @param filepath: path where file is created |
|
96 @param layerlist: list of layers |
|
97 @param metadatas: list of metadatas |
|
98 @param root_name: Name of configuration root |
|
99 """ |
|
100 |
|
101 file_header = ['<?xml version="1.0" encoding="UTF-8"?>' + "\r\n", |
|
102 '<convertprojectml xmlns="http://www.s60.com/xml/convertprojectml/1">' + "\r\n\r\n", |
|
103 '<targetProject path=""/>' + "\r\n", |
|
104 "\t" + '<layer path="">' + "\r\n", |
|
105 "\t\t" + '<file type="configuration_root" path="'+ conf_filename + '"'] |
|
106 |
|
107 #root_name can be empty so we need to check is there some content. |
|
108 if root_name: |
|
109 file_header.append(' configuration_name="' + root_name + '"') |
|
110 file_header.append('>' + "\r\n") |
|
111 |
|
112 file_footer = ["\t\t" + '</file>' + "\r\n", |
|
113 "\t" +'</layer>' + "\r\n", |
|
114 '</convertprojectml>'+ "\r\n"] |
|
115 |
|
116 convert_file = os.path.abspath(filepath + "/" + conv_proj_filename) |
|
117 fh = open(convert_file,'wb') |
|
118 fh.writelines(file_header) |
|
119 fh.write("\t\t\t" + '<meta xmlns:cv="http://www.nokia.com/xml/cpf-id/1">' + "\r\n") |
|
120 |
|
121 for meta_line in metadatas: |
|
122 fh.write("\t\t\t\t" + meta_line + "\r\n") |
|
123 fh.write("\t\t\t" + '</meta>' + "\r\n") |
|
124 |
|
125 for layer_line in layerlist: |
|
126 fh.write("\t\t\t" + layer_line + "\r\n") |
|
127 |
|
128 fh.writelines(file_footer) |
|
129 fh.close() |
|
130 |
|
131 def main(argv=sys.argv): |
|
132 """ Pack (zip) the variant layers of a configuration. """ |
|
133 parser = OptionParser(version="%%prog %s" % VERSION) |
|
134 |
|
135 parser.add_options(cone_common.COMMON_OPTIONS) |
|
136 |
|
137 parser.add_option("-p", "--project", |
|
138 dest="project", |
|
139 help="Defines the location of current project. Default is the current working directory.", |
|
140 default=".", |
|
141 metavar="STORAGE") |
|
142 |
|
143 group = OptionGroup(parser, "Packvariant options", |
|
144 "The packvariant action is intended for packing variant to a zip-file for integration purposes.") |
|
145 |
|
146 group.add_option("-c", "--configuration", |
|
147 dest="configuration", |
|
148 help="Name of the configuration wanted to be packed.", |
|
149 metavar="CONFIG") |
|
150 |
|
151 group.add_option("-r", "--remote", |
|
152 dest="remote", |
|
153 help="Defines a location and a name of remote storage (ZIP)", |
|
154 metavar="STORAGE") |
|
155 |
|
156 group.add_option("-l", "--convert-location", |
|
157 dest="convertlocation", |
|
158 help="Defines a location of convertprojectml file." |
|
159 "Default location is <PROJECT>/convertpluginlayer/implml/", |
|
160 default="/convertpluginlayer/implml/") |
|
161 |
|
162 parser.add_option_group(group) |
|
163 (options, _) = parser.parse_args(argv) |
|
164 |
|
165 cone_common.handle_common_options(options) |
|
166 |
|
167 # Check the passed options |
|
168 if not options.remote: parser.error("Target where variant package is placed must be given") |
|
169 if not options.configuration: parser.error("Configuration root to be packed must be given") |
|
170 |
|
171 try: |
|
172 target_storage = api.Storage.open(options.remote,'w', username=options.username, password=options.password) |
|
173 target_project = api.Project(target_storage) |
|
174 source_storage = api.Storage.open(options.project,'r', username=options.username, password=options.password) |
|
175 |
|
176 if not os.path.isdir(source_storage.get_path()): |
|
177 print "ERROR: --Project must be a directory. Terminating the program." |
|
178 sys.exit(1) |
|
179 |
|
180 source_project = api.Project(source_storage) |
|
181 source_config = get_active_root_if_necessary(source_project, options.configuration, 'source') |
|
182 source_config = source_project.get_configuration(source_config) |
|
183 fname, _ = os.path.splitext(options.configuration) |
|
184 conv_project_filename = fname + ".convertprojectml" |
|
185 print "Packing configuration: %s" % options.configuration |
|
186 print "Source project: %s" % options.project |
|
187 print "Target project: %s" % options.remote |
|
188 |
|
189 # Adding all files in layers |
|
190 layer_list = find_variant_layers(source_config) |
|
191 |
|
192 for add_layer in layer_list: |
|
193 layer_config = source_project.get_configuration(add_layer) |
|
194 layer = layer_config.get_layer() |
|
195 path_part = layer.path + "/" |
|
196 target_project.import_configuration(layer_config) |
|
197 resource_list = layer_config.layer.list_all_resources(recurse=True) |
|
198 |
|
199 for single_resource in resource_list: |
|
200 parsed_path = path_part + single_resource |
|
201 if source_storage.is_resource(parsed_path): |
|
202 logger.info("Adding file: %s" % parsed_path) |
|
203 target_storage.import_resources([parsed_path], source_storage) |
|
204 if source_storage.is_folder(path_part + single_resource): |
|
205 logger.info("Adding folder: %s" % parsed_path) |
|
206 target_storage.create_folder(parsed_path) |
|
207 |
|
208 layer_list = get_layerlist_as_convertprojectml(source_config) |
|
209 metadata_list = get_metadatas_as_convertprojectml(source_config) |
|
210 if not source_storage.is_folder(os.path.normpath(options.convertlocation + "/")): |
|
211 source_storage.create_folder(os.path.normpath(options.convertlocation + "/")) |
|
212 create_convertprojectml_file(options.configuration, |
|
213 conv_project_filename, |
|
214 options.project + "/"+ options.convertlocation + "/" , |
|
215 layer_list, |
|
216 metadata_list, |
|
217 source_config.get_name()) |
|
218 |
|
219 target_storage.import_resources([os.path.normpath(options.convertlocation + "/" +conv_project_filename)], source_storage) |
|
220 except Exception ,e: |
|
221 print "Could not create Zip archive: %s" % e |
|
222 sys.exit(2) |
|
223 |
|
224 try: |
|
225 target_storage.save() |
|
226 source_project.close() |
|
227 target_project.close() |
|
228 |
|
229 conv_path = (os.path.normpath(options.project + "/" + options.convertlocation + "/")) |
|
230 conv_file_path = (os.path.normpath(conv_path + "/" + conv_project_filename)) |
|
231 |
|
232 os.remove(conv_file_path) |
|
233 os.removedirs(conv_path) |
|
234 except: |
|
235 pass |
|
236 |
|
237 |
|
238 |
|
239 if __name__ == "__main__": |
|
240 main() |