2121import codecs
2222from collections import OrderedDict
2323import logging
24- import posixpath
24+ from posixpath import basename , dirname , exists , join , normpath
2525import sys
2626
2727if sys .version_info [0 ] < 3 :
3939from attributecode import util
4040from attributecode .util import add_unc
4141from attributecode .util import to_posix
42+ from attributecode .util import UNC_PREFIX_POSIX
4243
4344
4445LOG_FILENAME = 'error.log'
@@ -160,7 +161,7 @@ def load_inventory(location, base_dir, license_notice_text_location=None,
160161 continue
161162 else :
162163 afp = util .to_posix (afp )
163- loc = posixpath . join (base_dir , afp )
164+ loc = join (base_dir , afp )
164165 about = model .About (about_file_path = afp )
165166 about .location = loc
166167 running_inventory = False
@@ -177,15 +178,17 @@ def load_inventory(location, base_dir, license_notice_text_location=None,
177178 return errors , abouts
178179
179180
180- def generate (location , base_dir , license_notice_text_location = None ,
181- fetch_license = False , policy = None , conf_location = None ,
182- with_empty = False , with_absent = False , use_mapping = False ):
181+ def generate (location , base_dir , validate_about_resource = False ,
182+ license_notice_text_location = None , fetch_license = False , policy = None ,
183+ conf_location = None , with_empty = False , with_absent = False ,
184+ use_mapping = False ):
183185 """
184186 Load ABOUT data from a CSV inventory at `location`. Write ABOUT files to
185187 base_dir using policy flags and configuration file at conf_location.
186188 Policy defines which action to take for merging or overwriting fields and
187189 files. Return errors and about objects.
188190 """
191+ not_exist_errors = []
189192 api_url = ''
190193 api_key = ''
191194 gen_license = False
@@ -214,7 +217,7 @@ def generate(location, base_dir, license_notice_text_location=None,
214217 for about in abouts :
215218 if about .about_file_path .startswith ('/' ):
216219 about .about_file_path = about .about_file_path .lstrip ('/' )
217- dump_loc = posixpath . join (bdir , about .about_file_path .lstrip ('/' ))
220+ dump_loc = join (bdir , about .about_file_path .lstrip ('/' ))
218221
219222 # The following code is to check if there is any directory ends with spaces
220223 split_path = about .about_file_path .split ('/' )
@@ -234,25 +237,41 @@ def generate(location, base_dir, license_notice_text_location=None,
234237
235238 try :
236239 # Generate value for 'about_resource' if it does not exist
237- # Note: The `about_resource` and `about_resource_path` have
238- # OrderDict as the value type from PathField
240+ # Note: The `about_resource` is in ListField class
241+ # and `about_resource_path` is in AboutResourceField class
239242 if not about .about_resource .value :
240- about .about_resource .value = OrderedDict ()
243+ # about.about_resource.value = OrderedDict()
241244 if about .about_file_path .endswith ('/' ):
242- about .about_resource .value [ u'.' ] = None
245+ about .about_resource .value . append ( u'.' )
243246 about .about_resource .original_value = u'.'
244247 else :
245- about .about_resource .value [ posixpath . basename (about .about_file_path )] = None
246- about .about_resource .original_value = posixpath . basename (about .about_file_path )
248+ about .about_resource .value . append ( basename (about .about_file_path ))
249+ about .about_resource .original_value = basename (about .about_file_path )
247250 about .about_resource .present = True
248251
249252 # Generate value for 'about_resource_path' if it does not exist
250253 # Basically, this should be the same as the 'about_resource'
251254 if not about .about_resource_path .value :
252255 about .about_resource_path .value = OrderedDict ()
253- about .about_resource_path .value = about .about_resource .value
256+ for about_resource_value in about .about_resource .value :
257+ about .about_resource_path .value [about_resource_value ] = None
254258 about .about_resource_path .present = True
255-
259+ if validate_about_resource :
260+ # Check for the existence of the about_resource
261+ # If the input already have the about_resource_path field, it will
262+ # be validated when creating the about object
263+ loc = util .to_posix (dump_loc )
264+ about_file_loc = loc
265+ for about_resource_value in about .about_resource_path .value :
266+ path = join (dirname (util .to_posix (about_file_loc )),
267+ about_resource_value )
268+ if not exists (path ):
269+ path = util .to_posix (path .strip (UNC_PREFIX_POSIX ))
270+ path = normpath (path )
271+ msg = (u'The reference file: '
272+ u'%(path)s '
273+ u'does not exist' % locals ())
274+ not_exist_errors .append (msg )
256275 if gen_license :
257276 about .license_file .value = OrderedDict ()
258277 # Write generated LICENSE file
@@ -276,21 +295,15 @@ def generate(location, base_dir, license_notice_text_location=None,
276295 if about .license_name .value :
277296 about .license_name .present = True
278297
279- # Write the ABOUT file and check does the referenced file exist
280- # This function is not purposed to throw error. However, since I've commented
281- # out the error throwing in FileTextField (See model.py), I have add error handling
282- # in this function. This error handling should be removed once the fetch-license option
283- # is treated as a subcommand.
284- not_exist_errors = about .dump (dump_loc ,
285- with_empty = with_empty ,
286- with_absent = with_absent )
298+ # Write the ABOUT files
299+ about .dump (dump_loc , with_empty = with_empty , with_absent = with_absent )
300+
287301 file_field_not_exist_errors = check_file_field_exist (about , dump_loc )
288302
289303 for e in not_exist_errors :
290304 errors .append (Error (ERROR , e ))
291305 for e in file_field_not_exist_errors :
292306 errors .append (Error (ERROR , e ))
293-
294307 except Exception as e :
295308 # only keep the first 100 char of the exception
296309 emsg = repr (e )[:100 ]
0 commit comments