Sun Oct 27 19:19:55 2019 UTC ()
pkgtools/url2pkg: update to 19.3.4

Changes since 19.3.3:

The code that handles license names is the same for Python and Perl
modules.

Python packages that use distutils.extension can be handled. An example
package is devel/py-pysha3.

The DESCR file is filled from the package's README file.

The PLIST is generated with some comments providing further assistance.


(rillig)
diff -r1.106 -r1.107 pkgsrc/pkgtools/url2pkg/Makefile
diff -r1.8 -r1.9 pkgsrc/pkgtools/url2pkg/PLIST
diff -r1.3 -r1.4 pkgsrc/pkgtools/url2pkg/files/Build.pm
diff -r1.13 -r1.14 pkgsrc/pkgtools/url2pkg/files/MakeMaker.pm
diff -r1.6 -r1.7 pkgsrc/pkgtools/url2pkg/files/setuptools.py
diff -r1.23 -r1.24 pkgsrc/pkgtools/url2pkg/files/url2pkg.py
diff -r1.22 -r1.23 pkgsrc/pkgtools/url2pkg/files/url2pkg_test.py

cvs diff -r1.106 -r1.107 pkgsrc/pkgtools/url2pkg/Makefile (expand / switch to unified diff)

--- pkgsrc/pkgtools/url2pkg/Makefile 2019/10/06 12:55:30 1.106
+++ pkgsrc/pkgtools/url2pkg/Makefile 2019/10/27 19:19:54 1.107
@@ -1,16 +1,16 @@ @@ -1,16 +1,16 @@
1# $NetBSD: Makefile,v 1.106 2019/10/06 12:55:30 rillig Exp $ 1# $NetBSD: Makefile,v 1.107 2019/10/27 19:19:54 rillig Exp $
2 2
3PKGNAME= url2pkg-19.3.3 3PKGNAME= url2pkg-19.3.4
4CATEGORIES= pkgtools 4CATEGORIES= pkgtools
5 5
6MAINTAINER= rillig@NetBSD.org 6MAINTAINER= rillig@NetBSD.org
7HOMEPAGE= http://www.NetBSD.org/docs/pkgsrc/creating.html 7HOMEPAGE= http://www.NetBSD.org/docs/pkgsrc/creating.html
8COMMENT= Tool to automate initial steps in building a package 8COMMENT= Tool to automate initial steps in building a package
9LICENSE= 2-clause-bsd 9LICENSE= 2-clause-bsd
10 10
11WRKSRC= ${WRKDIR} 11WRKSRC= ${WRKDIR}
12NO_CHECKSUM= yes 12NO_CHECKSUM= yes
13NO_BUILD= yes 13NO_BUILD= yes
14USE_LANGUAGES= # none 14USE_LANGUAGES= # none
15USE_TOOLS+= perl:run 15USE_TOOLS+= perl:run
16AUTO_MKDIRS= yes 16AUTO_MKDIRS= yes
@@ -31,16 +31,17 @@ SUBST_STAGE.up= do-configure @@ -31,16 +31,17 @@ SUBST_STAGE.up= do-configure
31SUBST_MESSAGE.up= Replacing variable placeholders 31SUBST_MESSAGE.up= Replacing variable placeholders
32SUBST_FILES.up= MakeMaker.pm url2pkg.py 32SUBST_FILES.up= MakeMaker.pm url2pkg.py
33SUBST_VARS.up= MAKE PERL5 PKGSRCDIR PYTHONBIN 33SUBST_VARS.up= MAKE PERL5 PKGSRCDIR PYTHONBIN
34SUBST_SED.up= -e 's,@LIBDIR@,${PREFIX}/lib/url2pkg,g' 34SUBST_SED.up= -e 's,@LIBDIR@,${PREFIX}/lib/url2pkg,g'
35 35
36do-install: 36do-install:
37 ${INSTALL_SCRIPT} ${WRKSRC}/url2pkg.py ${DESTDIR}${PREFIX}/bin/url2pkg 37 ${INSTALL_SCRIPT} ${WRKSRC}/url2pkg.py ${DESTDIR}${PREFIX}/bin/url2pkg
38 ${INSTALL_MAN} ${FILESDIR}/url2pkg.8 ${DESTDIR}${PREFIX}/${PKGMANDIR}/man8 38 ${INSTALL_MAN} ${FILESDIR}/url2pkg.8 ${DESTDIR}${PREFIX}/${PKGMANDIR}/man8
39 ${INSTALL_DATA} ${WRKSRC}/Build.pm ${DESTDIR}${PREFIX}/lib/url2pkg/Module/ 39 ${INSTALL_DATA} ${WRKSRC}/Build.pm ${DESTDIR}${PREFIX}/lib/url2pkg/Module/
40 ${INSTALL_DATA} ${WRKSRC}/MakeMaker.pm ${DESTDIR}${PREFIX}/lib/url2pkg/ExtUtils/ 40 ${INSTALL_DATA} ${WRKSRC}/MakeMaker.pm ${DESTDIR}${PREFIX}/lib/url2pkg/ExtUtils/
41 ${INSTALL_DATA} ${WRKSRC}/setuptools.py ${DESTDIR}${PREFIX}/lib/url2pkg/ 41 ${INSTALL_DATA} ${WRKSRC}/setuptools.py ${DESTDIR}${PREFIX}/lib/url2pkg/
42 ${INSTALL_DATA} /dev/null ${DESTDIR}${PREFIX}/lib/url2pkg/distutils/__init__.py 42 ${INSTALL_DATA} /dev/null ${DESTDIR}${PREFIX}/lib/url2pkg/distutils/__init__.py
43 ${INSTALL_DATA} ${WRKSRC}/setuptools.py ${DESTDIR}${PREFIX}/lib/url2pkg/distutils/core.py 43 ${INSTALL_DATA} ${WRKSRC}/setuptools.py ${DESTDIR}${PREFIX}/lib/url2pkg/distutils/core.py
 44 ${INSTALL_DATA} ${WRKSRC}/setuptools.py ${DESTDIR}${PREFIX}/lib/url2pkg/distutils/extension.py
