Skip to content

Commit e0bcbf4

Browse files
committed
Update version to 2.0.2
Add try/catch to handle when ABOUT files don't have dje_license_name. Add code to handle long path specifically in windows (read and write) See See https://msdn.microsoft.com/en-us/library/aa365247.aspx Add code to strip the UNC_Prefix for path location the in the error log. Create test for long path handling. Add code to strip the quote from the api input.
1 parent 9cedb6d commit e0bcbf4

File tree

4 files changed

+77
-10
lines changed

4 files changed

+77
-10
lines changed

about_code_tool/about.py

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,24 @@
3232
import csv
3333
from datetime import datetime
3434
from email.parser import HeaderParser
35-
from os.path import basename, dirname, join, normpath, realpath
3635
import errno
3736
import httplib
3837
import logging
38+
import ntpath
3939
import optparse
4040
import os
41+
from os.path import basename, dirname, join, normpath, realpath
4142
import posixpath
4243
import socket
4344
import string
4445
import sys
4546
import urlparse
46-
import ntpath
4747

4848

49-
__version__ = '2.0.1'
49+
on_windows = 'win32' in sys.platform
50+
UNC_PREFIX = u'\\\\?\\'
51+
52+
__version__ = '2.0.2'
5053

5154
# See http://dejacode.org
5255
__about_spec_version__ = '1.0'
@@ -1082,7 +1085,10 @@ def get_dje_license_name(self):
10821085
"""
10831086
Return the about object's dje_license_name.
10841087
"""
1085-
return self.parsed.get('dje_license_name', '')
1088+
try:
1089+
return self.parsed.get('dje_license_name', '')
1090+
except:
1091+
return ''
10861092

10871093
def check_invalid_chars(field_name, line):
10881094
"""
@@ -1104,6 +1110,8 @@ def check_invalid_chars(field_name, line):
11041110
warnings = Warn(IGNORED, field_name, line, msg)
11051111
return invalid_chars, warnings
11061112

1113+
def posix_unc_prefix():
1114+
return posix_path(u'\\\\?\\')
11071115

11081116
class Collector(object):
11091117
"""
@@ -1144,6 +1152,23 @@ def collect(location):
11441152
"""
11451153
# FIXME: we should not accept both a file and dir location as input
11461154
paths = []
1155+
1156+
if on_windows:
1157+
location = unicode(location)
1158+
"""
1159+
Convert a location to an absolute Window UNC path to support long paths
1160+
on Windows. Return the location unchanged if not on Windows.
1161+
See https://msdn.microsoft.com/en-us/library/aa365247.aspx
1162+
"""
1163+
if on_windows and not location.startswith(UNC_PREFIX):
1164+
location = UNC_PREFIX + os.path.abspath(location)
1165+
location = os.path.expanduser(location)
1166+
location = os.path.expandvars(location)
1167+
location = os.path.normpath(location)
1168+
location = os.path.abspath(location)
1169+
1170+
assert os.path.exists(location)
1171+
11471172
if location:
11481173
if os.path.isfile(location) and is_about_file(location):
11491174
paths.append(location)
@@ -1241,6 +1266,9 @@ def get_about_context(self, about_object):
12411266
if '\n' in about_object.get_dje_license_name():
12421267
msg = ('Multiple licenses is not supported. '
12431268
'Skipping License generation.')
1269+
if on_windows:
1270+
if about_object.location.startswith(posix_unc_prefix()):
1271+
about_object.location = about_object.location.strip(posix_unc_prefix())
12441272
err = Error(GENATTRIB, 'dje_license',
12451273
about_object.location, msg)
12461274
self.genattrib_errors.append(err)
@@ -1258,6 +1286,9 @@ def get_about_context(self, about_object):
12581286
and not '\n' in about_object.get_dje_license_name():
12591287
msg = ('No license_text found. '
12601288
'Skipping License generation.')
1289+
if on_windows:
1290+
if about_object.location.startswith(posix_unc_prefix()):
1291+
about_object.location = about_object.location.strip(posix_unc_prefix())
12611292
err = Error(GENATTRIB, 'license_text_file',
12621293
about_object.location, msg)
12631294
self.genattrib_errors.append(err)
@@ -1314,6 +1345,9 @@ def generate_attribution(self, template_path=None, limit_to=None, verification=N
13141345
break
13151346

13161347
if not component_exist:
1348+
if on_windows:
1349+
if self.location.startswith(posix_unc_prefix()):
1350+
self.location = self.location.strip(posix_unc_prefix())
13171351
loc = self.location + component
13181352
msg = ('The requested ABOUT file: %r does not exist. '
13191353
'No attribution generated for this file.' % loc)
@@ -1364,6 +1398,9 @@ def check_paths(self, paths):
13641398
for path in paths:
13651399
path = posix_path(path)
13661400
afp = join(self.location, path)
1401+
if on_windows:
1402+
if afp.startswith(posix_unc_prefix()):
1403+
afp = afp.strip(posix_unc_prefix())
13671404
msg = ('The requested ABOUT file: %(afp)r does not exist. '
13681405
'No attribution generated for this file.' % locals())
13691406
err = Error(GENATTRIB, 'about_file', path, msg)

about_code_tool/genabout.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
import about
4343

44-
__version__ = '2.0.0'
44+
__version__ = '2.0.2'
4545

4646
__copyright__ = """
4747
Copyright (c) 2013-2014 nexB Inc. All rights reserved.
@@ -614,6 +614,8 @@ def format_output(input_list):
614614
@staticmethod
615615
def write_output(output):
616616
for about_file_location, context in output:
617+
if about.on_windows:
618+
about_file_location = about.UNC_PREFIX + os.path.abspath(about_file_location)
617619
if _exists(about_file_location):
618620
os.remove(about_file_location)
619621
with open(about_file_location, 'wb') as output_file:
@@ -855,6 +857,10 @@ def main(parser, options, args):
855857
sys.exit(errno.EINVAL)
856858

