pkgtools/url2pkg: improve Python implementation * verbose mode no longer crashes * licenses and other variables are copied to the package Makefile * several more automatic testsdiff -r1.1 -r1.2 pkgsrc/pkgtools/url2pkg/files/url2pkg.py
(rillig)
@@ -1,15 +1,15 @@ | @@ -1,15 +1,15 @@ | |||
1 | #! @PYTHONBIN@ | 1 | #! @PYTHONBIN@ | |
2 | # $NetBSD: url2pkg.py,v 1.1 2019/10/03 09:37:41 rillig Exp $ | 2 | # $NetBSD: url2pkg.py,v 1.2 2019/10/03 12:52:54 rillig Exp $ | |
3 | 3 | |||
4 | # Copyright (c) 2019 The NetBSD Foundation, Inc. | 4 | # Copyright (c) 2019 The NetBSD Foundation, Inc. | |
5 | # All rights reserved. | 5 | # All rights reserved. | |
6 | # | 6 | # | |
7 | # This code is derived from software contributed to The NetBSD Foundation | 7 | # This code is derived from software contributed to The NetBSD Foundation | |
8 | # by Roland Illig. | 8 | # by Roland Illig. | |
9 | # | 9 | # | |
10 | # Redistribution and use in source and binary forms, with or without | 10 | # Redistribution and use in source and binary forms, with or without | |
11 | # modification, are permitted provided that the following conditions | 11 | # modification, are permitted provided that the following conditions | |
12 | # are met: | 12 | # are met: | |
13 | # 1. Redistributions of source code must retain the above copyright | 13 | # 1. Redistributions of source code must retain the above copyright | |
14 | # notice, this list of conditions and the following disclaimer. | 14 | # notice, this list of conditions and the following disclaimer. | |
15 | # 2. Redistributions in binary form must reproduce the above copyright | 15 | # 2. Redistributions in binary form must reproduce the above copyright | |
@@ -40,36 +40,37 @@ from typing import Callable, Dict, Itera | @@ -40,36 +40,37 @@ from typing import Callable, Dict, Itera | |||
40 | 40 | |||
41 | def cvsid(fmt: str) -> str: | 41 | def cvsid(fmt: str) -> str: | |
42 | return fmt % ('$' + 'NetBSD$') | 42 | return fmt % ('$' + 'NetBSD$') | |
43 | 43 | |||
44 | 44 | |||
45 | class Config: | 45 | class Config: | |
46 | 46 | |||
47 | def __init__(self): | 47 | def __init__(self): | |
48 | self.make = '@MAKE@' | 48 | self.make = '@MAKE@' | |
49 | self.libdir = '@LIBDIR@' | 49 | self.libdir = '@LIBDIR@' | |
50 | self.perl5 = '@PERL5@' | 50 | self.perl5 = '@PERL5@' | |
51 | self.pkgsrcdir = '@PKGSRCDIR@' | 51 | self.pkgsrcdir = '@PKGSRCDIR@' | |
52 | self.pythonbin = '@PYTHONBIN@' | 52 | self.pythonbin = '@PYTHONBIN@' | |
53 | self.pkgdir = '.' # only overridable for tests | |||
53 | self.verbose = False | 54 | self.verbose = False | |
54 | 55 | |||
55 | 56 | |||
56 | config = Config() | 57 | config = Config() | |
57 | distname = '' | 58 | distname = '' | |
58 | 59 | |||
59 | 60 | |||
60 | def debug(fmt: str, *args): | 61 | def debug(fmt: str, *args): | |
61 | if config.verbose: | 62 | if config.verbose: | |
62 | msg = fmt % map(repr, args) | 63 | msg = fmt.format(*map(repr, args)) if len(args) else fmt | |
63 | sys.stderr.write('url2pkg: %s\n' % msg) | 64 | sys.stderr.write('url2pkg: %s\n' % msg) | |
64 | 65 | |||
65 | 66 | |||
66 | def run_editor(fname: str, lineno: int): | 67 | def run_editor(fname: str, lineno: int): | |
67 | editor = os.getenv('PKGEDITOR') or os.getenv('EDITOR') or 'vi' | 68 | editor = os.getenv('PKGEDITOR') or os.getenv('EDITOR') or 'vi' | |
68 | 69 | |||
69 | args: List[str] = [editor] | 70 | args: List[str] = [editor] | |
70 | if re.search(editor, r'(^|/)(mcedit|nano|pico|vi|vim)$'): | 71 | if re.search(editor, r'(^|/)(mcedit|nano|pico|vi|vim)$'): | |
71 | args.append(f'+{lineno}') | 72 | args.append(f'+{lineno}') | |
72 | args.append(fname) | 73 | args.append(fname) | |
73 | 74 | |||
74 | code = subprocess.check_call(args) | 75 | code = subprocess.check_call(args) | |
75 | 76 | |||
@@ -209,30 +210,30 @@ def generate_initial_package_Makefile_li | @@ -209,30 +210,30 @@ def generate_initial_package_Makefile_li | |||
209 | ) | 210 | ) | |
210 | 211 | |||
211 | lines.add('# url2pkg-marker (please do not remove this line.)') | 212 | lines.add('# url2pkg-marker (please do not remove this line.)') | |
212 | lines.add('.include "../../mk/bsd.pkg.mk"') | 213 | lines.add('.include "../../mk/bsd.pkg.mk"') | |
213 | 214 | |||
214 | return lines | 215 | return lines | |
215 | 216 | |||
216 | 217 | |||
217 | def generate_initial_package(url): | 218 | def generate_initial_package(url): | |
218 | try: | 219 | try: | |
219 | os.rename('Makefile', 'Makefile-url2pkg.bak') | 220 | os.rename('Makefile', 'Makefile-url2pkg.bak') | |
220 | except OSError: | 221 | except OSError: | |
221 | pass | 222 | pass | |
222 | generate_initial_package_Makefile_lines(url).write_to('Makefile') | 223 | generate_initial_package_Makefile_lines(url).write_to(config.pkgdir + '/Makefile') | |
223 | Lines(cvsid('@comment %s')).write_to('PLIST') | 224 | Lines(cvsid('@comment %s')).write_to(config.pkgdir + '/PLIST') | |
224 | Lines().write_to('DESCR') | 225 | Lines().write_to(config.pkgdir + '/DESCR') | |
225 | run_editor('Makefile', 5) | 226 | run_editor(config.pkgdir + '/Makefile', 5) | |
226 | 227 | |||
227 | bmake('distinfo') | 228 | bmake('distinfo') | |
228 | bmake('extract') | 229 | bmake('extract') | |
229 | 230 | |||
230 | 231 | |||
231 | class Var: | 232 | class Var: | |
232 | """ A variable assignment for the package Makefile """ | 233 | """ A variable assignment for the package Makefile """ | |
233 | 234 | |||
234 | def __init__(self, name: str, op: str, value: str): | 235 | def __init__(self, name: str, op: str, value: str): | |
235 | self.name = name | 236 | self.name = name | |
236 | self.op = op | 237 | self.op = op | |
237 | self.value = value | 238 | self.value = value | |
238 | 239 | |||
@@ -261,35 +262,35 @@ class Varassign: | @@ -261,35 +262,35 @@ class Varassign: | |||
261 | def __init__(self, index: int, varname: str, op: str, indent: str, | 262 | def __init__(self, index: int, varname: str, op: str, indent: str, | |
262 | value: str, space_after_value: str, comment: str): | 263 | value: str, space_after_value: str, comment: str): | |
263 | self.index = index | 264 | self.index = index | |
264 | self.varname = varname | 265 | self.varname = varname | |
265 | self.op = op | 266 | self.op = op | |
266 | self.indent = indent | 267 | self.indent = indent | |
267 | self.value = value | 268 | self.value = value | |
268 | self.space_after_value = space_after_value | 269 | self.space_after_value = space_after_value | |
269 | self.comment = comment | 270 | self.comment = comment | |
270 | 271 | |||
271 | 272 | |||
272 | def find_package(pkgbase: str) -> str: | 273 | def find_package(pkgbase: str) -> str: | |
273 | candidates = glob.glob(config.pkgsrcdir + '/*/' + pkgbase) | 274 | candidates = glob.glob(config.pkgsrcdir + '/*/' + pkgbase) | |
274 | debug('candidates for package %s are %s', pkgbase, candidates) | 275 | debug('candidates for package {0} are {1}', pkgbase, candidates) | |
275 | if len(candidates) != 1: | 276 | if len(candidates) != 1: | |
276 | return '' | 277 | return '' | |
277 | return candidates[0].replace(config.pkgsrcdir, '../..') | 278 | return candidates[0].replace(config.pkgsrcdir, '../..') | |
278 | 279 | |||
279 | 280 | |||
280 | def bmake(*args: str) -> None: | 281 | def bmake(*args: str) -> None: | |
281 | debug('running bmake %s', args) | 282 | debug('running bmake {0}', args) | |
282 | subprocess.check_call([config.make] + list(args)) | 283 | subprocess.check_call([config.make] + list(args), cwd=config.pkgdir) | |
283 | 284 | |||
284 | 285 | |||
285 | def show_var(varname: str) -> str: | 286 | def show_var(varname: str) -> str: | |
286 | output = subprocess.check_output((config.make, 'show-var', 'VARNAME=' + varname)) | 287 | output = subprocess.check_output((config.make, 'show-var', 'VARNAME=' + varname)) | |
287 | return output.decode('utf-8').strip() | 288 | return output.decode('utf-8').strip() | |
288 | 289 | |||
289 | 290 | |||
290 | class Lines: | 291 | class Lines: | |
291 | 292 | |||
292 | def __init__(self, *lines: str) -> None: | 293 | def __init__(self, *lines: str) -> None: | |
293 | self.lines = [] | 294 | self.lines = [] | |
294 | for line in lines: | 295 | for line in lines: | |
295 | self.add(line) | 296 | self.add(line) | |
@@ -336,36 +337,36 @@ class Lines: | @@ -336,36 +337,36 @@ class Lines: | |||
336 | if var.value != '': | 337 | if var.value != '': | |
337 | tabs = (width - len(var.name) - len(var.op) + 7) // 8 | 338 | tabs = (width - len(var.name) - len(var.op) + 7) // 8 | |
338 | self.add(var.name + var.op + '\t' * tabs + var.value) | 339 | self.add(var.name + var.op + '\t' * tabs + var.value) | |
339 | self.add('') | 340 | self.add('') | |
340 | 341 | |||
341 | def unique_varassign(self, varname: str) -> Optional[Varassign]: | 342 | def unique_varassign(self, varname: str) -> Optional[Varassign]: | |
342 | varassigns = self.all_varassigns(varname) | 343 | varassigns = self.all_varassigns(varname) | |
343 | return varassigns[0] if len(varassigns) == 1 else None | 344 | return varassigns[0] if len(varassigns) == 1 else None | |
344 | 345 | |||
345 | def all_varassigns(self, varname: str) -> Sequence[Varassign]: | 346 | def all_varassigns(self, varname: str) -> Sequence[Varassign]: | |
346 | varassigns = [] | 347 | varassigns = [] | |
347 | for (i, line) in enumerate(self.lines): | 348 | for (i, line) in enumerate(self.lines): | |
348 | m = re.search(r'^(#?[\w+\-]+?)([!+:?]?=)([ \t]*)([^#\\]*?)(\s*)(#.*|)$', line) | 349 | m = re.search(r'^(#?[\w+\-]+?)([!+:?]?=)([ \t]*)([^#\\]*?)(\s*)(#.*|)$', line) | |
349 | if m and m[1] == varname: | 350 | if m and m[1].lstrip('#') == varname: | |
350 | varassigns.append(Varassign(i, m[1], m[2], m[3], m[4], m[5], m[6])) | 351 | varassigns.append(Varassign(i, m[1], m[2], m[3], m[4], m[5], m[6])) | |
351 | return varassigns | 352 | return varassigns | |
352 | 353 | |||
353 | def set(self, varname: str, new_value: str) -> bool: | 354 | def set(self, varname: str, new_value: str) -> bool: | |
354 | """ Changes the value of an existing variable in the lines. """ | 355 | """ Changes the value of an existing variable in the lines. """ | |
355 | 356 | |||
356 | varassign = self.unique_varassign(varname) | 357 | varassign = self.unique_varassign(varname) | |
357 | if varassign is not None: | 358 | if varassign is not None: | |
358 | self.lines[varassign.index] = varassign.varname + varassign.op + varassign.indent + new_value | 359 | self.lines[varassign.index] = varname + varassign.op + varassign.indent + new_value | |
359 | return varassign is not None | 360 | return varassign is not None | |
360 | 361 | |||
361 | def append(self, varname: str, value: str) -> None: | 362 | def append(self, varname: str, value: str) -> None: | |
362 | """ Appends to the value of an existing variable in the lines. """ | 363 | """ Appends to the value of an existing variable in the lines. """ | |
363 | if value == '': | 364 | if value == '': | |
364 | return | 365 | return | |
365 | varassign = self.unique_varassign(varname) | 366 | varassign = self.unique_varassign(varname) | |
366 | # TODO: add a test for multiple assignments | 367 | # TODO: add a test for multiple assignments | |
367 | if varassign is not None: | 368 | if varassign is not None: | |
368 | before = ' ' if re.search(r'\S$', varassign.value) else '' | 369 | before = ' ' if re.search(r'\S$', varassign.value) else '' | |
369 | after = '' if varassign.comment == '' else ' ' | 370 | after = '' if varassign.comment == '' else ' ' | |
370 | self.lines[varassign.index] = \ | 371 | self.lines[varassign.index] = \ | |
371 | varassign.varname + varassign.op + varassign.indent \ | 372 | varassign.varname + varassign.op + varassign.indent \ | |
@@ -492,56 +493,57 @@ class Adjuster: | @@ -492,56 +493,57 @@ class Adjuster: | |||
492 | elif kind == 'BUILD_DEPENDS': | 493 | elif kind == 'BUILD_DEPENDS': | |
493 | self.build_depends.append(value) | 494 | self.build_depends.append(value) | |
494 | elif kind == 'TEST_DEPENDS': | 495 | elif kind == 'TEST_DEPENDS': | |
495 | self.test_depends.append(value) | 496 | self.test_depends.append(value) | |
496 | else: | 497 | else: | |
497 | self.todos.append('dependency {0} {1}'.format(kind, value)) | 498 | self.todos.append('dependency {0} {1}'.format(kind, value)) | |
498 | 499 | |||
499 | def read_dependencies(self, cmd: str, env: Dict[str, str], cwd: str, pkgname_prefix: str) -> None: | 500 | def read_dependencies(self, cmd: str, env: Dict[str, str], cwd: str, pkgname_prefix: str) -> None: | |
500 | dep_lines = [] | 501 | dep_lines = [] | |
501 | 502 | |||
502 | effective_env = dict(os.environ) | 503 | effective_env = dict(os.environ) | |
503 | effective_env.update(env) | 504 | effective_env.update(env) | |
504 | 505 | |||
506 | debug('reading dependencies: cd {0} && env {1} {2}', cwd, env, cmd) | |||
505 | output = subprocess.check_output( | 507 | output = subprocess.check_output( | |
506 | args=cmd, | 508 | args=cmd, | |
507 | shell=True, | 509 | shell=True, | |
508 | env=effective_env, | 510 | env=effective_env, | |
509 | cwd=cwd | 511 | cwd=cwd | |
510 | ) | 512 | ) | |
511 | 513 | |||
512 | for line in output.decode('utf-8').split('\n'): | 514 | for line in output.decode('utf-8').split('\n'): | |
513 | m = re.search(r'^(\w+)\t([^\s:>]+)(>[^\s:]+|)(?::(\.\./\.\./\S+))?$', line) | 515 | m = re.search(r'^(\w+)\t([^\s:>]+)(>[^\s:]+|)(?::(\.\./\.\./\S+))?$', line) | |
514 | if m: | 516 | if m: | |
515 | dep_lines.append([m[1], m[2], m[3] or '>=0', m[4] or '']) | 517 | dep_lines.append([m[1], m[2], m[3] or '>=0', m[4] or '']) | |
516 | continue | 518 | continue | |
517 | m = re.search(r'^var\t(\S+)\t(.+)$', line) | 519 | m = re.search(r'^var\t(\S+)\t(.+)$', line) | |
518 | if m: | 520 | if m: | |
519 | self.update_vars[m[1]] = m[2] | 521 | self.update_vars[m[1]] = m[2] | |
520 | continue | 522 | continue | |
521 | if line != '': | 523 | if line != '': | |
522 | debug('unknown dependency line: %s', line) | 524 | debug('unknown dependency line: {0}', line) | |
523 | 525 | |||
524 | for dep_line in dep_lines: | 526 | for dep_line in dep_lines: | |
525 | type, pkgbase, constraint, dir = dep_line | 527 | type, pkgbase, constraint, dir = dep_line | |
526 | 528 | |||
527 | if dir == '' and pkgname_prefix != '': | 529 | if dir == '' and pkgname_prefix != '': | |
528 | dir = find_package(pkgname_prefix + pkgbase) | 530 | dir = find_package(pkgname_prefix + pkgbase) | |
529 | if dir != '': | 531 | if dir != '': | |
530 | pkgbase = pkgname_prefix + pkgbase | 532 | pkgbase = pkgname_prefix + pkgbase | |
531 | if dir == '': | 533 | if dir == '': | |
532 | dir = find_package(pkgbase) | 534 | dir = find_package(pkgbase) | |
533 | 535 | |||
534 | debug('add_dependency: %s %s %s %s', type, pkgbase, constraint, dir) | 536 | debug('add_dependency: {0} {1} {2} {3}', type, pkgbase, constraint, dir) | |
535 | self.add_dependency(type, pkgbase, constraint, dir) | 537 | self.add_dependency(type, pkgbase, constraint, dir) | |
536 | 538 | |||
537 | def wrksrc_find(self, what: Union[str, Callable]) -> Iterator[str]: | 539 | def wrksrc_find(self, what: Union[str, Callable]) -> Iterator[str]: | |
538 | def search(f): | 540 | def search(f): | |
539 | if type(what) == str: | 541 | if type(what) == str: | |
540 | return re.search(what, f) | 542 | return re.search(what, f) | |
541 | return what(f) | 543 | return what(f) | |
542 | 544 | |||
543 | return list(filter(search, self.wrksrc_files)) | 545 | return list(filter(search, self.wrksrc_files)) | |
544 | 546 | |||
545 | def wrksrc_isdir(self, relative_pathname: str) -> bool: | 547 | def wrksrc_isdir(self, relative_pathname: str) -> bool: | |
546 | return isfile(self.abs_wrksrc + '/' + relative_pathname) | 548 | return isfile(self.abs_wrksrc + '/' + relative_pathname) | |
547 | 549 | |||
@@ -717,52 +719,52 @@ class Adjuster: | @@ -717,52 +719,52 @@ class Adjuster: | |||
717 | self.build_vars.append(Var('WRKSRC', '=', '${WRKDIR}/' + files[0])) | 719 | self.build_vars.append(Var('WRKSRC', '=', '${WRKDIR}/' + files[0])) | |
718 | self.abs_wrksrc = self.abs_wrkdir + '/' + files[0] | 720 | self.abs_wrksrc = self.abs_wrkdir + '/' + files[0] | |
719 | elif len(files) == 0: | 721 | elif len(files) == 0: | |
720 | self.build_vars.append(Var('WRKSRC', '=', '${WRKDIR}')) | 722 | self.build_vars.append(Var('WRKSRC', '=', '${WRKDIR}')) | |
721 | self.abs_wrksrc = self.abs_wrkdir | 723 | self.abs_wrksrc = self.abs_wrkdir | |
722 | else: | 724 | else: | |
723 | wrksrc = '${WRKDIR} # More than one possibility -- please check manually.' | 725 | wrksrc = '${WRKDIR} # More than one possibility -- please check manually.' | |
724 | self.build_vars.append(Var('WRKSRC', '=', wrksrc)) | 726 | self.build_vars.append(Var('WRKSRC', '=', wrksrc)) | |
725 | self.abs_wrksrc = self.abs_wrkdir | 727 | self.abs_wrksrc = self.abs_wrkdir | |
726 | 728 | |||
727 | def adjust_lines_python_module(self, lines: Lines, url: str): | 729 | def adjust_lines_python_module(self, lines: Lines, url: str): | |
728 | 730 | |||
729 | initial_lines = generate_initial_package_Makefile_lines(url) | 731 | initial_lines = generate_initial_package_Makefile_lines(url) | |
730 | current_lines = Lines.read_from('Makefile') | 732 | current_lines = self.makefile_lines | |
731 | 733 | |||
732 | if 'python' not in initial_lines.get('CATEGORIES'): | 734 | if 'python' not in initial_lines.get('CATEGORIES'): | |
733 | return | 735 | return | |
734 | pkgbase = initial_lines.get('GITHUB_PROJECT') | 736 | pkgbase = initial_lines.get('GITHUB_PROJECT') | |
735 | if pkgbase == '': | 737 | if pkgbase == '': | |
736 | return | 738 | return | |
737 | pkgbase1 = pkgbase[:1] | 739 | pkgbase1 = pkgbase[:1] | |
738 | pkgversion_norev = re.sub(r'^v', '', initial_lines.get('DISTNAME')) | 740 | pkgversion_norev = re.sub(r'^v', '', initial_lines.get('DISTNAME')) | |
739 | 741 | |||
740 | # don't risk to overwrite any changes made by the package developer. | 742 | # don't risk to overwrite any changes made by the package developer. | |
741 | if '\n'.join(current_lines.lines) != '\n'.join(initial_lines.lines): | 743 | if '\n'.join(current_lines.lines) != '\n'.join(initial_lines.lines): | |
742 | lines.lines.insert(-2, '# TODO: Migrate MASTER_SITES to PYPI') | 744 | lines.lines.insert(-2, '# TODO: Migrate MASTER_SITES to PYPI') | |
743 | return | 745 | return | |
744 | 746 | |||
745 | tx_lines = Lines(*self.makefile_lines.lines) | 747 | tx_lines = Lines(*self.makefile_lines.lines) | |
746 | if (tx_lines.remove('GITHUB_PROJECT') | 748 | if (tx_lines.remove('GITHUB_PROJECT') | |
747 | and tx_lines.set('DISTNAME', '%s-%s' % (pkgbase, pkgversion_norev)) | 749 | and tx_lines.set('DISTNAME', '%s-%s' % (pkgbase, pkgversion_norev)) | |
748 | and tx_lines.set('PKGNAME', '${PYPKGPREFIX}-${DISTNAME}') | 750 | and tx_lines.set('PKGNAME', '${PYPKGPREFIX}-${DISTNAME}') | |
749 | and tx_lines.set('MASTER_SITES', '${MASTER_SITE_PYPI:=%s/%s/}' % (pkgbase1, pkgbase)) | 751 | and tx_lines.set('MASTER_SITES', '${MASTER_SITE_PYPI:=%s/%s/}' % (pkgbase1, pkgbase)) | |
750 | and tx_lines.remove('DIST_SUBDIR') | 752 | and tx_lines.remove('DIST_SUBDIR') | |
751 | and (tx_lines.remove_if('EXTRACT_SUFX', '.zip') or True)): | 753 | and (tx_lines.remove_if('EXTRACT_SUFX', '.zip') or True)): | |
752 | self.makefile_lines = tx_lines | 754 | self.makefile_lines = tx_lines | |
753 | self.regenerate_distinfo = True | 755 | self.regenerate_distinfo = True | |
754 | 756 | |||
755 | def generate_adjusted_Makefile_lines(self, url): | 757 | def generate_adjusted_Makefile_lines(self, url) -> Lines: | |
756 | marker_index = self.makefile_lines.index(r'^# url2pkg-marker') | 758 | marker_index = self.makefile_lines.index(r'^# url2pkg-marker') | |
757 | if marker_index == -1: | 759 | if marker_index == -1: | |
758 | raise Exception('ERROR: didn\'t find the url2pkg marker in the Makefile.') | 760 | raise Exception('ERROR: didn\'t find the url2pkg marker in the Makefile.') | |
759 | 761 | |||
760 | lines = Lines(*self.makefile_lines.lines[: marker_index]) | 762 | lines = Lines(*self.makefile_lines.lines[: marker_index]) | |
761 | 763 | |||
762 | if lines.index(r'^PKGNAME=') == -1: | 764 | if lines.index(r'^PKGNAME=') == -1: | |
763 | distname_index = lines.index(r'^DISTNAME=(\t+)') | 765 | distname_index = lines.index(r'^DISTNAME=(\t+)') | |
764 | if distname_index != -1: | 766 | if distname_index != -1: | |
765 | pkgname_line = 'PKGNAME=\t%s${DISTNAME%s}' % (self.pkgname_prefix, self.pkgname_transform) | 767 | pkgname_line = 'PKGNAME=\t%s${DISTNAME%s}' % (self.pkgname_prefix, self.pkgname_transform) | |
766 | lines.lines.insert(distname_index + 1, pkgname_line) | 768 | lines.lines.insert(distname_index + 1, pkgname_line) | |
767 | 769 | |||
768 | if self.todos: | 770 | if self.todos: | |
@@ -779,69 +781,71 @@ class Adjuster: | @@ -779,69 +781,71 @@ class Adjuster: | |||
779 | lines.add_vars(*self.build_vars) | 781 | lines.add_vars(*self.build_vars) | |
780 | lines.add_vars(*self.extra_vars) | 782 | lines.add_vars(*self.extra_vars) | |
781 | 783 | |||
782 | lines.add(*self.bl3_lines) | 784 | lines.add(*self.bl3_lines) | |
783 | lines.add(*map(lambda include: '.include "%s"' % include, self.includes)) | 785 | lines.add(*map(lambda include: '.include "%s"' % include, self.includes)) | |
784 | 786 | |||
785 | lines.add(*self.makefile_lines.lines[marker_index + 1:]) | 787 | lines.add(*self.makefile_lines.lines[marker_index + 1:]) | |
786 | 788 | |||
787 | lines.append('CATEGORIES', ' '.join(self.categories)) | 789 | lines.append('CATEGORIES', ' '.join(self.categories)) | |
788 | 790 | |||
789 | self.adjust_lines_python_module(lines, url) | 791 | self.adjust_lines_python_module(lines, url) | |
790 | 792 | |||
791 | for varname in self.update_vars: | 793 | for varname in self.update_vars: | |
794 | debug('update_var {0} {1}', varname, self.update_vars[varname]) | |||
792 | lines.set(varname, self.update_vars[varname]) | 795 | lines.set(varname, self.update_vars[varname]) | |
793 | 796 | |||
794 | return lines | 797 | return lines | |
795 | 798 | |||
796 | def adjust_package_from_extracted_distfiles(self, url: str): | 799 | def adjust_package_from_extracted_distfiles(self, url: str): | |
797 | 800 | |||
798 | debug('Adjusting the Makefile') | 801 | debug('Adjusting the Makefile') | |
799 | 802 | |||
800 | self.abs_wrkdir = show_var('WRKDIR') | 803 | self.abs_wrkdir = show_var('WRKDIR') | |
801 | self.determine_wrksrc() | 804 | self.determine_wrksrc() | |
802 | self.wrksrc_files = glob.glob(f'{self.abs_wrksrc}/**', recursive=True) | 805 | self.wrksrc_files = glob.glob(f'{self.abs_wrksrc}/**', recursive=True) | |
803 | self.wrksrc_dirs = glob.glob(f'{self.abs_wrksrc}/**/', recursive=True) | 806 | self.wrksrc_dirs = glob.glob(f'{self.abs_wrksrc}/**/', recursive=True) | |
804 | 807 | |||
805 | self.makefile_lines = Lines.read_from('Makefile') | 808 | self.makefile_lines = Lines.read_from(config.pkgdir + '/Makefile') | |
806 | 809 | |||
807 | self.adjust_configure() | 810 | self.adjust_configure() | |
808 | self.adjust_cmake() | 811 | self.adjust_cmake() | |
809 | self.adjust_meson() | 812 | self.adjust_meson() | |
810 | self.adjust_gconf2_schemas() | 813 | self.adjust_gconf2_schemas() | |
811 | self.adjust_libtool() | 814 | self.adjust_libtool() | |
812 | self.adjust_perl_module(url) | 815 | self.adjust_perl_module(url) | |
813 | self.adjust_python_module() | 816 | self.adjust_python_module() | |
814 | self.adjust_cargo() | 817 | self.adjust_cargo() | |
815 | self.adjust_pkg_config() | 818 | self.adjust_pkg_config() | |
816 | self.adjust_po() | 819 | self.adjust_po() | |
817 | self.adjust_use_languages() | 820 | self.adjust_use_languages() | |
818 | 821 | |||
819 | self.generate_adjusted_Makefile_lines(url).write_to('Makefile') | 822 | self.generate_adjusted_Makefile_lines(url).write_to(config.pkgdir + '/Makefile') | |
820 | 823 | |||
821 | if self.regenerate_distinfo: | 824 | if self.regenerate_distinfo: | |
822 | bmake('distinfo') | 825 | bmake('distinfo') | |
823 | 826 | |||
824 | 827 | |||
825 | def main(): | 828 | def main(): | |
826 | global distname | 829 | global distname | |
827 | 830 | |||
828 | if not isfile('../../mk/bsd.pkg.mk'): | 831 | if not isfile('../../mk/bsd.pkg.mk'): | |
829 | sys.exit(f'ERROR: {sys.argv[0]} must be run from a package directory (.../pkgsrc/category/package).') | 832 | sys.exit(f'ERROR: {sys.argv[0]} must be run from a package directory (.../pkgsrc/category/package).') | |
830 | 833 | |||
831 | try: | 834 | try: | |
832 | opts, args = getopt.getopt(sys.argv[1:], 'v', ['verbose']) | 835 | opts, args = getopt.getopt(sys.argv[1:], 'v', ['verbose']) | |
833 | for opt in opts: | 836 | for (opt, optarg) in opts: | |
834 | if opt in ('v', 'verbose'): | 837 | print('opt', repr(opt)) | |
838 | if opt in ('-v', '--verbose'): | |||
835 | config.verbose = True | 839 | config.verbose = True | |
836 | except getopt.GetoptError: | 840 | except getopt.GetoptError: | |
837 | sys.exit(f'usage: {sys.argv[0]} [-v|--verbose] [URL]') | 841 | sys.exit(f'usage: {sys.argv[0]} [-v|--verbose] [URL]') | |
838 | 842 | |||
839 | if len(args) == 0: | 843 | if len(args) == 0: | |
840 | url = input('URL: ') | 844 | url = input('URL: ') | |
841 | else: | 845 | else: | |
842 | url = args[0] | 846 | url = args[0] | |
843 | 847 | |||
844 | extract_cookie = glob.glob('w*/.extract_done') | 848 | extract_cookie = glob.glob('w*/.extract_done') | |
845 | if not extract_cookie or not isfile('Makefile'): | 849 | if not extract_cookie or not isfile('Makefile'): | |
846 | generate_initial_package(url) | 850 | generate_initial_package(url) | |
847 | else: | 851 | else: |
@@ -1,30 +1,57 @@ | @@ -1,30 +1,57 @@ | |||
1 | # $NetBSD: url2pkg_test.py,v 1.1 2019/10/03 09:37:41 rillig Exp $ | 1 | # $NetBSD: url2pkg_test.py,v 1.2 2019/10/03 12:52:54 rillig Exp $ | |
2 | 2 | |||
3 | import os | |||
4 | from typing import List | |||
5 | from url2pkg import * | 3 | from url2pkg import * | |
6 | 4 | |||
7 | 5 | |||
8 | def setup_function(fn): | 6 | def setup_function(_): | |
9 | config.pkgsrcdir = os.getenv('PKGSRCDIR') | 7 | config.pkgsrcdir = os.getenv('PKGSRCDIR') | |
10 | assert config.pkgsrcdir is not None | 8 | assert config.pkgsrcdir is not None | |
11 | os.chdir(config.pkgsrcdir + '/pkgtools/url2pkg') | 9 | os.chdir(config.pkgsrcdir + '/pkgtools/url2pkg') | |
12 | 10 | |||
13 | 11 | |||
14 | def vars(vars: List[Var]) -> List[str]: | 12 | def str_vars(vars: List[Var]) -> List[str]: | |
15 | return list(map(lambda var: var.name + var.op + var.value, vars)) | 13 | return list(map(lambda var: var.name + var.op + var.value, vars)) | |
16 | 14 | |||
17 | 15 | |||
16 | def test_debug(): | |||
17 | """ Just ensure that the debug calls do not crash. """ | |||
18 | config.verbose = True | |||
19 | try: | |||
20 | debug('plain message') | |||
21 | debug('list {0}', [1, 2, 3]) | |||
22 | debug('tuple {0}', (1, 2, 3)) | |||
23 | debug('cwd {0} env {1} cmd {2}', 'directory', {'VAR': 'value'}, 'command') | |||
24 | finally: | |||
25 | config.verbose = False | |||
26 | ||||
27 | ||||
28 | def test_aligned__empty(): | |||
29 | assert aligned([]) == [] | |||
30 | ||||
31 | ||||
32 | def test_aligned__variables(): | |||
33 | vars = [ | |||
34 | Var('V', '=', 'value'), | |||
35 | Var('LONG_NAME', '=', 'value # comment') | |||
36 | ] | |||
37 | lines = [ | |||
38 | 'V=\t\tvalue', | |||
39 | 'LONG_NAME=\tvalue # comment', | |||
40 | '' | |||
41 | ] | |||
42 | assert aligned(vars) == lines | |||
43 | ||||
44 | ||||
18 | def test_Lines_add_vars__simple(): | 45 | def test_Lines_add_vars__simple(): | |
19 | lines = Lines() | 46 | lines = Lines() | |
20 | 47 | |||
21 | lines.add_vars( | 48 | lines.add_vars( | |
22 | Var("1", "=", "one"), | 49 | Var("1", "=", "one"), | |
23 | Var("6", "=", "six"), | 50 | Var("6", "=", "six"), | |
24 | ) | 51 | ) | |
25 | 52 | |||
26 | assert lines.lines == [ | 53 | assert lines.lines == [ | |
27 | "1=\tone", | 54 | "1=\tone", | |
28 | "6=\tsix", | 55 | "6=\tsix", | |
29 | "", | 56 | "", | |
30 | ] | 57 | ] | |
@@ -84,55 +111,130 @@ def test_Lines_append__only_comment(): | @@ -84,55 +111,130 @@ def test_Lines_append__only_comment(): | |||
84 | 111 | |||
85 | 112 | |||
86 | def test_Lines_append__value_with_comment(): | 113 | def test_Lines_append__value_with_comment(): | |
87 | lines = Lines("VARNAME=\tvalue # comment") | 114 | lines = Lines("VARNAME=\tvalue # comment") | |
88 | 115 | |||
89 | lines.append("VARNAME", "appended") | 116 | lines.append("VARNAME", "appended") | |
90 | 117 | |||
91 | assert lines.lines == ["VARNAME=\tvalue appended # comment"] | 118 | assert lines.lines == ["VARNAME=\tvalue appended # comment"] | |
92 | 119 | |||
93 | 120 | |||
94 | def test_Lines_append__value_without_comment(): | 121 | def test_Lines_append__value_without_comment(): | |
95 | lines = Lines("VARNAME+=\tvalue") | 122 | lines = Lines("VARNAME+=\tvalue") | |
96 | 123 | |||
97 | assert lines.append("VARNAME", "appended") == True | 124 | assert lines.append("VARNAME", "appended") | |
98 | 125 | |||
99 | assert lines.lines == ["VARNAME+=\tvalue appended"] | 126 | assert lines.lines == ["VARNAME+=\tvalue appended"] | |
100 | 127 | |||
101 | 128 | |||
102 | def test_Lines_set__previously_with_comment(): | 129 | def test_Lines_set__previously_with_comment(): | |
103 | lines = Lines("LICENSE=\t# TODO: see mk/license.mk") | 130 | lines = Lines("LICENSE=\t# TODO: see mk/license.mk") | |
104 | 131 | |||
105 | lines.set("LICENSE", "${PERL5_LICENSE}") | 132 | assert lines.set("LICENSE", "${PERL5_LICENSE}") | |
106 | 133 | |||
107 | assert lines.lines == ["LICENSE=\t${PERL5_LICENSE}"] | 134 | assert lines.lines == ["LICENSE=\t${PERL5_LICENSE}"] | |
108 | 135 | |||
109 | 136 | |||
137 | def test_Lines_unique_varassign__commented_out_no_value(): | |||
138 | lines = Lines("#LICENSE=\t# TODO: see mk/license.mk") | |||
139 | ||||
140 | assert len(lines.all_varassigns('LICENSE')) == 1 | |||
141 | ||||
142 | ||||
110 | def test_Lines_set__overwrite_comment_with_comment(): | 143 | def test_Lines_set__overwrite_comment_with_comment(): | |
111 | lines = Lines("#LICENSE=\t# TODO: see mk/license.mk") | 144 | lines = Lines("#LICENSE=\t# TODO: see mk/license.mk") | |
112 | 145 | |||
113 | lines.set("#LICENSE", "${PERL5_LICENSE}") | 146 | assert len(lines.all_varassigns('LICENSE')) == 1 | |
147 | assert lines.set("LICENSE", "${PERL5_LICENSE}") | |||
114 | 148 | |||
115 | assert lines.lines == ["#LICENSE=\t${PERL5_LICENSE}"] | 149 | assert lines.lines == ["LICENSE=\t${PERL5_LICENSE}"] | |
150 | ||||
151 | ||||
152 | def test_Lines_set__overwrite_commented_with_comment(): | |||
153 | lines = Lines("#LICENSE=\t# TODO: see mk/license.mk") | |||
154 | ||||
155 | assert lines.set("LICENSE", "${PERL5_LICENSE}") | |||
156 | ||||
157 | assert lines.lines == ["LICENSE=\t${PERL5_LICENSE}"] | |||
116 | 158 | |||
117 | 159 | |||
118 | def test_Lines_set__not_found(): | 160 | def test_Lines_set__not_found(): | |
119 | lines = Lines("OLD_VAR=\told value # old comment") | 161 | lines = Lines("OLD_VAR=\told value # old comment") | |
120 | 162 | |||
121 | lines.set("NEW_VAR", "new value") | 163 | assert not lines.set("NEW_VAR", "new value") | |
122 | 164 | |||
123 | assert lines.lines == ["OLD_VAR=\told value # old comment"] | 165 | assert lines.lines == ["OLD_VAR=\told value # old comment"] | |
124 | 166 | |||
125 | 167 | |||
168 | def test_Lines_remove__not_found(): | |||
169 | lines = Lines('VAR=\tvalue') | |||
170 | ||||
171 | assert not lines.remove('VARIABLE') | |||
172 | ||||
173 | assert lines.lines == ['VAR=\tvalue'] | |||
174 | ||||
175 | ||||
176 | def test_Lines_remove__found(): | |||
177 | lines = Lines('VAR=\tvalue') | |||
178 | ||||
179 | assert lines.remove('VAR') | |||
180 | ||||
181 | assert lines.lines == [] | |||
182 | ||||
183 | ||||
184 | def test_Lines_remove__found_several_times(): | |||
185 | lines = Lines('VAR=\tvalue1', 'VAR=\tvalue2') | |||
186 | ||||
187 | assert not lines.remove('VAR') | |||
188 | ||||
189 | assert lines.lines == ['VAR=\tvalue1', 'VAR=\tvalue2'] | |||
190 | ||||
191 | ||||
192 | def test_Lines_remove_if__different_name(): | |||
193 | lines = Lines('VAR=\tvalue') | |||
194 | ||||
195 | assert not lines.remove_if('VARIABLE', 'value') | |||
196 | ||||
197 | assert lines.lines == ['VAR=\tvalue'] | |||
198 | ||||
199 | ||||
200 | def test_Lines_remove_if__different_value(): | |||
201 | lines = Lines('VAR=\tvalue') | |||
202 | ||||
203 | assert not lines.remove_if('VAR', 'something') | |||
204 | ||||
205 | assert lines.lines == ['VAR=\tvalue'] | |||
206 | ||||
207 | ||||
208 | def test_Lines_remove_if__found(): | |||
209 | lines = Lines('VAR=\tvalue') | |||
210 | ||||
211 | assert lines.remove_if('VAR', 'value') | |||
212 | ||||
213 | assert lines.lines == [] | |||
214 | ||||
215 | ||||
216 | def test_Lines_remove_if__multiple(): | |||
217 | lines = Lines('VAR=\tvalue', 'VAR=\tvalue') | |||
218 | ||||
219 | assert lines.remove_if('VAR', 'value') | |||
220 | ||||
221 | assert lines.lines == ['VAR=\tvalue'] | |||
222 | ||||
223 | assert lines.remove_if('VAR', 'value') | |||
224 | ||||
225 | assert lines.lines == [] | |||
226 | ||||
227 | ||||
126 | def test_Lines_index(): | 228 | def test_Lines_index(): | |
127 | lines = Lines("1", "2", "345") | 229 | lines = Lines("1", "2", "345") | |
128 | 230 | |||
129 | assert lines.index("1") == 0 | 231 | assert lines.index("1") == 0 | |
130 | assert lines.index("2") == 1 | 232 | assert lines.index("2") == 1 | |
131 | assert lines.index("345") == 2 | 233 | assert lines.index("345") == 2 | |
132 | assert lines.index("4") == 2 | 234 | assert lines.index("4") == 2 | |
133 | 235 | |||
134 | assert lines.index(r'^(\d\d)\d$') == 2 | 236 | assert lines.index(r'^(\d\d)\d$') == 2 | |
135 | assert lines.index(r"^\d\s\d$") == -1 | 237 | assert lines.index(r"^\d\s\d$") == -1 | |
136 | assert lines.index(r"(\d)") == 0 | 238 | assert lines.index(r"(\d)") == 0 | |
137 | 239 | |||
138 | 240 | |||
@@ -245,48 +347,52 @@ def test_generate_initial_package_Makefi | @@ -245,48 +347,52 @@ def test_generate_initial_package_Makefi | |||
245 | "# url2pkg-marker (please do not remove this line.)", | 347 | "# url2pkg-marker (please do not remove this line.)", | |
246 | ".include \"../../mk/bsd.pkg.mk\"" | 348 | ".include \"../../mk/bsd.pkg.mk\"" | |
247 | ] | 349 | ] | |
248 | 350 | |||
249 | 351 | |||
250 | def test_Adjuster_read_dependencies(): | 352 | def test_Adjuster_read_dependencies(): | |
251 | dep_lines = [ | 353 | dep_lines = [ | |
252 | "DEPENDS\tpackage>=version:../../pkgtools/pkglint", | 354 | "DEPENDS\tpackage>=version:../../pkgtools/pkglint", | |
253 | "DEPENDS\tpackage>=version:../../pkgtools/x11-links", | 355 | "DEPENDS\tpackage>=version:../../pkgtools/x11-links", | |
254 | "BUILD_DEPENDS\turl2pkg>=1.0", | 356 | "BUILD_DEPENDS\turl2pkg>=1.0", | |
255 | "TEST_DEPENDS\tpkglint", | 357 | "TEST_DEPENDS\tpkglint", | |
256 | "A line that is not a dependency at all", | 358 | "A line that is not a dependency at all", | |
257 | "", | 359 | "", | |
360 | "var\tHOMEPAGE\thttps://homepage.example.org/" | |||
258 | "" | 361 | "" | |
259 | ] | 362 | ] | |
260 | env = {"URL2PKG_DEPENDENCIES": '\n'.join(dep_lines)} | 363 | env = {"URL2PKG_DEPENDENCIES": '\n'.join(dep_lines)} | |
261 | cmd = "printf '%s\n' \"$URL2PKG_DEPENDENCIES\"" | 364 | cmd = "printf '%s\n' \"$URL2PKG_DEPENDENCIES\"" | |
262 | 365 | |||
263 | adjuster = Adjuster() | 366 | adjuster = Adjuster() | |
264 | adjuster.read_dependencies(cmd, env, '.', '') | 367 | adjuster.read_dependencies(cmd, env, '.', '') | |
265 | 368 | |||
266 | assert os.getenv('URL2PKG_DEPENDENCIES') is None | 369 | assert os.getenv('URL2PKG_DEPENDENCIES') is None | |
267 | 370 | |||
268 | assert adjuster.depends == [ | 371 | assert adjuster.depends == [ | |
269 | "package>=version:../../pkgtools/pkglint" | 372 | "package>=version:../../pkgtools/pkglint" | |
270 | ] | 373 | ] | |
271 | assert adjuster.bl3_lines == [ | 374 | assert adjuster.bl3_lines == [ | |
272 | ".include \"../../pkgtools/x11-links/buildlink3.mk\"" | 375 | ".include \"../../pkgtools/x11-links/buildlink3.mk\"" | |
273 | ] | 376 | ] | |
274 | assert adjuster.build_depends == [ | 377 | assert adjuster.build_depends == [ | |
275 | "url2pkg>=1.0:../../pkgtools/url2pkg" | 378 | "url2pkg>=1.0:../../pkgtools/url2pkg" | |
276 | ] | 379 | ] | |
277 | assert adjuster.test_depends == [ | 380 | assert adjuster.test_depends == [ | |
278 | "pkglint>=0:../../pkgtools/pkglint" | 381 | "pkglint>=0:../../pkgtools/pkglint" | |
279 | ] | 382 | ] | |
383 | assert adjuster.update_vars == { | |||
384 | 'HOMEPAGE': 'https://homepage.example.org/' | |||
385 | } | |||
280 | 386 | |||
281 | 387 | |||
282 | def test_Adjuster_generate_adjusted_Makefile_lines(): | 388 | def test_Adjuster_generate_adjusted_Makefile_lines(): | |
283 | adjuster = Adjuster() | 389 | adjuster = Adjuster() | |
284 | adjuster.makefile_lines = Lines( | 390 | adjuster.makefile_lines = Lines( | |
285 | "# before 1", | 391 | "# before 1", | |
286 | "# before 2", | 392 | "# before 2", | |
287 | "# url2pkg-marker", | 393 | "# url2pkg-marker", | |
288 | "# after 1", | 394 | "# after 1", | |
289 | "# after 2" | 395 | "# after 2" | |
290 | ) | 396 | ) | |
291 | 397 | |||
292 | lines = adjuster.generate_adjusted_Makefile_lines("https://example.org/pkgname-1.0.tar.gz") | 398 | lines = adjuster.generate_adjusted_Makefile_lines("https://example.org/pkgname-1.0.tar.gz") | |
@@ -299,149 +405,301 @@ def test_Adjuster_generate_adjusted_Make | @@ -299,149 +405,301 @@ def test_Adjuster_generate_adjusted_Make | |||
299 | ] | 405 | ] | |
300 | 406 | |||
301 | 407 | |||
302 | def test_Adjuster_generate_adjusted_Makefile_lines__dependencies(): | 408 | def test_Adjuster_generate_adjusted_Makefile_lines__dependencies(): | |
303 | adjuster = Adjuster() | 409 | adjuster = Adjuster() | |
304 | adjuster.makefile_lines.add( | 410 | adjuster.makefile_lines.add( | |
305 | "# $" + "NetBSD$", | 411 | "# $" + "NetBSD$", | |
306 | "", | 412 | "", | |
307 | "# url2pkg-marker", | 413 | "# url2pkg-marker", | |
308 | ".include \"../../mk/bsd.pkg.mk\"" | 414 | ".include \"../../mk/bsd.pkg.mk\"" | |
309 | ) | 415 | ) | |
310 | 416 | |||
311 | # some dependencies whose directory will not be found | 417 | # some dependencies whose directory will not be found | |
312 | adjuster.add_dependency("DEPENDS", "depends", ">=5.0", "../../devel/depends"); | 418 | adjuster.add_dependency("DEPENDS", "depends", ">=5.0", "../../devel/depends") | |
313 | adjuster.add_dependency("TOOL_DEPENDS", "tool-depends", ">=6.0", "../../devel/tool-depends"); | 419 | adjuster.add_dependency("TOOL_DEPENDS", "tool-depends", ">=6.0", "../../devel/tool-depends") | |
314 | adjuster.add_dependency("BUILD_DEPENDS", "build-depends", ">=7.0", "../../devel/build-depends"); | 420 | adjuster.add_dependency("BUILD_DEPENDS", "build-depends", ">=7.0", "../../devel/build-depends") | |
315 | adjuster.add_dependency("TEST_DEPENDS", "test-depends", ">=8.0", "../../devel/test-depends"); | 421 | adjuster.add_dependency("TEST_DEPENDS", "test-depends", ">=8.0", "../../devel/test-depends") | |
316 | # some dependencies whose directory is explicitly given | 422 | # some dependencies whose directory is explicitly given | |
317 | adjuster.depends.append("depends>=11.0:../../devel/depends") | 423 | adjuster.depends.append("depends>=11.0:../../devel/depends") | |
318 | adjuster.build_depends.append("build-depends>=12.0:../../devel/build-depends") | 424 | adjuster.build_depends.append("build-depends>=12.0:../../devel/build-depends") | |
319 | adjuster.test_depends.append("test-depends>=13.0:../../devel/test-depends") | 425 | adjuster.test_depends.append("test-depends>=13.0:../../devel/test-depends") | |
320 | 426 | |||
321 | lines = adjuster.generate_adjusted_Makefile_lines("https://example.org/pkgname-1.0.tar.gz") | 427 | lines = adjuster.generate_adjusted_Makefile_lines("https://example.org/pkgname-1.0.tar.gz") | |
322 | 428 | |||
323 | assert lines.lines == [ | 429 | assert lines.lines == [ | |
324 | "# $" + "NetBSD$", | 430 | "# $" + "NetBSD$", | |
325 | "", | 431 | "", | |
326 | "# TODO: dependency TOOL_DEPENDS # TODO: tool-depends>=6.0", | 432 | "# TODO: dependency TOOL_DEPENDS # TODO: tool-depends>=6.0", | |
327 | "", | 433 | "", | |
328 | "BUILD_DEPENDS+=\t# TODO: build-depends>=7.0", | 434 | "BUILD_DEPENDS+=\t# TODO: build-depends>=7.0", | |
329 | "BUILD_DEPENDS+=\tbuild-depends>=12.0:../../devel/build-depends", | 435 | "BUILD_DEPENDS+=\tbuild-depends>=12.0:../../devel/build-depends", | |
330 | "DEPENDS+=\t# TODO: depends>=5.0", | 436 | "DEPENDS+=\t# TODO: depends>=5.0", | |
331 | "DEPENDS+=\tdepends>=11.0:../../devel/depends", | 437 | "DEPENDS+=\tdepends>=11.0:../../devel/depends", | |
332 | "TEST_DEPENDS+=\t# TODO: test-depends>=8.0", | 438 | "TEST_DEPENDS+=\t# TODO: test-depends>=8.0", | |
333 | "TEST_DEPENDS+=\ttest-depends>=13.0:../../devel/test-depends", | 439 | "TEST_DEPENDS+=\ttest-depends>=13.0:../../devel/test-depends", | |
334 | "", | 440 | "", | |
335 | ".include \"../../mk/bsd.pkg.mk\"" | 441 | ".include \"../../mk/bsd.pkg.mk\"" | |
336 | ] | 442 | ] | |
337 | 443 | |||
338 | 444 | |||
445 | def test_Adjuster_adjust_configure__not_found(tmp_path): | |||
446 | adjuster = Adjuster() | |||
447 | adjuster.abs_wrksrc = str(tmp_path) | |||
448 | ||||
449 | adjuster.adjust_configure() | |||
450 | ||||
451 | assert adjuster.build_vars == [] | |||
452 | ||||
453 | ||||
454 | def test_Adjuster_adjust_configure__GNU_configure(tmp_path): | |||
455 | adjuster = Adjuster() | |||
456 | adjuster.abs_wrksrc = str(tmp_path) | |||
457 | (tmp_path / 'configure').write_text('# Free Software Foundation\n') | |||
458 | ||||
459 | adjuster.adjust_configure() | |||
460 | ||||
461 | assert str_vars(adjuster.build_vars) == [ | |||
462 | 'GNU_CONFIGURE=yes', | |||
463 | ] | |||
464 | ||||
465 | ||||
466 | def test_Adjuster_adjust_configure__other_configure(tmp_path): | |||
467 | adjuster = Adjuster() | |||
468 | adjuster.abs_wrksrc = str(tmp_path) | |||
469 | (tmp_path / 'configure').write_text('# A generic configure script\n') | |||
470 | ||||
471 | adjuster.adjust_configure() | |||
472 | ||||
473 | assert str_vars(adjuster.build_vars) == [ | |||
474 | 'HAS_CONFIGURE=yes', | |||
475 | ] | |||
476 | ||||
477 | ||||
478 | def test_Adjuster_adjust_cargo__not_found(tmp_path): | |||
479 | adjuster = Adjuster() | |||
480 | adjuster.abs_wrksrc = str(tmp_path) | |||
481 | ||||
482 | adjuster.adjust_cargo() | |||
483 | ||||
484 | assert str_vars(adjuster.build_vars) == [] | |||
485 | ||||
486 | ||||
487 | def test_Adjuster_adjust_cargo__found(tmp_path): | |||
488 | adjuster = Adjuster() | |||
489 | adjuster.abs_wrksrc = str(tmp_path) | |||
490 | (tmp_path / 'Cargo.lock').write_text('"checksum cargo-package-name cargo-package-version 1234"') | |||
491 | ||||
492 | adjuster.adjust_cargo() | |||
493 | ||||
494 | assert str_vars(adjuster.build_vars) == [ | |||
495 | 'CARGO_CRATE_DEPENDS+=cargo-package-name-cargo-package-version', | |||
496 | ] | |||
497 | ||||
498 | ||||
339 | def test_Adjuster_adjust_po__not_found(): | 499 | def test_Adjuster_adjust_po__not_found(): | |
340 | adjuster = Adjuster() | 500 | adjuster = Adjuster() | |
341 | 501 | |||
342 | adjuster.adjust_po() | 502 | adjuster.adjust_po() | |
343 | 503 | |||
344 | assert adjuster.build_vars == [] | 504 | assert adjuster.build_vars == [] | |
345 | 505 | |||
346 | 506 | |||
347 | def test_Adjuster_adjust_po__found(): | 507 | def test_Adjuster_adjust_po__found(): | |
348 | adjuster = Adjuster() | 508 | adjuster = Adjuster() | |
349 | adjuster.wrksrc_files = ['share/locale/de.mo'] | 509 | adjuster.wrksrc_files = ['share/locale/de.mo'] | |
350 | 510 | |||
351 | adjuster.adjust_po() | 511 | adjuster.adjust_po() | |
352 | 512 | |||
353 | assert vars(adjuster.build_vars) == [ | 513 | assert str_vars(adjuster.build_vars) == [ | |
354 | 'USE_PKGLOCALEDIR=yes' | 514 | 'USE_PKGLOCALEDIR=yes' | |
355 | ] | 515 | ] | |
356 | 516 | |||
357 | 517 | |||
358 | def test_Adjuster_adjust_use_languages__none(): | 518 | def test_Adjuster_adjust_use_languages__none(): | |
359 | adjuster = Adjuster() | 519 | adjuster = Adjuster() | |
360 | 520 | |||
361 | adjuster.adjust_use_languages() | 521 | adjuster.adjust_use_languages() | |
362 | 522 | |||
363 | assert vars(adjuster.build_vars) == [ | 523 | assert str_vars(adjuster.build_vars) == [ | |
364 | 'USE_LANGUAGES=# none' | 524 | 'USE_LANGUAGES=# none' | |
365 | ] | 525 | ] | |
366 | 526 | |||
367 | 527 | |||
368 | def test_Adjuster_adjust_use_languages__c(): | 528 | def test_Adjuster_adjust_use_languages__c(): | |
369 | adjuster = Adjuster() | 529 | adjuster = Adjuster() | |
370 | adjuster.wrksrc_files = ['main.c'] | 530 | adjuster.wrksrc_files = ['main.c'] | |
371 | 531 | |||
372 | adjuster.adjust_use_languages() | 532 | adjuster.adjust_use_languages() | |
373 | 533 | |||
374 | assert vars(adjuster.build_vars) == [] | 534 | assert str_vars(adjuster.build_vars) == [] | |
375 | 535 | |||
376 | 536 | |||
377 | def test_Adjuster_adjust_use_languages__c_in_subdir(): | 537 | def test_Adjuster_adjust_use_languages__c_in_subdir(): | |
378 | adjuster = Adjuster() | 538 | adjuster = Adjuster() | |
379 | adjuster.wrksrc_files = ['subdir/main.c'] | 539 | adjuster.wrksrc_files = ['subdir/main.c'] | |
380 | 540 | |||
381 | adjuster.adjust_use_languages() | 541 | adjuster.adjust_use_languages() | |
382 | 542 | |||
383 | assert vars(adjuster.build_vars) == [] | 543 | assert str_vars(adjuster.build_vars) == [] | |
384 | 544 | |||
385 | 545 | |||
386 | def test_Adjuster_adjust_use_languages__cplusplus_in_subdir(): | 546 | def test_Adjuster_adjust_use_languages__cplusplus_in_subdir(): | |
387 | adjuster = Adjuster() | 547 | adjuster = Adjuster() | |
388 | adjuster.wrksrc_files = ['subdir/main.cpp'] | 548 | adjuster.wrksrc_files = ['subdir/main.cpp'] | |
389 | 549 | |||
390 | adjuster.adjust_use_languages() | 550 | adjuster.adjust_use_languages() | |
391 | 551 | |||
392 | assert vars(adjuster.build_vars) == [ | 552 | assert str_vars(adjuster.build_vars) == [ | |
393 | 'USE_LANGUAGES=c++' | 553 | 'USE_LANGUAGES=c++' | |
394 | ] | 554 | ] | |
395 | 555 | |||
396 | 556 | |||
397 | def test_Adjuster_adjust_use_languages__cplusplus_and_fortran(): | 557 | def test_Adjuster_adjust_use_languages__cplusplus_and_fortran(): | |
398 | adjuster = Adjuster() | 558 | adjuster = Adjuster() | |
399 | adjuster.wrksrc_files = ['subdir/main.cpp', 'main.f'] | 559 | adjuster.wrksrc_files = ['subdir/main.cpp', 'main.f'] | |
400 | 560 | |||
401 | adjuster.adjust_use_languages() | 561 | adjuster.adjust_use_languages() | |
402 | 562 | |||
403 | assert vars(adjuster.build_vars) == [ | 563 | assert str_vars(adjuster.build_vars) == [ | |
404 | 'USE_LANGUAGES=c++ fortran' | 564 | 'USE_LANGUAGES=c++ fortran' | |
405 | ] | 565 | ] | |
406 | 566 | |||
407 | 567 | |||
408 | def test_Adjuster_adjust_pkg_config__none(): | 568 | def test_Adjuster_adjust_pkg_config__none(): | |
409 | adjuster = Adjuster() | 569 | adjuster = Adjuster() | |
410 | 570 | |||
411 | adjuster.adjust_pkg_config() | 571 | adjuster.adjust_pkg_config() | |
412 | 572 | |||
413 | assert vars(adjuster.build_vars) == [] | 573 | assert str_vars(adjuster.build_vars) == [] | |
414 | assert vars(adjuster.extra_vars) == [] | 574 | assert str_vars(adjuster.extra_vars) == [] | |
415 | 575 | |||
416 | 576 | |||
417 | def test_Adjuster_adjust_pkg_config__pc_in(): | 577 | def test_Adjuster_adjust_pkg_config__pc_in(): | |
418 | adjuster = Adjuster() | 578 | adjuster = Adjuster() | |
419 | adjuster.wrksrc_files = ['library.pc.in'] | 579 | adjuster.wrksrc_files = ['library.pc.in'] | |
420 | 580 | |||
421 | adjuster.adjust_pkg_config() | 581 | adjuster.adjust_pkg_config() | |
422 | 582 | |||
423 | assert vars(adjuster.build_vars) == ['USE_TOOLS+=pkg-config'] | 583 | assert str_vars(adjuster.build_vars) == ['USE_TOOLS+=pkg-config'] | |
424 | assert vars(adjuster.extra_vars) == ['PKGCONFIG_OVERRIDE+=library.pc.in'] | 584 | assert str_vars(adjuster.extra_vars) == ['PKGCONFIG_OVERRIDE+=library.pc.in'] | |
425 | 585 | |||
426 | 586 | |||
427 | def test_Adjuster_adjust_pkg_config__uninstalled_pc_in(): | 587 | def test_Adjuster_adjust_pkg_config__uninstalled_pc_in(): | |
428 | adjuster = Adjuster() | 588 | adjuster = Adjuster() | |
429 | adjuster.wrksrc_files = ['library-uninstalled.pc.in'] | 589 | adjuster.wrksrc_files = ['library-uninstalled.pc.in'] | |
430 | 590 | |||
431 | adjuster.adjust_pkg_config() | 591 | adjuster.adjust_pkg_config() | |
432 | 592 | |||
433 | assert vars(adjuster.build_vars) == [] | 593 | assert str_vars(adjuster.build_vars) == [] | |
434 | assert vars(adjuster.extra_vars) == [] | 594 | assert str_vars(adjuster.extra_vars) == [] | |
435 | 595 | |||
436 | 596 | |||
437 | def test_Adjuster_adjust_pkg_config__both(): | 597 | def test_Adjuster_adjust_pkg_config__both(): | |
438 | adjuster = Adjuster() | 598 | adjuster = Adjuster() | |
439 | adjuster.wrksrc_files = [ | 599 | adjuster.wrksrc_files = [ | |
440 | 'library.pc.in', | 600 | 'library.pc.in', | |
441 | 'library-uninstalled.pc.in' | 601 | 'library-uninstalled.pc.in' | |
442 | ] | 602 | ] | |
443 | 603 | |||
444 | adjuster.adjust_pkg_config() | 604 | adjuster.adjust_pkg_config() | |
445 | 605 | |||
446 | assert vars(adjuster.build_vars) == ['USE_TOOLS+=pkg-config'] | 606 | assert str_vars(adjuster.build_vars) == ['USE_TOOLS+=pkg-config'] | |
447 | assert vars(adjuster.extra_vars) == ['PKGCONFIG_OVERRIDE+=library.pc.in'] | 607 | assert str_vars(adjuster.extra_vars) == ['PKGCONFIG_OVERRIDE+=library.pc.in'] | |
608 | ||||
609 | ||||
610 | def test_Adjuster__adjust_homepage(): | |||
611 | url = 'https://dummy.example.org/package-1.0.tar.gz' | |||
612 | adjuster = Adjuster() | |||
613 | adjuster.makefile_lines = generate_initial_package_Makefile_lines(url) | |||
614 | adjuster.update_vars['HOMEPAGE'] = 'https://example.org/' | |||
615 | adjuster.depends.append('dependency>=0:../../category/dependency') | |||
616 | adjuster.todos.append('Run pkglint') | |||
617 | ||||
618 | lines = adjuster.generate_adjusted_Makefile_lines(url) | |||
619 | ||||
620 | assert lines.lines == [ | |||
621 | '# $' + 'NetBSD$', | |||
622 | '', | |||
623 | 'DISTNAME=\tpackage-1.0', | |||
624 | 'PKGNAME=\t${DISTNAME}', | |||
625 | 'CATEGORIES=\tpkgtools', | |||
626 | 'MASTER_SITES=\thttps://dummy.example.org/', | |||
627 | '', | |||
628 | 'MAINTAINER=\tINSERT_YOUR_MAIL_ADDRESS_HERE', | |||
629 | 'HOMEPAGE=\thttps://example.org/', | |||
630 | 'COMMENT=\tTODO: Short description of the package', | |||
631 | '#LICENSE=\t# TODO: (see mk/license.mk)', | |||
632 | '', | |||
633 | '# TODO: Run pkglint', | |||
634 | '', | |||
635 | 'DEPENDS+=\tdependency>=0:../../category/dependency', | |||
636 | '', | |||
637 | '.include "../../mk/bsd.pkg.mk"' | |||
638 | ] | |||
639 | ||||
640 | ||||
641 | def test_Adjuster_determine_wrksrc__no_files(tmp_path): | |||
642 | adjuster = Adjuster() | |||
643 | adjuster.abs_wrkdir = str(tmp_path) | |||
644 | ||||
645 | adjuster.determine_wrksrc() | |||
646 | ||||
647 | assert adjuster.abs_wrksrc == adjuster.abs_wrkdir | |||
648 | ||||
649 | ||||
650 | def test_Adjuster_determine_wrksrc__single_dir(tmp_path): | |||
651 | adjuster = Adjuster() | |||
652 | adjuster.abs_wrkdir = str(tmp_path) | |||
653 | (tmp_path / 'subdir').mkdir() | |||
654 | ||||
655 | adjuster.determine_wrksrc() | |||
656 | ||||
657 | assert adjuster.abs_wrksrc == adjuster.abs_wrkdir + '/subdir' | |||
658 | ||||
659 | ||||
660 | def test_Adjuster_determine_wrksrc__several_dirs(tmp_path): | |||
661 | adjuster = Adjuster() | |||
662 | adjuster.abs_wrkdir = str(tmp_path) | |||
663 | (tmp_path / 'subdir1').mkdir() | |||
664 | (tmp_path / 'subdir2').mkdir() | |||
665 | ||||
666 | adjuster.determine_wrksrc() | |||
667 | ||||
668 | assert adjuster.abs_wrksrc == adjuster.abs_wrkdir | |||
669 | assert str_vars(adjuster.build_vars) == [ | |||
670 | 'WRKSRC=${WRKDIR} # More than one possibility -- please check manually.' | |||
671 | ] | |||
672 | ||||
673 | ||||
674 | def test_Adjuster_adjust_package_from_extracted_distfiles__empty_wrkdir(tmp_path): | |||
675 | pkgdir = tmp_path | |||
676 | wrkdir = tmp_path / 'wrkdir' | |||
677 | fake = '''\ | |||
678 | #! /bin/sh | |||
679 | case $* in | |||
680 | ("show-var VARNAME=WRKDIR") echo '%s' ;; | |||
681 | (*) "unknown: $*" ;; | |||
682 | esac | |||
683 | ''' % str(wrkdir) | |||
684 | config.pkgdir = str(tmp_path) | |||
685 | wrkdir.mkdir() | |||
686 | url = 'https://example.org/distfile-1.0.zip' | |||
687 | adjuster = Adjuster() | |||
688 | adjuster.abs_wrkdir = str(wrkdir) | |||
689 | (pkgdir / 'Makefile').write_text('# url2pkg-marker\n') | |||
690 | fake_path = (tmp_path / "fake") | |||
691 | fake_path.write_text(fake) | |||
692 | fake_path.chmod(0o755) | |||
693 | ||||
694 | prev_make = config.make | |||
695 | config.make = fake_path | |||
696 | try: | |||
697 | adjuster.adjust_package_from_extracted_distfiles(url) | |||
698 | finally: | |||
699 | config.make = prev_make | |||
700 | ||||
701 | assert adjuster.generate_adjusted_Makefile_lines(url).lines == [ | |||
702 | 'WRKSRC=\t\t${WRKDIR}', | |||
703 | 'USE_LANGUAGES=\t# none', | |||
704 | '', | |||
705 | ] |