44 45
45.include "../../lang/python/application.mk" 46.include "../../lang/python/application.mk"
46.include "../../mk/bsd.pkg.mk" 47.include "../../mk/bsd.pkg.mk"

cvs diff -r1.8 -r1.9 pkgsrc/pkgtools/url2pkg/PLIST (expand / switch to unified diff)

--- pkgsrc/pkgtools/url2pkg/PLIST 2019/10/06 12:55:30 1.8
+++ pkgsrc/pkgtools/url2pkg/PLIST 2019/10/27 19:19:54 1.9
@@ -1,8 +1,9 @@ @@ -1,8 +1,9 @@
1@comment $NetBSD: PLIST,v 1.8 2019/10/06 12:55:30 rillig Exp $ 1@comment $NetBSD: PLIST,v 1.9 2019/10/27 19:19:54 rillig Exp $
2bin/url2pkg 2bin/url2pkg
3lib/url2pkg/ExtUtils/MakeMaker.pm 3lib/url2pkg/ExtUtils/MakeMaker.pm
4lib/url2pkg/Module/Build.pm 4lib/url2pkg/Module/Build.pm
5lib/url2pkg/distutils/__init__.py 5lib/url2pkg/distutils/__init__.py
6lib/url2pkg/distutils/core.py 6lib/url2pkg/distutils/core.py
 7lib/url2pkg/distutils/extension.py
7lib/url2pkg/setuptools.py 8lib/url2pkg/setuptools.py
8man/man8/url2pkg.8 9man/man8/url2pkg.8

cvs diff -r1.3 -r1.4 pkgsrc/pkgtools/url2pkg/files/Build.pm (expand / switch to unified diff)

--- pkgsrc/pkgtools/url2pkg/files/Build.pm 2019/09/13 05:19:27 1.3
+++ pkgsrc/pkgtools/url2pkg/files/Build.pm 2019/10/27 19:19:55 1.4
@@ -46,44 +46,48 @@ sub url2pkg_write_dependencies($$$) { @@ -46,44 +46,48 @@ sub url2pkg_write_dependencies($$$) {
46 my $deps = $self->{$key}; 46 my $deps = $self->{$key};
47 foreach my $item (keys %$deps) { 47 foreach my $item (keys %$deps) {
48 my $pkgbase = "p5-$item" =~ s/::/-/gr; 48 my $pkgbase = "p5-$item" =~ s/::/-/gr;
49 printf("%s\t%s>=%s\n", $varname, $pkgbase, $deps->{$item}); 49 printf("%s\t%s>=%s\n", $varname, $pkgbase, $deps->{$item});
50 } 50 }
51} 51}
52 52
53sub url2pkg_write_var($$$) { 53sub url2pkg_write_var($$$) {
54 my ($self, $varname, $value) = @_; 54 my ($self, $varname, $value) = @_;
55 return unless defined($value) && $value ne ""; 55 return unless defined($value) && $value ne "";
56 printf("var\t%s\t%s\n", $varname, $value); 56 printf("var\t%s\t%s\n", $varname, $value);
57} 57}
58 58
 59sub url2pkg_write_cmd($$) {
 60 my ($self, $cmd, $arg) = @_;
 61 printf("cmd\t%s\t%s\n", $cmd, $arg);
 62}
 63
59sub VERSION($$) { 64sub VERSION($$) {
60 my ($class, $min_version) = @_; 65 my ($class, $min_version) = @_;
61 return $min_version <= $VERSION; 66 return $min_version <= $VERSION;
62} 67}
63 68
64sub new(%) { 69sub new(%) {
65 my ($class, %args) = @_; 70 my ($class, %args) = @_;
66 my $self = \%args; 71 my $self = \%args;
67 bless($self, $class); 72 bless($self, $class);
68 return $self; 73 return $self;
69} 74}
70 75
71sub create_build_script($) { 76sub create_build_script($) {
72 my ($self) = @_; 77 my ($self) = @_;
73 78
74 $self->url2pkg_write_dependencies("BUILD_DEPENDS", "configure_requires"); 79 $self->url2pkg_write_dependencies("BUILD_DEPENDS", "configure_requires");
75 $self->url2pkg_write_dependencies("BUILD_DEPENDS", "build_requires"); 80 $self->url2pkg_write_dependencies("BUILD_DEPENDS", "build_requires");
76 $self->url2pkg_write_dependencies("DEPENDS", "requires"); 81 $self->url2pkg_write_dependencies("DEPENDS", "requires");
77 $self->url2pkg_write_dependencies("TEST_DEPENDS", "test_requires"); 82 $self->url2pkg_write_dependencies("TEST_DEPENDS", "test_requires");
78 $self->url2pkg_write_dependencies("#RECOMMENDS", "recommends"); 83 $self->url2pkg_write_dependencies("#RECOMMENDS", "recommends");
79 84
80 $self->url2pkg_write_var("COMMENT", $self->{"dist_abstract"}); 85 $self->url2pkg_write_var("COMMENT", $self->{"dist_abstract"});
81 my $license = $self->{"license"} || ""; 86 my $license = $self->{"license"} || "";
82 if ($license eq "perl") { 87 if ($license ne "") {
83 $self->url2pkg_write_var("LICENSE", "\${PERL5_LICENSE}"); 88 $self->url2pkg_write_cmd("license", $license);
84 } elsif ($license ne "") { 89 $self->url2pkg_write_var("license_default", "# TODO: $license (from Build.PL)")
85 $self->url2pkg_write_var("#LICENSE", "# TODO: $license (from Build.PL)") 
86 } 90 }
87} 91}
88 92
891; 931;

cvs diff -r1.13 -r1.14 pkgsrc/pkgtools/url2pkg/files/MakeMaker.pm (expand / switch to unified diff)