857859
if gen_license:
860+
# Strip the ' and " for api_url, api_username and api_key from input
861+
api_url = api_url.strip("'").strip("\"")
862+
api_username = api_username.strip("'").strip("\"")
863+
api_key = api_key.strip("'").strip("\"")
858864
dje_license_dict = gen.pre_process_and_dje_license_dict(input_list,
859865
api_url,
860866
api_username,

about_code_tool/genattrib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
logger.addHandler(handler)
4444
file_logger = logging.getLogger(__name__ + '_file')
4545

46-
__version__ = '2.0.0'
46+
__version__ = '2.0.2'
4747

4848
__about_spec_version__ = '1.0.0' # See http://dejacode.org
4949

about_code_tool/tests/test_about.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@
2727
from os.path import abspath, dirname, join, split
2828

2929
from about_code_tool import about
30+
from pip._vendor.distlib.wheel import to_posix
31+
from about_code_tool.about import on_windows
3032

3133

3234
TESTDATA_DIR = join(abspath(dirname(__file__)), 'testdata')
35+
UNC_PREFIX = u'\\\\?\\'
3336

3437

3538
def create_dir(location):
@@ -134,11 +137,16 @@ def test_header_row_in_csv_output(self):
134137

135138
def test_collect_can_collect_a_directory_tree(self):
136139
test_dir = 'about_code_tool/tests/testdata/DateTest'
137-
expected = [('about_code_tool/tests/testdata/DateTest'
138-
'/non-supported_date_format.ABOUT'),
139-
('about_code_tool/tests/testdata/DateTest'
140-
'/supported_date_format.ABOUT')]
140+
expected = [(os.path.abspath('about_code_tool/tests/testdata/DateTest'
141+
'/non-supported_date_format.ABOUT')),
142+
(os.path.abspath('about_code_tool/tests/testdata/DateTest'
143+
'/supported_date_format.ABOUT'))]
141144
result = about.Collector.collect(test_dir)
145+
if on_windows:
146+
expected = [(to_posix(UNC_PREFIX + os.path.abspath('about_code_tool/tests/testdata/DateTest'
147+
'/non-supported_date_format.ABOUT'))),
148+
(to_posix(UNC_PREFIX + os.path.abspath('about_code_tool/tests/testdata/DateTest'
149+
'/supported_date_format.ABOUT')))]
142150
self.assertEqual(sorted(expected), sorted(result))
143151

144152
def test_collect_can_collect_a_single_file(self):
@@ -147,8 +155,24 @@ def test_collect_can_collect_a_single_file(self):
147155
expected = ['about_code_tool/tests/testdata/thirdparty'
148156
'/django_snippets_2413.ABOUT']
149157
result = about.Collector.collect(test_file)
158+
if on_windows:
159+
expected = [to_posix(UNC_PREFIX + os.path.abspath('about_code_tool/tests/testdata/thirdparty'
160+
'/django_snippets_2413.ABOUT'))]
150161
self.assertEqual(expected, result)
151162

163+
def test_collect_can_collect_a_long_directory_tree(self):
164+
test_dir = 'about_code_tool/tests/testdata/longpath/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/'
165+
expected = [('about_code_tool/tests/testdata/longpath/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1'
166+
'/non-supported_date_format.ABOUT')]
167+
result = about.Collector.collect(test_dir)
168+
if on_windows:
169+
# For some reasons, the os.path.abspath doesn't work if I have long
170+
# path in the parameter. Therefore, I just append to long path
171+
# after the os.path.abspath()
172+
expected = [to_posix(UNC_PREFIX + os.path.abspath('about_code_tool') + '/tests/testdata/longpath/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1/longpath1'
173+
'/non-supported_date_format.ABOUT')]
174+
self.assertEqual(sorted(expected), sorted(result))
175+
152176
def test_collector_errors_encapsulation(self):
153177
test_file = 'about_code_tool/tests/testdata/DateTest'
154178
collector = about.Collector(test_file)

0 commit comments

Comments
 (0)