99
1010import argparse
1111import plistlib
12- import sys
13- import re
1412from datetime import datetime
1513from xml .parsers .expat import ExpatError
1614
3028 "date" : datetime ,
3129}
3230
31+ # List keys and their expected item types
32+ PFM_LIST_TYPES = {
33+ "pfm_allowed_file_types" : str ,
34+ "pfm_conditionals" : dict ,
35+ "pfm_exclude" : dict ,
36+ "pfm_subkeys" : dict ,
37+ "pfm_target_conditions" : str ,
38+ "pfm_targets" : str ,
39+ "pfm_upk_input_keys" : str ,
40+ "pfm_n_platforms" : str ,
41+ "pfm_platforms" : str ,
42+ "pfm_range_list_titles" : str ,
43+ }
44+
3345
3446def build_argument_parser ():
3547 """Build and return the argument parser."""
@@ -137,32 +149,18 @@ def validate_manifest_key_types(manifest, filename):
137149def validate_list_item_types (manifest , filename ):
138150 """Validation of list member items."""
139151
140- # manifest list names and their member item types
141- item_types = {
142- "pfm_allowed_file_types" : str ,
143- "pfm_conditionals" : dict ,
144- "pfm_exclude" : dict ,
145- "pfm_subkeys" : dict ,
146- "pfm_target_conditions" : str ,
147- "pfm_targets" : str ,
148- "pfm_upk_input_keys" : str ,
149- "pfm_n_platforms" : str ,
150- "pfm_platforms" : str ,
151- "pfm_range_list_titles" : str ,
152- }
153-
154152 passed = True
155- for name in item_types :
153+ for name in PFM_LIST_TYPES :
156154 if name in manifest :
157155 try :
158156 actual_type = type (manifest [name ][0 ])
159157 except IndexError :
160158 # Probably an empty array; no way to validate items
161159 continue
162- if actual_type is not item_types [name ]:
160+ if actual_type is not PFM_LIST_TYPES [name ]:
163161 print (
164162 '{}: "{}" items should be type {}, not type {}' .format (
165- filename , name , item_types [name ], actual_type
163+ filename , name , PFM_LIST_TYPES [name ], actual_type
166164 )
167165 )
168166 passed = False
@@ -274,17 +272,28 @@ def validate_pfm_targets(subkey, filename):
274272 return passed
275273
276274
277- def validate_pfm_default_and_placeholder (subkey , filename ):
278- """Ensure that default and placeholder values have the expected type."""
275+ def validate_pfm_default (subkey , filename ):
276+ """Ensure that default values have the expected type."""
279277 passed = True
280278
281279 if "pfm_type" in subkey :
282- for test_key in ("pfm_default" , "pfm_value_placeholder" ):
280+ # TODO: Should we validate pfm_value_placeholder here too?
281+ for test_key in ("pfm_default" ,):
283282 if test_key in subkey :
284- if type (subkey [test_key ]) != PFM_TYPES [subkey ["pfm_type" ]]:
283+ if PFM_TYPES [subkey ["pfm_type" ]] == list :
284+ desired_type = type (subkey ["pfm_subkeys" ][0 ])
285+ else :
286+ try :
287+ desired_type = PFM_TYPES [subkey ["pfm_type" ]]
288+ except IndexError :
289+ # Unknown desired type
290+ continue
291+ if type (subkey [test_key ]) != desired_type :
285292 print (
286- ' {}: test_key value should be type "{}" , not type " {}"' .format (
293+ " {}: {} value for {} should be {} , not {}" .format (
287294 filename ,
295+ test_key ,
296+ subkey .get ("pfm_name" ),
288297 PFM_TYPES [subkey ["pfm_type" ]],
289298 type (subkey [test_key ]),
290299 )
@@ -294,6 +303,26 @@ def validate_pfm_default_and_placeholder(subkey, filename):
294303 return passed
295304
296305
306+ def validate_urls (subkey , filename ):
307+ """Ensure that URL values are actual URLs."""
308+ passed = True
309+
310+ url_keys = ("pfm_app_url" , "pfm_documentation_url" )
311+ for url_key in url_keys :
312+ if url_key in subkey :
313+ if not subkey [url_key ].startswith ("http" ):
314+ print (
315+ "{}: {} value doesn't look like a URL: {}" .format (
316+ filename ,
317+ url_key ,
318+ subkey [url_key ],
319+ )
320+ )
321+ passed = False
322+
323+ return passed
324+
325+
297326def validate_subkeys (subkeys , filename ):
298327 """Given a list of subkeys, run validation on their contents."""
299328 passed = True
@@ -324,13 +353,13 @@ def validate_subkeys(subkeys, filename):
324353 if not validate_pfm_targets (subkey , filename ):
325354 passed = False
326355
327- # Check default and placeholder values to ensure consistent type
328- if not validate_pfm_default_and_placeholder (subkey , filename ):
356+ # Check default values to ensure consistent type
357+ if not validate_pfm_default (subkey , filename ):
329358 passed = False
330359
331- # TODO: Ensure pfm_placeholder_value is consistent with pfm_type
332-
333- # TODO: Ensure pfm_documentation_url is a URL
360+ # Validate URLs
361+ if not validate_urls ( subkey , filename ):
362+ passed = False
334363
335364 # TODO: Validate pfm_conditionals
336365 # https://github.com/ProfileCreator/ProfileManifests/wiki/Manifest-Format#example-conditions--exclusions
0 commit comments