--- pkgsrc/pkgtools/url2pkg/files/MakeMaker.pm 2019/10/02 15:57:37 1.13
+++ pkgsrc/pkgtools/url2pkg/files/MakeMaker.pm 2019/10/27 19:19:55 1.14
@@ -89,46 +89,50 @@ sub url2pkg_write_dependency($$$) { @@ -89,46 +89,50 @@ sub url2pkg_write_dependency($$$) {
89 # If the package does not exist but the Perl module can be loaded, assume 89 # If the package does not exist but the Perl module can be loaded, assume
90 # that it is a built-in module and no dependency declaration is needed. 90 # that it is a built-in module and no dependency declaration is needed.
91 return if eval("use $dep $ver; 1;"); 91 return if eval("use $dep $ver; 1;");
92 92
93 printf("%s\t%s>=%s\n", $type, $pkgbase, $ver); 93 printf("%s\t%s>=%s\n", $type, $pkgbase, $ver);
94} 94}
95 95
96sub url2pkg_write_var($$) { 96sub url2pkg_write_var($$) {
97 my ($varname, $value) = @_; 97 my ($varname, $value) = @_;
98 return unless defined($value) && $value ne ""; 98 return unless defined($value) && $value ne "";
99 printf("var\t%s\t%s\n", $varname, $value); 99 printf("var\t%s\t%s\n", $varname, $value);
100} 100}
101 101
 102sub url2pkg_write_cmd($$) {
 103 my ($cmd, $arg) = @_;
 104 printf("cmd\t%s\t%s\n", $cmd, $arg);
 105}
 106
102sub url2pkg_write_depends($$) { 107sub url2pkg_write_depends($$) {
103 my ($type, $deps) = @_; 108 my ($type, $deps) = @_;
104 109
105 return unless $deps; 110 return unless defined $deps;
106 foreach my $dep (sort(keys(%$deps))) { 111 foreach my $dep (sort(keys(%$deps))) {
107 url2pkg_write_dependency($type, $dep, $deps->{$dep}); 112 url2pkg_write_dependency($type, $dep, $deps->{$dep});
108 } 113 }
109} 114}
110 115
111sub WriteMakefile(%) { 116sub WriteMakefile(%) {
112 my (%options) = @_; 117 my (%options) = @_;
113 118
114 url2pkg_write_depends("DEPENDS", $options{"PREREQ_PM"}); 119 url2pkg_write_depends("DEPENDS", $options{"PREREQ_PM"});
115 url2pkg_write_depends("TEST_DEPENDS", $options{"TEST_DEPENDS"}); 120 url2pkg_write_depends("TEST_DEPENDS", $options{"TEST_DEPENDS"});
116 121
117 my $license = $options{"LICENSE"} || ""; 122 my $license = $options{"LICENSE"} || "";
118 if ($license eq "perl") { 123 if ($license ne "") {
119 url2pkg_write_var("LICENSE", "\${PERL5_LICENSE}"); 124 url2pkg_write_cmd("license", $license);
120 } elsif ($license ne "") { 125 url2pkg_write_cmd("license_default", "# TODO: $license (from Makefile.PL)");
121 url2pkg_write_var("#LICENSE", "# TODO: $license (from Makefile.PL)") 
122 } 126 }
123} 127}
124 128
125sub prompt(@) { 129sub prompt(@) {
126 my ($message, $default) = @_; 130 my ($message, $default) = @_;
127 131
128 return $default || ""; 132 return $default || "";
129} 133}
130 134
131sub neatvalue { 135sub neatvalue {
132 return; 136 return;
133} 137}
134 138

cvs diff -r1.6 -r1.7 pkgsrc/pkgtools/url2pkg/files/Attic/setuptools.py (expand / switch to unified diff)

--- pkgsrc/pkgtools/url2pkg/files/Attic/setuptools.py 2019/10/27 13:15:04 1.6
+++ pkgsrc/pkgtools/url2pkg/files/Attic/setuptools.py 2019/10/27 19:19:55 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: setuptools.py,v 1.6 2019/10/27 13:15:04 rillig Exp $ 1# $NetBSD: setuptools.py,v 1.7 2019/10/27 19:19:55 rillig Exp $
2 2
3# This is a drop-in replacement for the setuptools Python module. Instead 3# This is a drop-in replacement for the setuptools Python module. Instead
4# of actually searching for the dependencies, it extracts the dependency 4# of actually searching for the dependencies, it extracts the dependency
5# information and includes it in the generated pkgsrc package Makefile. 5# information and includes it in the generated pkgsrc package Makefile.
6 6
7 7
8def url2pkg_print_depends(varname, depends): 8def url2pkg_print_depends(varname, depends):
9 for dep in depends: 9 for dep in depends:
10 print('%s\t%s%s' % (varname, dep.replace(' ', ''), '' if '>' in dep else '>=0')) 10 print('%s\t%s%s' % (varname, dep.replace(' ', ''), '' if '>' in dep else '>=0'))
11 11
12 12
13def url2pkg_print_var(varname, value): 13def url2pkg_print_var(varname, value):
14 if value != '': 14 if value != '':
@@ -34,13 +34,24 @@ def setup(**kwargs): @@ -34,13 +34,24 @@ def setup(**kwargs):
34 url2pkg_print_depends('TEST_DEPENDS', kwargs.get('tests_require', [])) 34 url2pkg_print_depends('TEST_DEPENDS', kwargs.get('tests_require', []))
35 url2pkg_print_depends('BUILD_DEPENDS', kwargs.get('extras_require', {}).get('dev', [])) 35 url2pkg_print_depends('BUILD_DEPENDS', kwargs.get('extras_require', {}).get('dev', []))
36 url2pkg_print_depends('BUILD_DEPENDS', kwargs.get('setup_requires', [])) 36 url2pkg_print_depends('BUILD_DEPENDS', kwargs.get('setup_requires', []))
37 url2pkg_print_var('COMMENT', kwargs.get('description', '').rstrip('.')) 37 url2pkg_print_var('COMMENT', kwargs.get('description', '').rstrip('.'))
38 url2pkg_print_var('HOMEPAGE', kwargs.get('url', '')) 38 url2pkg_print_var('HOMEPAGE', kwargs.get('url', ''))
39 url2pkg_print_license(kwargs.get('license', '')) 39 url2pkg_print_license(kwargs.get('license', ''))
40 40
41 # TODO: python_requires (see devel/py-futures) 41 # TODO: python_requires (see devel/py-futures)
42 # example: '>=2.6, <3, >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*') 42 # example: '>=2.6, <3, >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*')
43 43
44 44
45def find_packages(where='.', exclude=(), include=('*',)): 45def find_packages(where='.', exclude=(), include=('*',)):
46 return [] 46 return []
 47
 48
 49# for distutils.core; see devel/py-pysha3-1.0.2 for an example
 50class Command:
 51 pass
 52
 53
 54# for distutils.extension; see devel/py-pysha3-1.0.2 for an example
 55class Extension:
 56 def __init__(self, *args, **kwargs):
 57 pass

