|
36 | 36 | import posixpath |
37 | 37 | import traceback |
38 | 38 |
|
39 | | -from attributecode.util import python2 |
| 39 | +from attributecode.util import python2, to_posix |
40 | 40 |
|
41 | 41 | if python2: # pragma: nocover |
42 | 42 | from itertools import izip_longest as zip_longest # NOQA |
|
63 | 63 | from attributecode.util import add_unc |
64 | 64 | from attributecode.util import boolean_fields |
65 | 65 | from attributecode.util import copy_license_notice_files |
| 66 | +from attributecode.util import copy_file |
66 | 67 | from attributecode.util import csv |
67 | 68 | from attributecode.util import file_fields |
68 | 69 | from attributecode.util import filter_errors |
69 | 70 | from attributecode.util import is_valid_name |
70 | 71 | from attributecode.util import on_windows |
| 72 | +from attributecode.util import norm |
71 | 73 | from attributecode.util import replace_tab_with_spaces |
72 | 74 | from attributecode.util import wrap_boolean_value |
73 | 75 | from attributecode.util import UNC_PREFIX |
@@ -876,7 +878,7 @@ def hydrate(self, fields): |
876 | 878 | # this is a special attribute, skip entirely |
877 | 879 | continue |
878 | 880 |
|
879 | | - # A field that has been alredy processed ... and has a value |
| 881 | + # A field that has been already processed ... and has a value |
880 | 882 | previous_value = seen_fields.get(name) |
881 | 883 | if previous_value: |
882 | 884 | if value != previous_value: |
@@ -942,8 +944,9 @@ def process(self, fields, about_file_path, running_inventory=False, |
942 | 944 | errors = self.hydrate(fields) |
943 | 945 | # We want to copy the license_files before the validation |
944 | 946 | if reference_dir: |
945 | | - copy_license_notice_files( |
| 947 | + copy_err = copy_license_notice_files( |
946 | 948 | fields, base_dir, reference_dir, afp) |
| 949 | + errors.extend(copy_err) |
947 | 950 |
|
948 | 951 | # TODO: why? we validate all fields, not only these hydrated |
949 | 952 | validation_errors = validate_fields( |
@@ -1289,6 +1292,113 @@ def get_field_names(abouts): |
1289 | 1292 | return fields |
1290 | 1293 |
|
1291 | 1294 |
|
| 1295 | +def copy_redist_src(copy_list, location, output, with_structure): |
| 1296 | + """ |
| 1297 | + Given a list of files/directories and copy to the destination |
| 1298 | + """ |
| 1299 | + errors = [] |
| 1300 | + for from_path in copy_list: |
| 1301 | + norm_from_path = norm(from_path) |
| 1302 | + relative_from_path = norm_from_path.partition(util.norm(location))[2] |
| 1303 | + # Need to strip the '/' to use the join |
| 1304 | + if relative_from_path.startswith('/'): |
| 1305 | + relative_from_path = relative_from_path.partition('/')[2] |
| 1306 | + # Get the directory name of the output path |
| 1307 | + if with_structure: |
| 1308 | + output_dir = os.path.dirname(os.path.join(output, util.norm(relative_from_path))) |
| 1309 | + else: |
| 1310 | + output_dir = output |
| 1311 | + err = copy_file(from_path, output_dir) |
| 1312 | + if err: |
| 1313 | + errors.extend(err) |
| 1314 | + return errors |
| 1315 | + |
| 1316 | + |
| 1317 | +def get_copy_list(abouts, location): |
| 1318 | + """ |
| 1319 | + Return a list of files/directories that need to be copied (and error if any) |
| 1320 | + This is a summary list in a sense that if a directory is already in the list, |
| 1321 | + its children directories/files will not be included in the list regardless if |
| 1322 | + they have 'redistribute' flagged. The reason for this is we want to capture |
| 1323 | + the error/warning if existence files/directories already exist. However, if |
| 1324 | + we don't have this "summarized" list, and we've copied a file (with directory structure) |
| 1325 | + and then later on this file's parent directory also need to be copied, then |
| 1326 | + it will prompt warning as the directory that need to be copied is already exist. |
| 1327 | + Technically, this is correct, but it leads to confusion. Therefore, we want to |
| 1328 | + create a summarized list to avoid this kind of confusion. |
| 1329 | + """ |
| 1330 | + errors = [] |
| 1331 | + copy_list = [] |
| 1332 | + dir_list = [] |
| 1333 | + file_list = [] |
| 1334 | + for about in abouts: |
| 1335 | + if about.redistribute.value: |
| 1336 | + file_exist = True |
| 1337 | + for e in about.errors: |
| 1338 | + if 'Field about_resource' in e.message and 'not found' in e.message: |
| 1339 | + msg = e.message + u' and cannot be copied.' |
| 1340 | + errors.append(Error(CRITICAL, msg)) |
| 1341 | + file_exist = False |
| 1342 | + continue |
| 1343 | + if file_exist: |
| 1344 | + for k in about.about_resource.value: |
| 1345 | + from_path = about.about_resource.value.get(k) |
| 1346 | + if on_windows: |
| 1347 | + norm_from_path = norm(from_path) |
| 1348 | + else: |
| 1349 | + norm_from_path = os.path.normpath(from_path) |
| 1350 | + # Get the relative path |
| 1351 | + relative_from_path = norm_from_path.partition(util.norm(location))[2] |
| 1352 | + if os.path.isdir(from_path): |
| 1353 | + if not dir_list: |
| 1354 | + dir_list.append(relative_from_path) |
| 1355 | + else: |
| 1356 | + handled = False |
| 1357 | + for dir in dir_list: |
| 1358 | + # The dir is a parent of the relative_from_path |
| 1359 | + if dir in relative_from_path: |
| 1360 | + handled = True |
| 1361 | + continue |
| 1362 | + # The relative_from_path is the parent of the dir |
| 1363 | + # We need to update the dir_list |
| 1364 | + if relative_from_path in dir: |
| 1365 | + dir_list.remove(dir) |
| 1366 | + dir_list.append(relative_from_path) |
| 1367 | + handled = True |
| 1368 | + continue |
| 1369 | + if not handled: |
| 1370 | + dir_list.append(relative_from_path) |
| 1371 | + else: |
| 1372 | + # Check if the file is from "root" |
| 1373 | + # If the file is at root level, it'll add to the copy_list |
| 1374 | + if not os.path.dirname(relative_from_path) == '/': |
| 1375 | + file_list.append(relative_from_path) |
| 1376 | + else: |
| 1377 | + copy_list.append(from_path) |
| 1378 | + |
| 1379 | + for dir in dir_list: |
| 1380 | + for f in file_list: |
| 1381 | + # The file is already in one of copied directories |
| 1382 | + if dir in f: |
| 1383 | + file_list.remove(f) |
| 1384 | + continue |
| 1385 | + if dir.startswith('/'): |
| 1386 | + dir = dir.partition('/')[2] |
| 1387 | + absolute_path = os.path.join(location, dir) |
| 1388 | + if on_windows: |
| 1389 | + absolute_path = add_unc(absolute_path) |
| 1390 | + copy_list.append(absolute_path) |
| 1391 | + |
| 1392 | + for f in file_list: |
| 1393 | + if f.startswith('/'): |
| 1394 | + f = f.partition('/')[2] |
| 1395 | + absolute_path = os.path.join(location, f) |
| 1396 | + if on_windows: |
| 1397 | + absolute_path = add_unc(absolute_path) |
| 1398 | + copy_list.append(absolute_path) |
| 1399 | + |
| 1400 | + return copy_list, errors |
| 1401 | + |
1292 | 1402 | def about_object_to_list_of_dictionary(abouts): |
1293 | 1403 | """ |
1294 | 1404 | Convert About objects to a list of dictionaries |
|
0 commit comments