cvs diff -r1.23 -r1.24 pkgsrc/pkgtools/url2pkg/files/url2pkg.py (expand / switch to unified diff)

--- pkgsrc/pkgtools/url2pkg/files/url2pkg.py 2019/10/27 13:15:04 1.23
+++ pkgsrc/pkgtools/url2pkg/files/url2pkg.py 2019/10/27 19:19:55 1.24
@@ -1,15 +1,15 @@ @@ -1,15 +1,15 @@
1#! @PYTHONBIN@ 1#! @PYTHONBIN@
2# $NetBSD: url2pkg.py,v 1.23 2019/10/27 13:15:04 rillig Exp $ 2# $NetBSD: url2pkg.py,v 1.24 2019/10/27 19:19:55 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
@@ -112,45 +112,47 @@ class Globals: @@ -112,45 +112,47 @@ class Globals:
112 subprocess.check_call([self.make, *args], cwd=self.pkgdir) 112 subprocess.check_call([self.make, *args], cwd=self.pkgdir)
113 113
114 def show_var(self, varname: str) -> str: 114 def show_var(self, varname: str) -> str:
115 output = subprocess.check_output((self.make, 'show-var', 'VARNAME=' + varname)) 115 output = subprocess.check_output((self.make, 'show-var', 'VARNAME=' + varname))
116 return output.decode('utf-8').strip() 116 return output.decode('utf-8').strip()
117 117
118 def pkgsrc_license(self, license_name: str) -> str: 118 def pkgsrc_license(self, license_name: str) -> str:
119 known_licenses = ( 119 known_licenses = (
120 ('', 120 ('',
121 'Apache Software License', # too unspecific; needs a version number 121 'Apache Software License', # too unspecific; needs a version number
122 'BSD'), # too unspecific, may be 2-clause, 3-clause, 4-clause 122 'BSD'), # too unspecific, may be 2-clause, 3-clause, 4-clause
123 ('${PERL5_LICENSE}', 'perl'), 123 ('${PERL5_LICENSE}', 'perl'),
124 ('apache-2.0', 'Apache 2', 'Apache 2.0'), 124 ('apache-2.0', 'Apache 2', 'Apache 2.0'),
 125 ('artistic-2.0', 'artistic_2'),
125 ('gnu-gpl-v3', 'GNU Lesser General Public License (LGPL), Version 3'), 126 ('gnu-gpl-v3', 'GNU Lesser General Public License (LGPL), Version 3'),
126 ('gnu-lgpl-v2', 'LGPL'), 127 ('gnu-lgpl-v2', 'LGPL'),
127 ('mit', 'MIT', 'MIT License'), 128 ('mit', 'MIT', 'MIT License'),
128 ('python-software-foundation', 129 ('python-software-foundation',
129 'PSF', 'PSF license', 'Python Software Foundation License'), 130 'PSF', 'PSF license', 'Python Software Foundation License'),
130 ('zpl-2.1', 'ZPL 2.1'), 131 ('zpl-2.1', 'ZPL 2.1'),
131 ) 132 )
132 133
133 for known_license in known_licenses: 134 for known_license in known_licenses:
134 if license_name in known_license: 135 if license_name in known_license:
135 return known_license[0] 136 return known_license[0]
136 if (self.pkgsrcdir / 'licenses' / license_name).is_file(): 137 if (self.pkgsrcdir / 'licenses' / license_name).is_file():
137 return license_name 138 return license_name
138 return '' 139 return ''
139 140
 141
140class Lines: 142class Lines:
141 """ 143 """
142 A list of Makefile lines with high-level methods for manipulating 144 A list of lines (typically from a Makefile, but other file types work as
143 variable assignments. 145 well) with high-level methods for manipulating variable assignments.
144 """ 146 """
145 lines: List[str] 147 lines: List[str]
146 148
147 def __init__(self, *lines: str) -> None: 149 def __init__(self, *lines: str) -> None:
148 self.lines = [] 150 self.lines = []
149 for line in lines: 151 for line in lines:
150 self.add(line) 152 self.add(line)
151 153
152 @classmethod 154 @classmethod
153 def read_from(cls, src: Union[Path, Any]) -> 'Lines': 155 def read_from(cls, src: Union[Path, Any]) -> 'Lines':
154 return Lines(*src.read_text().splitlines()) 156 return Lines(*src.read_text().splitlines())
155 157
156 def write_to(self, dst: Union[Path, Any]): 158 def write_to(self, dst: Union[Path, Any]):
@@ -473,38 +475,43 @@ class Generator: @@ -473,38 +475,43 @@ class Generator:
473 475
474 def generate_Makefile(self) -> Lines: 476 def generate_Makefile(self) -> Lines:
475 self.adjust_site_SourceForge() 477 self.adjust_site_SourceForge()
476 self.adjust_site_GitHub_archive() 478 self.adjust_site_GitHub_archive()
477 self.adjust_site_GitHub_release() 479 self.adjust_site_GitHub_release()
478 self.foreach_site_from_sites_mk(self.adjust_site_from_sites_mk) 480 self.foreach_site_from_sites_mk(self.adjust_site_from_sites_mk)
479 self.adjust_site_other() 481 self.adjust_site_other()
480 self.adjust_everything_else() 482 self.adjust_everything_else()
481 return self.generate_lines() 483 return self.generate_lines()
482 484
483 def generate_package(self, g: Globals) -> Lines: 485 def generate_package(self, g: Globals) -> Lines:
484 pkgdir = g.pkgdir 486 pkgdir = g.pkgdir
485 makefile = pkgdir / 'Makefile' 487 makefile = pkgdir / 'Makefile'
486 descr = pkgdir / 'DESCR' 
487 plist = pkgdir / 'PLIST' 488 plist = pkgdir / 'PLIST'
488 489
489 initial_lines = self.generate_Makefile() 490 initial_lines = self.generate_Makefile()
490 491
491 try: 492 try:
492 makefile.replace(f'{makefile}.url2pkg~') 493 makefile.replace(f'{makefile}.url2pkg~')
493 except OSError: 494 except OSError:
494 pass 495 pass
495 initial_lines.write_to(makefile) 496 initial_lines.write_to(makefile)
496 plist.is_file() or Lines('@comment $''NetBSD$').write_to(plist) 497
497 descr.is_file() or Lines().write_to(descr) 498 plist_lines = [
 499 f'@comment $''NetBSD$',
 500 f'@comment TODO: to fill this file with the file listing:',
 501 f'@comment TODO: 1. run "{g.make} package"',
 502 f'@comment TODO: 2. run "{g.make} print-PLIST"'
 503 ]
 504 plist.is_file() or Lines(*plist_lines).write_to(plist)
498 505
499 subprocess.check_call([g.editor, makefile]) 506 subprocess.check_call([g.editor, makefile])
500 507
501 g.bmake('clean', 'distinfo', 'extract') 508 g.bmake('clean', 'distinfo', 'extract')
502 509
503 return initial_lines 510 return initial_lines
504 511
505 512
506class Adjuster: 513class Adjuster:
507 """ 514 """
508 After the distfile has been downloaded and extracted, the 515 After the distfile has been downloaded and extracted, the
509 adjust_* methods of this class inspect the extracted files 516 adjust_* methods of this class inspect the extracted files
510 and adjust the variable definitions in the package Makefile. 517 and adjust the variable definitions in the package Makefile.
@@ -560,47 +567,50 @@ class Adjuster: @@ -560,47 +567,50 @@ class Adjuster:
560 # these are inserted below the second paragraph in the Makefile. 567 # these are inserted below the second paragraph in the Makefile.
561 todos: List[str] 568 todos: List[str]
562 569
563 # the package name is based on DISTNAME and modified by 570 # the package name is based on DISTNAME and modified by
564 # pkgname_prefix and pkgname_transform. 571 # pkgname_prefix and pkgname_transform.
565 pkgname_prefix: str # example: ${PYPKGPREFIX}- 572 pkgname_prefix: str # example: ${PYPKGPREFIX}-
566 pkgname_transform: str # example: :S,-v,-, 573 pkgname_transform: str # example: :S,-v,-,
567 574
568 # all lines of the package Makefile, for direct modification. 575 # all lines of the package Makefile, for direct modification.
569 makefile_lines: Lines 576 makefile_lines: Lines
570 577
571 regenerate_distinfo: bool 578 regenerate_distinfo: bool
572 579
 580 descr_lines: List[str]
 581
573 def __init__(self, g: Globals, url: str, initial_lines: Lines): 582 def __init__(self, g: Globals, url: str, initial_lines: Lines):
574 self.g = g 583 self.g = g
575 self.url = url 584 self.url = url
576 self.initial_lines = initial_lines 585 self.initial_lines = initial_lines
577 self.abs_wrkdir = Path('') 586 self.abs_wrkdir = Path('')
578 self.abs_wrksrc = Path('') 587 self.abs_wrksrc = Path('')
579 self.wrksrc_files = [] 588 self.wrksrc_files = []
580 self.wrksrc_dirs = [] 589 self.wrksrc_dirs = []
581 self.categories = [] 590 self.categories = []
582 self.depends = [] 591 self.depends = []
583 self.build_depends = [] 592 self.build_depends = []
584 self.test_depends = [] 593 self.test_depends = []
585 self.bl3_lines = [] 594 self.bl3_lines = []
586 self.includes = [] 595 self.includes = []
587 self.build_vars = [] 596 self.build_vars = []
588 self.extra_vars = [] 597 self.extra_vars = []
589 self.todos = [] 598 self.todos = []
590 self.pkgname_prefix = '' 599 self.pkgname_prefix = ''
591 self.pkgname_transform = '' 600 self.pkgname_transform = ''
592 self.makefile_lines = Lines() 601 self.makefile_lines = Lines()
593 self.regenerate_distinfo = False 602 self.regenerate_distinfo = False
 603 self.descr_lines = []
594 604
595 def add_dependency(self, kind: str, pkgbase: str, constraint: str, dep_dir: str) -> None: 605 def add_dependency(self, kind: str, pkgbase: str, constraint: str, dep_dir: str) -> None:
596 """ add_dependency('DEPENDS', 'package', '>=1', '../../category/package') """ 606 """ add_dependency('DEPENDS', 'package', '>=1', '../../category/package') """
597 607
598 self.g.debug('add_dependency: {0} {1} {2} {3}', kind, pkgbase, constraint, dep_dir) 608 self.g.debug('add_dependency: {0} {1} {2} {3}', kind, pkgbase, constraint, dep_dir)
599 609
600 def bl3_identifier(): 610 def bl3_identifier():
601 try: 611 try:
602 with open(dep_dir + '/buildlink3.mk') as f: 612 with open(dep_dir + '/buildlink3.mk') as f:
603 for line in f: 613 for line in f:
604 m = re.search(r'^BUILDLINK_TREE\+=\s*(\S+)$', line) 614 m = re.search(r'^BUILDLINK_TREE\+=\s*(\S+)$', line)
605 if m: 615 if m:
606 return m[1] 616 return m[1]
@@ -688,49 +698,72 @@ class Adjuster: @@ -688,49 +698,72 @@ class Adjuster:
688 if not self.makefile_lines.set(varname, value): 698 if not self.makefile_lines.set(varname, value):
689 self.extra_vars.append(Var(varname, '=', value)) 699 self.extra_vars.append(Var(varname, '=', value))
690 700
691 def set_license(self, license_name: str, license_default: str): 701 def set_license(self, license_name: str, license_default: str):
692 pkgsrc_license_name = self.g.pkgsrc_license(license_name) 702 pkgsrc_license_name = self.g.pkgsrc_license(license_name)
693 if pkgsrc_license_name != '': 703 if pkgsrc_license_name != '':
694 self.set_or_add('LICENSE', pkgsrc_license_name) 704 self.set_or_add('LICENSE', pkgsrc_license_name)
695 elif license_default != '': 705 elif license_default != '':
696 self.set_or_add('#LICENSE', license_default) 706 self.set_or_add('#LICENSE', license_default)
697 707
698 def wrksrc_open(self, relative_pathname: str): 708 def wrksrc_open(self, relative_pathname: str):
699 return (self.abs_wrksrc / relative_pathname).open() 709 return (self.abs_wrksrc / relative_pathname).open()
700 710
 711 def wrksrc_head(self, relative_pathname: str, n: int):
 712 try:
 713 with (self.abs_wrksrc / relative_pathname).open(encoding="UTF-8") as f:
 714 return f.read().splitlines()[:n]
 715 except IOError:
 716 return []
 717
701 def wrksrc_find(self, what: Union[str, Callable[[str], bool]]) -> List[str]: 718 def wrksrc_find(self, what: Union[str, Callable[[str], bool]]) -> List[str]:
702 def search(f): 719 def search(f):
703 return re.search(what, f) if type(what) == str else what(f) 720 return re.search(what, f) if type(what) == str else what(f)
704 721
705 return list(sorted(filter(search, self.wrksrc_files))) 722 return list(sorted(filter(search, self.wrksrc_files)))
706 723
707 def wrksrc_grep(self, filename: str, pattern: str) -> List[Union[str, List[str]]]: 724 def wrksrc_grep(self, filename: str, pattern: str) -> List[Union[str, List[str]]]:
708 with self.wrksrc_open(filename) as f: 725 with self.wrksrc_open(filename) as f:
709 matches = [] 726 matches = []
710 for line in f: 727 for line in f:
711 line = line.rstrip('\n') 728 line = line.rstrip('\n')
712 m = re.search(pattern, line) 729 m = re.search(pattern, line)
713 if m: 730 if m:
714 groups = list(m.groups()) 731 groups = list(m.groups())
715 matches.append(groups if groups else line) 732 matches.append(groups if groups else line)
716 return matches 733 return matches
717 734
718 def wrksrc_isdir(self, relative_pathname: str) -> bool: 735 def wrksrc_isdir(self, relative_pathname: str) -> bool:
719 return (self.abs_wrksrc / relative_pathname).is_dir() 736 return (self.abs_wrksrc / relative_pathname).is_dir()
720 737
721 def wrksrc_isfile(self, relative_pathname: str) -> bool: 738 def wrksrc_isfile(self, relative_pathname: str) -> bool:
722 return (self.abs_wrksrc / relative_pathname).is_file() 739 return (self.abs_wrksrc / relative_pathname).is_file()
723 740
 741 def adjust_descr(self):
 742 for filename in ('README', 'README.txt', 'README.md'):
 743 lines = self.wrksrc_head(filename, 21)
 744 if len(lines) == 21:
 745 lines[-1] = '...'
 746 if lines:
 747 self.descr_lines = [
 748 f'TODO: Adjust the following lines from {filename}',
 749 '',
 750 *lines]
 751 return
 752
 753 self.descr_lines = [
 754 'TODO: Fill in a short description of the package.',
 755 'TODO: It should be between 3 and 20 lines.']
 756
724 def adjust_configure(self): 757 def adjust_configure(self):
725 if not self.wrksrc_isfile('configure'): 758 if not self.wrksrc_isfile('configure'):
726 return 759 return
727 760
728 configures = self.wrksrc_find(r'(^|/)configure$') 761 configures = self.wrksrc_find(r'(^|/)configure$')
729 if configures: 762 if configures:
730 gnu = any(self.wrksrc_grep(configure, r'\b(Free Software Foundation|autoconf)\b') 763 gnu = any(self.wrksrc_grep(configure, r'\b(Free Software Foundation|autoconf)\b')
731 for configure in configures) 764 for configure in configures)
732 varname = 'GNU_CONFIGURE' if gnu else 'HAS_CONFIGURE' 765 varname = 'GNU_CONFIGURE' if gnu else 'HAS_CONFIGURE'
733 self.build_vars.append(Var(varname, '=', 'yes')) 766 self.build_vars.append(Var(varname, '=', 'yes'))
734 767
735 def adjust_cmake(self): 768 def adjust_cmake(self):
736 if self.wrksrc_isfile('CMakeLists.txt'): 769 if self.wrksrc_isfile('CMakeLists.txt'):
@@ -755,27 +788,27 @@ class Adjuster: @@ -755,27 +788,27 @@ class Adjuster:
755 if self.wrksrc_isdir('libltdl'): 788 if self.wrksrc_isdir('libltdl'):
756 self.includes.append('../../devel/libltdl/convenience.mk') 789 self.includes.append('../../devel/libltdl/convenience.mk')
757 790
758 def adjust_perl_module_Build_PL(self): 791 def adjust_perl_module_Build_PL(self):
759 # Example packages: 792 # Example packages:
760 # devel/p5-Algorithm-CheckDigits 793 # devel/p5-Algorithm-CheckDigits
761 794
762 cmd = f'{self.g.perl5} -I{self.g.libdir} -I. Build.PL' 795 cmd = f'{self.g.perl5} -I{self.g.libdir} -I. Build.PL'
763 self.read_dependencies(cmd, {}, self.abs_wrksrc, '') 796 self.read_dependencies(cmd, {}, self.abs_wrksrc, '')
764 self.build_vars.append(Var('PERL5_MODULE_TYPE', '=', 'Module::Build')) 797 self.build_vars.append(Var('PERL5_MODULE_TYPE', '=', 'Module::Build'))
765 798
766 def adjust_perl_module_Makefile_PL(self): 799 def adjust_perl_module_Makefile_PL(self):
767 # Example packages: 800 # Example packages:
768 # devel/p5-Algorithm-Diff (no dependencies) 801 # devel/p5-Algorithm-Diff (no dependencies, no license)
769 # devel/p5-Carp-Assert-More (dependencies without version numbers) 802 # devel/p5-Carp-Assert-More (dependencies without version numbers)
770 # www/p5-HTML-Quoted (dependency with version number) 803 # www/p5-HTML-Quoted (dependency with version number)
771 804
772 # To avoid fix_up_makefile error for p5-HTML-Quoted, generate Makefile first. 805 # To avoid fix_up_makefile error for p5-HTML-Quoted, generate Makefile first.
773 cmd1 = f'{self.g.perl5} -I. Makefile.PL </dev/null 1>&0 2>&0' 806 cmd1 = f'{self.g.perl5} -I. Makefile.PL </dev/null 1>&0 2>&0'
774 subprocess.call(cmd1, shell=True, cwd=self.abs_wrksrc) 807 subprocess.call(cmd1, shell=True, cwd=self.abs_wrksrc)
775 808
776 cmd2 = f'{self.g.perl5} -I{self.g.libdir} -I. Makefile.PL' 809 cmd2 = f'{self.g.perl5} -I{self.g.libdir} -I. Makefile.PL'
777 self.read_dependencies(cmd2, {}, self.abs_wrksrc, '') 810 self.read_dependencies(cmd2, {}, self.abs_wrksrc, '')
778 811
779 def adjust_perl_module_homepage(self): 812 def adjust_perl_module_homepage(self):
780 if '${MASTER_SITE_PERL_CPAN:' not in self.makefile_lines.get('MASTER_SITES'): 813 if '${MASTER_SITE_PERL_CPAN:' not in self.makefile_lines.get('MASTER_SITES'):
781 return 814 return
@@ -980,39 +1013,42 @@ class Adjuster: @@ -980,39 +1013,42 @@ class Adjuster:
980 def scan(basedir: Union[Path, Any], only: Callable[[Path], bool]) -> List[str]: 1013 def scan(basedir: Union[Path, Any], only: Callable[[Path], bool]) -> List[str]:
981 relevant = (f for f in basedir.rglob('*') if only(f)) 1014 relevant = (f for f in basedir.rglob('*') if only(f))
982 relative = (str(f.relative_to(basedir)) for f in relevant) 1015 relative = (str(f.relative_to(basedir)) for f in relevant)
983 return list(sorted((f for f in relative if not f.startswith('.')))) 1016 return list(sorted((f for f in relative if not f.startswith('.'))))
984 1017
985 self.g.debug('Adjusting the Makefile') 1018 self.g.debug('Adjusting the Makefile')
986 self.makefile_lines = Lines.read_from(self.g.pkgdir / 'Makefile') 1019 self.makefile_lines = Lines.read_from(self.g.pkgdir / 'Makefile')
987 1020
988 self.abs_wrkdir = Path(self.g.show_var('WRKDIR')) 1021 self.abs_wrkdir = Path(self.g.show_var('WRKDIR'))
989 self.determine_wrksrc() 1022 self.determine_wrksrc()
990 self.wrksrc_dirs = scan(self.abs_wrksrc, Path.is_dir) 1023 self.wrksrc_dirs = scan(self.abs_wrksrc, Path.is_dir)
991 self.wrksrc_files = scan(self.abs_wrksrc, Path.is_file) 1024 self.wrksrc_files = scan(self.abs_wrksrc, Path.is_file)
992 1025
 1026 self.adjust_descr()
993 self.adjust_configure() 1027 self.adjust_configure()
994 self.adjust_cmake() 1028 self.adjust_cmake()
995 self.adjust_meson() 1029 self.adjust_meson()
996 self.adjust_gconf2_schemas() 1030 self.adjust_gconf2_schemas()
997 self.adjust_libtool() 1031 self.adjust_libtool()
998 self.adjust_perl_module() 1032 self.adjust_perl_module()
999 self.adjust_python_module() 1033 self.adjust_python_module()
1000 self.adjust_cargo() 1034 self.adjust_cargo()
1001 self.adjust_pkg_config() 1035 self.adjust_pkg_config()
1002 self.adjust_po() 1036 self.adjust_po()
1003 self.adjust_use_languages() 1037 self.adjust_use_languages()
1004 1038
1005 self.generate_lines().write_to(self.g.pkgdir / 'Makefile') 1039 self.generate_lines().write_to(self.g.pkgdir / 'Makefile')
 1040 descr = (self.g.pkgdir / 'DESCR')
 1041 descr.is_file() or Lines(*self.descr_lines).write_to(descr)
1006 1042
1007 if self.regenerate_distinfo: 1043 if self.regenerate_distinfo:
1008 self.g.bmake('distinfo') 1044 self.g.bmake('distinfo')
1009 1045
1010 1046
1011def main(argv: List[str], g: Globals): 1047def main(argv: List[str], g: Globals):
1012 if not os.path.isfile('../../mk/bsd.pkg.mk'): 1048 if not os.path.isfile('../../mk/bsd.pkg.mk'):
1013 sys.exit(f'{argv[0]}: must be run from a package directory (.../pkgsrc/category/package)') 1049 sys.exit(f'{argv[0]}: must be run from a package directory (.../pkgsrc/category/package)')
1014 1050
1015 try: 1051 try:
1016 opts, args = getopt.getopt(argv[1:], 'v', ['verbose']) 1052 opts, args = getopt.getopt(argv[1:], 'v', ['verbose'])
1017 for (opt, _) in opts: 1053 for (opt, _) in opts:
1018 if opt in ('-v', '--verbose'): 1054 if opt in ('-v', '--verbose'):

cvs diff -r1.22 -r1.23 pkgsrc/pkgtools/url2pkg/files/url2pkg_test.py (expand / switch to unified diff)

--- pkgsrc/pkgtools/url2pkg/files/url2pkg_test.py 2019/10/27 13:15:04 1.22
+++ pkgsrc/pkgtools/url2pkg/files/url2pkg_test.py 2019/10/27 19:19:55 1.23
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: url2pkg_test.py,v 1.22 2019/10/27 13:15:04 rillig Exp $ 1# $NetBSD: url2pkg_test.py,v 1.23 2019/10/27 19:19:55 rillig Exp $
2 2
3import pytest 3import pytest
4from url2pkg import * 4from url2pkg import *
5 5
6mkcvsid = '# $''NetBSD$' 6mkcvsid = '# $''NetBSD$'
7g: Globals 7g: Globals
8prev_dir = Path.cwd() 8prev_dir = Path.cwd()
9 9
10 10
11def setup_function(_): 11def setup_function(_):
12 global g 12 global g
13 13
14 g = Globals() 14 g = Globals()
@@ -89,27 +89,27 @@ def test_Global_bmake(): @@ -89,27 +89,27 @@ def test_Global_bmake():
89 g.bmake('hello', 'world') 89 g.bmake('hello', 'world')
90 90
91 assert g.err.written() == [ 91 assert g.err.written() == [
92 'url2pkg: running bmake (\'hello\', \'world\') in \'.\'', 92 'url2pkg: running bmake (\'hello\', \'world\') in \'.\'',
93 ] 93 ]
94 94
95 95
96def test_Global_pkgsrc_license(): 96def test_Global_pkgsrc_license():
97 assert g.pkgsrc_license('BSD') == '' 97 assert g.pkgsrc_license('BSD') == ''
98 assert g.pkgsrc_license('apache-2.0') == 'apache-2.0' 98 assert g.pkgsrc_license('apache-2.0') == 'apache-2.0'
99 assert g.pkgsrc_license('Apache 2') == 'apache-2.0' 99 assert g.pkgsrc_license('Apache 2') == 'apache-2.0'
100 100
101 # Not explicitly in the list, looked up from PKGSRCDIR. 101 # Not explicitly in the list, looked up from PKGSRCDIR.
102 assert g.pkgsrc_license('artistic-2.0') == 'artistic-2.0' 102 assert g.pkgsrc_license('skype21-license') == 'skype21-license'
103 103
104 # Neither in the list nor in PKGSRCDIR/licenses. 104 # Neither in the list nor in PKGSRCDIR/licenses.
105 assert g.pkgsrc_license('unknown') == '' 105 assert g.pkgsrc_license('unknown') == ''
106 106
107 107
108def test_Lines__write_and_read(tmp_path: Path): 108def test_Lines__write_and_read(tmp_path: Path):
109 example = tmp_path / 'example' 109 example = tmp_path / 'example'
110 110
111 lines = Lines('1', '2', '3') 111 lines = Lines('1', '2', '3')
112 112
113 lines.write_to(example) 113 lines.write_to(example)
114 114
115 assert example.read_text() == '1\n2\n3\n' 115 assert example.read_text() == '1\n2\n3\n'
@@ -637,32 +637,37 @@ def test_Generator_adjust_everything_els @@ -637,32 +637,37 @@ def test_Generator_adjust_everything_els
637 '# url2pkg-marker (please do not remove this line.)', 637 '# url2pkg-marker (please do not remove this line.)',
638 '.include "../../mk/bsd.pkg.mk"', 638 '.include "../../mk/bsd.pkg.mk"',
639 ] 639 ]
640 640
641 641
642def test_Generator_generate_package(tmp_path: Path): 642def test_Generator_generate_package(tmp_path: Path):
643 url = 'https://ftp.gnu.org/pub/gnu/cflow/cflow-1.6.tar.gz' 643 url = 'https://ftp.gnu.org/pub/gnu/cflow/cflow-1.6.tar.gz'
644 g.editor = 'true' # the shell command 644 g.editor = 'true' # the shell command
645 g.make = 'true' # the shell command 645 g.make = 'true' # the shell command
646 g.pkgdir = tmp_path 646 g.pkgdir = tmp_path
647 647
648 Generator(url).generate_package(g) 648 Generator(url).generate_package(g)
649 649
650 assert (tmp_path / 'DESCR').read_text() == '' 650 assert not (tmp_path / 'DESCR').is_file() # is created later
651 assert len((tmp_path / 'Makefile').read_text().splitlines()) == 13 651 assert len((tmp_path / 'Makefile').read_text().splitlines()) == 13
652 assert (tmp_path / 'PLIST').read_text() == '@comment $''NetBSD$\n' 652 assert (tmp_path / 'PLIST').read_text().splitlines() == [
 653 '@comment $''NetBSD$',
 654 '@comment TODO: to fill this file with the file listing:',
 655 '@comment TODO: 1. run "true package"',
 656 '@comment TODO: 2. run "true print-PLIST"',
 657 ]
653 658
654 # Since bmake is only fake in this test, the distinfo file is not created. 659 # Since bmake is only fake in this test, the distinfo file is not created.
655 expected_files = ['DESCR', 'Makefile', 'PLIST'] 660 expected_files = ['Makefile', 'PLIST']
656 assert sorted([f.name for f in tmp_path.glob("*")]) == expected_files 661 assert sorted([f.name for f in tmp_path.glob("*")]) == expected_files
657 662
658 663
659def test_Adjuster_read_dependencies(): 664def test_Adjuster_read_dependencies():
660 child_process_output = [ 665 child_process_output = [
661 'DEPENDS\tpackage>=112.0:../../pkgtools/pkglint', 666 'DEPENDS\tpackage>=112.0:../../pkgtools/pkglint',
662 'DEPENDS\tpackage>=120.0:../../pkgtools/x11-links', 667 'DEPENDS\tpackage>=120.0:../../pkgtools/x11-links',
663 'BUILD_DEPENDS\turl2pkg>=1.0', 668 'BUILD_DEPENDS\turl2pkg>=1.0',
664 'BUILD_DEPENDS\tdoes-not-exist>=1.0', 669 'BUILD_DEPENDS\tdoes-not-exist>=1.0',
665 'TEST_DEPENDS\tpkglint', 670 'TEST_DEPENDS\tpkglint',
666 'A line that is not a dependency at all', 671 'A line that is not a dependency at all',
667 '', 672 '',
668 'var\tHOMEPAGE\thttps://homepage.example.org/', 673 'var\tHOMEPAGE\thttps://homepage.example.org/',