Import upstream version 0.009+git20130731.1.d2e0170
Debian Janitor
2 years ago
0 | NAME | |
1 | CONTRIBUTING | |
2 | ||
3 | DESCRIPTION | |
4 | If you're reading this document, that means you might be thinking about | |
5 | helping me out with this project. Thanks! | |
6 | ||
7 | Here's some ways you could help out: | |
8 | ||
9 | * Bug reports | |
10 | ||
11 | Found a bug? Great! (Well, not so great I suppose.) | |
12 | ||
13 | The place to report them is <https://rt.cpan.org/>. Don't e-mail me | |
14 | about it, as your e-mail is more than likely to get lost amongst the | |
15 | spam. | |
16 | ||
17 | An example script clearly demonstrating the bug (preferably written | |
18 | using Test::More) would be greatly appreciated. | |
19 | ||
20 | * Patches | |
21 | ||
22 | If you've found a bug and written a fix for it, even better! | |
23 | ||
24 | Generally speaking you should check out the latest copy of the code | |
25 | from the source repository rather than using the CPAN distribution. | |
26 | The file META.yml should contain a link to the source repository. If | |
27 | not, then try <https://github.com/tobyink> or submit a bug report. | |
28 | (As far as I'm concerned the lack of a link is a bug.) Many of my | |
29 | distributions are also mirrored at <http://bitbucket.org/tobyink>. | |
30 | ||
31 | To submit the patch, do a pull request on GitHub or Bitbucket, or | |
32 | attach a diff file to a bug report. Unless otherwise stated, I'll | |
33 | assume that your contributions are licensed under the same terms as | |
34 | the rest of the project. | |
35 | ||
36 | (If using git, feel free to work in a branch. For Mercurial, I'd | |
37 | prefer bookmarks within the default branch.) | |
38 | ||
39 | * Documentation | |
40 | ||
41 | If there's anything unclear in the documentation, please submit this | |
42 | as a bug report or patch as above. | |
43 | ||
44 | Non-toy example scripts that I can bundle would also be appreciated. | |
45 | ||
46 | * Translation | |
47 | ||
48 | Translations of documentation would be welcome. | |
49 | ||
50 | For translations of error messages and other strings embedded in the | |
51 | code, check with me first. Sometimes the English strings may not in | |
52 | a stable state, so it would be a waste of time translating them. | |
53 | ||
54 | Coding Style | |
55 | I tend to write using something approximating the Allman style, using | |
56 | tabs for indentation and Unix-style line breaks. | |
57 | ||
58 | * <http://en.wikipedia.org/wiki/Indent_style#Allman_style> | |
59 | ||
60 | * <http://www.derkarl.org/why_to_tabs.html> | |
61 | ||
62 | I nominally encode all source files as UTF-8, though in practice most of | |
63 | them use a 7-bit-safe ASCII-compatible subset of UTF-8. | |
64 | ||
65 | AUTHOR | |
66 | Toby Inkster <tobyink@cpan.org>. | |
67 | ||
68 | COPYRIGHT AND LICENCE | |
69 | Copyright (c) 2012-2013 by Toby Inkster. | |
70 | ||
71 | CONTRIBUTING.pod is licensed under the Creative Commons | |
72 | Attribution-ShareAlike 2.0 UK: England & Wales License. To view a copy | |
73 | of this license, visit | |
74 | <http://creativecommons.org/licenses/by-sa/2.0/uk/>. | |
75 |
2 | 2 | Upstream-Contact: Toby Inkster <tobyink@cpan.org> |
3 | 3 | Source: https://metacpan.org/release/Module-Install-RDF |
4 | 4 | |
5 | Files: CONTRIBUTING | |
6 | CREDITS | |
5 | Files: CREDITS | |
7 | 6 | Changes |
8 | 7 | LICENSE |
9 | 8 | MANIFEST.SKIP |
25 | 24 | Copyright: Copyright 2002 - 2012 Brian Ingerson, Audrey Tang and Adam Kennedy. |
26 | 25 | License: GPL-1.0+ or Artistic-1.0 |
27 | 26 | |
27 | Files: lib/Module/Install/Admin/RDF.pm | |
28 | lib/Module/Install/RDF.pm | |
29 | Copyright: Copyright (C) 2011-2013 by Toby Inkster. | |
30 | License: GPL-1.0+ or Artistic-1.0 | |
31 | ||
28 | 32 | Files: inc/Module/Install/TrustMetaYml.pm |
29 | 33 | inc/Module/Package/Dist/RDF.pm |
30 | 34 | Copyright: This software is copyright (c) 2011-2012 by Toby Inkster. |
31 | 35 | License: GPL-1.0+ or Artistic-1.0 |
32 | 36 | |
33 | Files: lib/Module/Install/Admin/RDF.pm | |
34 | lib/Module/Install/RDF.pm | |
35 | Copyright: Copyright (C) 2011-2013 by Toby Inkster. | |
36 | License: GPL-1.0+ or Artistic-1.0 | |
37 | ||
38 | 37 | Files: inc/YAML/Tiny.pm |
39 | Copyright: Copyright 2006 - 2012 Adam Kennedy. | |
40 | License: GPL-1.0+ or Artistic-1.0 | |
41 | ||
42 | Files: inc/Module/Install/Package.pm | |
43 | Copyright: Copyright (c) 2011. Ingy doet Net. | |
38 | Copyright: Copyright 2006 - 2013 Adam Kennedy. | |
44 | 39 | License: GPL-1.0+ or Artistic-1.0 |
45 | 40 | |
46 | 41 | Files: COPYRIGHT |
52 | 47 | Copyright: Copyright 2002, 2003, 2004 Audrey Tang and Brian Ingerson. |
53 | 48 | License: GPL-1.0+ or Artistic-1.0 |
54 | 49 | |
50 | Files: inc/Module/Install/Package.pm | |
51 | Copyright: Copyright (c) 2011. Ingy doet Net. | |
52 | License: GPL-1.0+ or Artistic-1.0 | |
53 | ||
55 | 54 | Files: inc/Module/Install/Base.pm |
56 | 55 | Copyright: Copyright 2003, 2004 by Audrey Tang <autrijus@autrijus.org>. |
57 | 56 | License: GPL-1.0+ or Artistic-1.0 |
58 | 57 | |
59 | 58 | License: Artistic-1.0 |
60 | This software is Copyright (c) 2013 by the copyright holder(s). | |
59 | This software is Copyright (c) 2021 by the copyright holder(s). | |
61 | 60 | |
62 | 61 | This is free software, licensed under: |
63 | 62 | |
64 | 63 | The Artistic License 1.0 |
65 | 64 | |
66 | 65 | License: GPL-1.0 |
67 | This software is Copyright (c) 2013 by the copyright holder(s). | |
66 | This software is Copyright (c) 2021 by the copyright holder(s). | |
68 | 67 | |
69 | 68 | This is free software, licensed under: |
70 | 69 |
0 | This software is copyright (c) 2013 by Toby Inkster <tobyink@cpan.org>. | |
0 | This software is copyright (c) 2021 by Toby Inkster <tobyink@cpan.org>. | |
1 | 1 | |
2 | 2 | This is free software; you can redistribute it and/or modify it under |
3 | 3 | the same terms as the Perl 5 programming language system itself. |
11 | 11 | |
12 | 12 | --- The GNU General Public License, Version 1, February 1989 --- |
13 | 13 | |
14 | This software is Copyright (c) 2013 by Toby Inkster <tobyink@cpan.org>. | |
14 | This software is Copyright (c) 2021 by Toby Inkster <tobyink@cpan.org>. | |
15 | 15 | |
16 | 16 | This is free software, licensed under: |
17 | 17 | |
21 | 21 | Version 1, February 1989 |
22 | 22 | |
23 | 23 | Copyright (C) 1989 Free Software Foundation, Inc. |
24 | 51 Franklin St, Suite 500, Boston, MA 02110-1335 USA | |
24 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
25 | 25 | |
26 | 26 | Everyone is permitted to copy and distribute verbatim copies |
27 | 27 | of this license document, but changing it is not allowed. |
271 | 271 | |
272 | 272 | --- The Artistic License 1.0 --- |
273 | 273 | |
274 | This software is Copyright (c) 2013 by Toby Inkster <tobyink@cpan.org>. | |
274 | This software is Copyright (c) 2021 by Toby Inkster <tobyink@cpan.org>. | |
275 | 275 | |
276 | 276 | This is free software, licensed under: |
277 | 277 |
0 | 0 | Changes |
1 | CONTRIBUTING | |
2 | 1 | COPYRIGHT |
3 | 2 | CREDITS |
4 | 3 | inc/Module/AutoInstall.pm |
29 | 28 | meta/deps.pret |
30 | 29 | meta/doap.pret |
31 | 30 | meta/makefile.pret |
31 | Module-Install-RDF-0.009/Changes | |
32 | Module-Install-RDF-0.009/COPYRIGHT | |
33 | Module-Install-RDF-0.009/CREDITS | |
34 | Module-Install-RDF-0.009/inc/Module/AutoInstall.pm | |
35 | Module-Install-RDF-0.009/inc/Module/Install.pm | |
36 | Module-Install-RDF-0.009/inc/Module/Install/AutoInstall.pm | |
37 | Module-Install-RDF-0.009/inc/Module/Install/AutoManifest.pm | |
38 | Module-Install-RDF-0.009/inc/Module/Install/Base.pm | |
39 | Module-Install-RDF-0.009/inc/Module/Install/Can.pm | |
40 | Module-Install-RDF-0.009/inc/Module/Install/Fetch.pm | |
41 | Module-Install-RDF-0.009/inc/Module/Install/Include.pm | |
42 | Module-Install-RDF-0.009/inc/Module/Install/Makefile.pm | |
43 | Module-Install-RDF-0.009/inc/Module/Install/Metadata.pm | |
44 | Module-Install-RDF-0.009/inc/Module/Install/Package.pm | |
45 | Module-Install-RDF-0.009/inc/Module/Install/TrustMetaYml.pm | |
46 | Module-Install-RDF-0.009/inc/Module/Install/Win32.pm | |
47 | Module-Install-RDF-0.009/inc/Module/Install/WriteAll.pm | |
48 | Module-Install-RDF-0.009/inc/Module/Package.pm | |
49 | Module-Install-RDF-0.009/inc/Module/Package/Dist/RDF.pm | |
50 | Module-Install-RDF-0.009/inc/YAML/Tiny.pm | |
51 | Module-Install-RDF-0.009/lib/Module/Install/Admin/RDF.pm | |
52 | Module-Install-RDF-0.009/lib/Module/Install/RDF.pm | |
53 | Module-Install-RDF-0.009/LICENSE | |
54 | Module-Install-RDF-0.009/Makefile.PL | |
55 | Module-Install-RDF-0.009/MANIFEST | |
56 | Module-Install-RDF-0.009/META.ttl | |
57 | Module-Install-RDF-0.009/META.yml | |
58 | Module-Install-RDF-0.009/meta/changes.pret | |
59 | Module-Install-RDF-0.009/meta/deps.pret | |
60 | Module-Install-RDF-0.009/meta/doap.pret | |
61 | Module-Install-RDF-0.009/meta/makefile.pret | |
62 | Module-Install-RDF-0.009/README | |
63 | Module-Install-RDF-0.009/SIGNATURE | |
64 | Module-Install-RDF-0.009/t/01basic.t | |
65 | Module-Install-RDF-0.009/TODO | |
32 | 66 | README |
33 | 67 | t/01basic.t |
34 | 68 | TODO |
0 | @prefix cpan: <http://purl.org/NET/cpan-uri/person/> . | |
0 | @prefix bugs: <http://ontologi.es/doap-bugs#> . | |
1 | @prefix cpan: <http://purl.org/NET/cpan-uri/person/> . | |
1 | 2 | @prefix cpant: <http://purl.org/NET/cpan-uri/terms#> . |
2 | @prefix dc: <http://purl.org/dc/terms/> . | |
3 | @prefix dcs: <http://ontologi.es/doap-changeset#> . | |
4 | @prefix dist: <http://purl.org/NET/cpan-uri/dist/Module-Install-RDF/> . | |
5 | @prefix doap: <http://usefulinc.com/ns/doap#> . | |
6 | @prefix foaf: <http://xmlns.com/foaf/0.1/> . | |
7 | @prefix nfo: <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#> . | |
8 | @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . | |
9 | @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . | |
3 | @prefix dcs: <http://ontologi.es/doap-changeset#> . | |
4 | @prefix deps: <http://ontologi.es/doap-deps#> . | |
5 | @prefix dist: <http://purl.org/NET/cpan-uri/dist/Module-Install-RDF/> . | |
6 | @prefix doap: <http://usefulinc.com/ns/doap#> . | |
7 | @prefix foaf: <http://xmlns.com/foaf/0.1/> . | |
8 | @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . | |
9 | @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . | |
10 | 10 | |
11 | dist:project | |
12 | a doap:Project; | |
13 | doap:name "Module-Install-RDF"; | |
14 | cpant:perl_version_from [ | |
15 | a nfo:FileDataObject; | |
16 | a nfo:SourceCode; | |
17 | rdfs:label "Module::Install::RDF"; | |
18 | nfo:fileName "lib/Module/Install/RDF.pm"; | |
19 | nfo:programmingLanguage "Perl"; | |
20 | ]; | |
21 | cpant:readme_from [ | |
22 | a nfo:FileDataObject; | |
23 | a nfo:SourceCode; | |
24 | rdfs:label "Module::Install::RDF"; | |
25 | nfo:fileName "lib/Module/Install/RDF.pm"; | |
26 | nfo:programmingLanguage "Perl"; | |
27 | ]; | |
28 | cpant:requires "Module::Install 1.00"^^cpant:dsWithVersion; | |
29 | cpant:requires "Module::Runtime"^^cpant:dsWithoutVersion; | |
30 | cpant:requires "Object::ID"^^cpant:dsWithoutVersion; | |
31 | cpant:requires "RDF::TriN3 0.201"^^cpant:dsWithVersion; | |
32 | cpant:requires "RDF::Trine 0.135"^^cpant:dsWithVersion; | |
33 | cpant:requires "URI::file 4.0"^^cpant:dsWithVersion; | |
34 | cpant:test_requires "Test::More 0.61"^^cpant:dsWithVersion; | |
35 | cpant:version_from [ | |
36 | a nfo:FileDataObject; | |
37 | a nfo:SourceCode; | |
38 | rdfs:label "Module::Install::RDF"; | |
39 | nfo:fileName "lib/Module/Install/RDF.pm"; | |
40 | nfo:programmingLanguage "Perl"; | |
41 | ]; | |
42 | dc:contributor cpan:tobyink; | |
43 | doap:bug-database <http://rt.cpan.org/Dist/Display.html?Queue=Module-Install-RDF>; | |
44 | doap:category [ rdfs:label "Semantic Web" ]; | |
45 | doap:category [ rdfs:label "Packaging" ]; | |
46 | doap:created "2011-09-30"^^xsd:date; | |
47 | doap:developer cpan:tobyink; | |
48 | doap:documenter cpan:tobyink; | |
49 | doap:download-page <https://metacpan.org/release/Module-Install-RDF>; | |
50 | doap:homepage <https://metacpan.org/release/Module-Install-RDF>; | |
51 | doap:license <http://dev.perl.org/licenses/>; | |
52 | doap:maintainer cpan:tobyink; | |
53 | doap:programming-language "Perl"; | |
54 | doap:release dist:v_0-001; | |
55 | doap:release dist:v_0-002; | |
56 | doap:release dist:v_0-003; | |
57 | doap:release dist:v_0-004; | |
58 | doap:release dist:v_0-005; | |
59 | doap:release dist:v_0-006; | |
60 | doap:release dist:v_0-007; | |
61 | doap:release dist:v_0-008; | |
62 | doap:release dist:v_0-009; | |
63 | doap:repository [ | |
64 | a doap:GitRepository; | |
65 | doap:browse <https://github.com/tobyink/p5-module-install-rdf>; | |
66 | ]; | |
67 | doap:shortdesc "advanced metadata for your distribution"@en; | |
68 | doap:tester cpan:tobyink. | |
69 | ||
70 | dist:v_0-001 | |
71 | a doap:Version; | |
72 | rdfs:label "Initial release"; | |
73 | dc:identifier "Module-Install-RDF-0.001"^^xsd:string; | |
74 | dc:issued "2011-10-01"^^xsd:date; | |
75 | dcs:released-by cpan:tobyink; | |
76 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.001.tar.gz>; | |
77 | doap:revision "0.001"^^xsd:string. | |
78 | ||
79 | dist:v_0-002 | |
80 | a doap:Version; | |
81 | dc:identifier "Module-Install-RDF-0.002"^^xsd:string; | |
82 | dc:issued "2011-10-06"^^xsd:date; | |
83 | dcs:changeset [ | |
84 | dcs:item [ | |
85 | a dcs:Packaging; | |
86 | rdfs:label "Upgrade Module::Package::RDF version."; | |
87 | ]; | |
88 | ]; | |
89 | dcs:released-by cpan:tobyink; | |
90 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.002.tar.gz>; | |
91 | doap:revision "0.002"^^xsd:string. | |
92 | ||
93 | dist:v_0-003 | |
94 | a doap:Version; | |
95 | dc:identifier "Module-Install-RDF-0.003"^^xsd:string; | |
96 | dc:issued "2011-11-26"^^xsd:date; | |
97 | dcs:changeset [ | |
98 | dcs:item [ a dcs:Regression; rdfs:label "use parent" ]; | |
99 | dcs:item [ | |
100 | a dcs:Addition; | |
101 | rdfs:label "rdf_project_uri function which provides heuristics to determine the URI of the primary doap:Project described in the meta directory."; | |
102 | ]; | |
103 | dcs:item [ | |
104 | a dcs:Change; | |
105 | rdfs:label "Use Object::ID::object_id instead of Scalar::Util::refaddr to uniquely identity Module::Install objects. (Though in a typical installation scenario, this shouldn't matter much.)"; | |
106 | ]; | |
107 | ]; | |
108 | dcs:released-by cpan:tobyink; | |
109 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.003.tar.gz>; | |
110 | doap:revision "0.003"^^xsd:string. | |
111 | ||
112 | dist:v_0-004 | |
113 | a doap:Version; | |
114 | dc:identifier "Module-Install-RDF-0.004"^^xsd:string; | |
115 | dc:issued "2011-12-03"^^xsd:date; | |
116 | dcs:changeset [ | |
117 | dcs:item [ a dcs:Bugfix; rdfs:label "use base" ]; | |
118 | ]; | |
119 | dcs:released-by cpan:tobyink; | |
120 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.004.tar.gz>; | |
121 | doap:revision "0.004"^^xsd:string. | |
122 | ||
123 | dist:v_0-005 | |
124 | a doap:Version; | |
125 | dc:identifier "Module-Install-RDF-0.005"^^xsd:string; | |
126 | dc:issued "2012-07-04"^^xsd:date; | |
127 | dcs:changeset [ | |
128 | dcs:item [ | |
129 | a dcs:Addition; | |
130 | rdfs:label "Support metadata written in Pretdsl."; | |
131 | ]; | |
132 | ]; | |
133 | dcs:released-by cpan:tobyink; | |
134 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.005.tar.gz>; | |
135 | doap:revision "0.005"^^xsd:string. | |
136 | ||
137 | dist:v_0-006 | |
138 | a doap:Version; | |
139 | dc:identifier "Module-Install-RDF-0.006"^^xsd:string; | |
140 | dc:issued "2012-07-04"^^xsd:date; | |
141 | dcs:changeset [ | |
142 | dcs:item [ | |
143 | a dcs:Packaging; | |
144 | rdfs:label "Add Module::Runtime dependency."; | |
145 | ]; | |
146 | ]; | |
147 | dcs:released-by cpan:tobyink; | |
148 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.006.tar.gz>; | |
149 | doap:revision "0.006"^^xsd:string. | |
150 | ||
151 | dist:v_0-007 | |
152 | a doap:Version; | |
153 | rdfs:label "Bond, James Bond"; | |
154 | dc:identifier "Module-Install-RDF-0.007"^^xsd:string; | |
155 | dc:issued "2012-07-05"^^xsd:date; | |
156 | dcs:changeset [ | |
157 | dcs:item [ | |
158 | a dcs:Packaging; | |
159 | rdfs:label "Bump RDF::TriN3 dependency to 0.201."; | |
160 | ]; | |
161 | ]; | |
162 | dcs:released-by cpan:tobyink; | |
163 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.007.tar.gz>; | |
164 | doap:revision "0.007"^^xsd:string. | |
165 | ||
166 | dist:v_0-008 | |
167 | a doap:Version; | |
168 | dc:identifier "Module-Install-RDF-0.008"^^xsd:string; | |
169 | dc:issued "2013-03-16"^^xsd:date; | |
170 | dcs:changeset [ | |
171 | dcs:item [ | |
172 | a dcs:Addition; | |
173 | rdfs:label "write_meta_ttl method."; | |
174 | ]; | |
175 | ]; | |
176 | dcs:released-by cpan:tobyink; | |
177 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.008.tar.gz>; | |
178 | doap:revision "0.008"^^xsd:string. | |
179 | ||
180 | dist:v_0-009 | |
181 | a doap:Version; | |
182 | dc:identifier "Module-Install-RDF-0.009"^^xsd:string; | |
183 | dc:issued "2013-07-31"^^xsd:date; | |
184 | dcs:changeset [ | |
185 | dcs:item [ | |
186 | a dcs:Update; | |
187 | rdfs:label "Add a hard-coded prefix for doap-deps."; | |
188 | ]; | |
189 | dcs:item [ | |
190 | a dcs:Change; | |
191 | rdfs:label "Change the hard-coded prefix for doap-bugs."; | |
192 | ]; | |
193 | ]; | |
194 | dcs:released-by cpan:tobyink; | |
195 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.009.tar.gz>; | |
196 | doap:revision "0.009"^^xsd:string. | |
197 | ||
198 | cpan:tobyink | |
199 | a foaf:Person; | |
200 | foaf:name "Toby Inkster"; | |
201 | foaf:homepage <http://tobyinkster.co.uk/>; | |
202 | foaf:mbox <mailto:tobyink@cpan.org>; | |
203 | foaf:nick "tobyink"; | |
204 | foaf:page <https://metacpan.org/author/TOBYINK>. | |
205 | ||
11 | _:r1627689586r0 a dcs:Packaging ; | |
12 | rdfs:label "Upgrade Module::Package::RDF version." . | |
13 | _:r1627689586r1 a dcs:Bugfix ; | |
14 | rdfs:label "use base" . | |
15 | _:r1627689586r10 <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName> "lib/Module/Install/RDF.pm" ; | |
16 | <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#programmingLanguage> "Perl" ; | |
17 | a <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject>, <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SourceCode> ; | |
18 | rdfs:label "Module::Install::RDF" . | |
19 | _:r1627689586r2 a dcs:Addition ; | |
20 | rdfs:label "Support metadata written in Pretdsl." . | |
21 | _:r1627689586r3 a dcs:Packaging ; | |
22 | rdfs:label "Add Module::Runtime dependency." . | |
23 | _:r1627689586r4 a dcs:Packaging ; | |
24 | rdfs:label "Bump RDF::TriN3 dependency to 0.201." . | |
25 | _:r1627689586r5 a dcs:Addition ; | |
26 | rdfs:label "write_meta_ttl method." . | |
27 | _:r1627689586r6 a dcs:Update ; | |
28 | rdfs:label "Add a hard-coded prefix for doap-deps." . | |
29 | _:r1627689586r7 a dcs:Change ; | |
30 | rdfs:label "Change the hard-coded prefix for doap-bugs." . | |
31 | _:r1627689586r8 <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName> "lib/Module/Install/RDF.pm" ; | |
32 | <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#programmingLanguage> "Perl" ; | |
33 | a <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject>, <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SourceCode> ; | |
34 | rdfs:label "Module::Install::RDF" . | |
35 | _:r1627689586r9 <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName> "lib/Module/Install/RDF.pm" ; | |
36 | <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#programmingLanguage> "Perl" ; | |
37 | a <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject>, <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SourceCode> ; | |
38 | rdfs:label "Module::Install::RDF" . | |
39 | _:rbe72dc1a36f85473b87f4792bfc9582cer0 dcs:item _:r1627689586r0 . | |
40 | _:rbe72dc1a36f85473b87f4792bfc9582cer1 dcs:item [ | |
41 | a dcs:Regression ; | |
42 | rdfs:label "use parent" | |
43 | ], [ | |
44 | a dcs:Addition ; | |
45 | rdfs:label "rdf_project_uri function which provides heuristics to determine the URI of the primary doap:Project described in the meta directory." | |
46 | ], [ | |
47 | a dcs:Change ; | |
48 | rdfs:label "Use Object::ID::object_id instead of Scalar::Util::refaddr to uniquely identity Module::Install objects. (Though in a typical installation scenario, this shouldn't matter much.)" | |
49 | ] . | |
50 | _:rbe72dc1a36f85473b87f4792bfc9582cer10 dcs:item _:r1627689586r6, _:r1627689586r7 . | |
51 | _:rbe72dc1a36f85473b87f4792bfc9582cer11 doap:browse <https://github.com/tobyink/p5-module-install-rdf> ; | |
52 | a doap:GitRepository . | |
53 | _:rbe72dc1a36f85473b87f4792bfc9582cer12 rdfs:label "Semantic Web" . | |
54 | _:rbe72dc1a36f85473b87f4792bfc9582cer13 rdfs:label "Packaging" . | |
55 | _:rbe72dc1a36f85473b87f4792bfc9582cer5 dcs:item _:r1627689586r1 . | |
56 | _:rbe72dc1a36f85473b87f4792bfc9582cer6 dcs:item _:r1627689586r2 . | |
57 | _:rbe72dc1a36f85473b87f4792bfc9582cer7 dcs:item _:r1627689586r3 . | |
58 | _:rbe72dc1a36f85473b87f4792bfc9582cer8 dcs:item _:r1627689586r4 . | |
59 | _:rbe72dc1a36f85473b87f4792bfc9582cer9 dcs:item _:r1627689586r5 . | |
60 | dist:project cpant:perl_version_from _:r1627689586r8 ; | |
61 | cpant:readme_from _:r1627689586r10 ; | |
62 | cpant:requires "Module::Install 1.00"^^cpant:dsWithVersion, "Module::Runtime"^^cpant:dsWithoutVersion, "Object::ID"^^cpant:dsWithoutVersion, "RDF::TriN3 0.201"^^cpant:dsWithVersion, "RDF::Trine 0.135"^^cpant:dsWithVersion, "URI::file 4.0"^^cpant:dsWithVersion ; | |
63 | cpant:test_requires "Test::More 0.61"^^cpant:dsWithVersion ; | |
64 | cpant:version_from _:r1627689586r9 ; | |
65 | <http://purl.org/dc/terms/contributor> cpan:tobyink ; | |
66 | doap:bug-database <http://rt.cpan.org/Dist/Display.html?Queue=Module-Install-RDF> ; | |
67 | doap:category _:rbe72dc1a36f85473b87f4792bfc9582cer12, _:rbe72dc1a36f85473b87f4792bfc9582cer13 ; | |
68 | doap:created "2011-09-30"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
69 | doap:developer cpan:tobyink ; | |
70 | doap:documenter cpan:tobyink ; | |
71 | doap:download-page <https://metacpan.org/release/Module-Install-RDF> ; | |
72 | doap:homepage <https://metacpan.org/release/Module-Install-RDF> ; | |
73 | doap:license <http://dev.perl.org/licenses/> ; | |
74 | doap:maintainer cpan:tobyink ; | |
75 | doap:name "Module-Install-RDF" ; | |
76 | doap:programming-language "Perl" ; | |
77 | doap:release dist:v_0-001, dist:v_0-002, dist:v_0-003, dist:v_0-004, dist:v_0-005, dist:v_0-006, dist:v_0-007, dist:v_0-008, dist:v_0-009 ; | |
78 | doap:repository _:rbe72dc1a36f85473b87f4792bfc9582cer11 ; | |
79 | doap:shortdesc "advanced metadata for your distribution"@en ; | |
80 | doap:tester cpan:tobyink ; | |
81 | a doap:Project . | |
82 | dist:v_0-001 dcs:released-by cpan:tobyink ; | |
83 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.001"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
84 | <http://purl.org/dc/terms/issued> "2011-10-01"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
85 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.001.tar.gz> ; | |
86 | doap:revision "0.001"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
87 | a doap:Version ; | |
88 | rdfs:label "Initial release" . | |
89 | dist:v_0-002 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer0 ; | |
90 | dcs:released-by cpan:tobyink ; | |
91 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.002"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
92 | <http://purl.org/dc/terms/issued> "2011-10-06"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
93 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.002.tar.gz> ; | |
94 | doap:revision "0.002"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
95 | a doap:Version . | |
96 | dist:v_0-003 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer1 ; | |
97 | dcs:released-by cpan:tobyink ; | |
98 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.003"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
99 | <http://purl.org/dc/terms/issued> "2011-11-26"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
100 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.003.tar.gz> ; | |
101 | doap:revision "0.003"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
102 | a doap:Version . | |
103 | dist:v_0-004 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer5 ; | |
104 | dcs:released-by cpan:tobyink ; | |
105 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.004"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
106 | <http://purl.org/dc/terms/issued> "2011-12-03"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
107 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.004.tar.gz> ; | |
108 | doap:revision "0.004"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
109 | a doap:Version . | |
110 | dist:v_0-005 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer6 ; | |
111 | dcs:released-by cpan:tobyink ; | |
112 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.005"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
113 | <http://purl.org/dc/terms/issued> "2012-07-04"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
114 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.005.tar.gz> ; | |
115 | doap:revision "0.005"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
116 | a doap:Version . | |
117 | dist:v_0-006 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer7 ; | |
118 | dcs:released-by cpan:tobyink ; | |
119 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.006"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
120 | <http://purl.org/dc/terms/issued> "2012-07-04"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
121 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.006.tar.gz> ; | |
122 | doap:revision "0.006"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
123 | a doap:Version . | |
124 | dist:v_0-007 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer8 ; | |
125 | dcs:released-by cpan:tobyink ; | |
126 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.007"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
127 | <http://purl.org/dc/terms/issued> "2012-07-05"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
128 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.007.tar.gz> ; | |
129 | doap:revision "0.007"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
130 | a doap:Version ; | |
131 | rdfs:label "Bond, James Bond" . | |
132 | dist:v_0-008 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer9 ; | |
133 | dcs:released-by cpan:tobyink ; | |
134 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.008"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
135 | <http://purl.org/dc/terms/issued> "2013-03-16"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
136 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.008.tar.gz> ; | |
137 | doap:revision "0.008"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
138 | a doap:Version . | |
139 | dist:v_0-009 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer10 ; | |
140 | dcs:released-by cpan:tobyink ; | |
141 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.009"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
142 | <http://purl.org/dc/terms/issued> "2013-07-31"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
143 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.009.tar.gz> ; | |
144 | doap:revision "0.009"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
145 | a doap:Version . | |
146 | cpan:tobyink a foaf:Person ; | |
147 | foaf:homepage <http://tobyinkster.co.uk/> ; | |
148 | foaf:mbox <mailto:tobyink@cpan.org> ; | |
149 | foaf:name "Toby Inkster" ; | |
150 | foaf:nick "tobyink" ; | |
151 | foaf:page <https://metacpan.org/author/TOBYINK> . |
3 | 3 | - 'Toby Inkster <tobyink@cpan.org>' |
4 | 4 | build_requires: |
5 | 5 | ExtUtils::MakeMaker: 6.36 |
6 | Test::More: 0.61 | |
6 | Test::More: '0.61' | |
7 | 7 | configure_requires: |
8 | 8 | ExtUtils::MakeMaker: 6.36 |
9 | 9 | distribution_type: module |
10 | 10 | dynamic_config: 0 |
11 | generated_by: 'Module::Install version 1.06' | |
11 | generated_by: 'Module::Install version 1.19' | |
12 | 12 | keywords: |
13 | 13 | - Packaging |
14 | 14 | - 'Semantic Web' |
23 | 23 | - inc |
24 | 24 | - t |
25 | 25 | requires: |
26 | Module::Install: 1.00 | |
26 | Module::Install: '1.00' | |
27 | 27 | Module::Runtime: 0 |
28 | 28 | Object::ID: 0 |
29 | RDF::TriN3: 0.201 | |
30 | RDF::Trine: 0.135 | |
31 | URI::file: 4.0 | |
32 | perl: 5.005 | |
29 | RDF::TriN3: '0.201' | |
30 | RDF::Trine: '0.135' | |
31 | URI::file: '4.0' | |
32 | perl: '5.005' | |
33 | 33 | resources: |
34 | 34 | bugtracker: http://rt.cpan.org/Dist/Display.html?Queue=Module-Install-RDF |
35 | 35 | homepage: https://metacpan.org/release/Module-Install-RDF |
36 | 36 | license: http://dev.perl.org/licenses/ |
37 | 37 | repository: https://github.com/tobyink/p5-module-install-rdf |
38 | version: 0.009 | |
38 | version: '0.009' |
0 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ | |
1 | Upstream-Name: Module-Install-RDF | |
2 | Upstream-Contact: Toby Inkster <tobyink@cpan.org> | |
3 | Source: https://metacpan.org/release/Module-Install-RDF | |
4 | ||
5 | Files: CREDITS | |
6 | Changes | |
7 | LICENSE | |
8 | MANIFEST.SKIP | |
9 | META.ttl | |
10 | Makefile.PL | |
11 | README | |
12 | TODO | |
13 | meta/changes.pret | |
14 | meta/deps.pret | |
15 | meta/doap.pret | |
16 | meta/makefile.pret | |
17 | t/01basic.t | |
18 | Copyright: Unknown | |
19 | License: Unknown | |
20 | ||
21 | Files: inc/Module/Install.pm | |
22 | inc/Module/Install/Include.pm | |
23 | inc/Module/Install/Metadata.pm | |
24 | Copyright: Copyright 2002 - 2012 Brian Ingerson, Audrey Tang and Adam Kennedy. | |
25 | License: GPL-1.0+ or Artistic-1.0 | |
26 | ||
27 | Files: lib/Module/Install/Admin/RDF.pm | |
28 | lib/Module/Install/RDF.pm | |
29 | Copyright: Copyright (C) 2011-2013 by Toby Inkster. | |
30 | License: GPL-1.0+ or Artistic-1.0 | |
31 | ||
32 | Files: inc/Module/Install/TrustMetaYml.pm | |
33 | inc/Module/Package/Dist/RDF.pm | |
34 | Copyright: This software is copyright (c) 2011-2012 by Toby Inkster. | |
35 | License: GPL-1.0+ or Artistic-1.0 | |
36 | ||
37 | Files: inc/YAML/Tiny.pm | |
38 | Copyright: Copyright 2006 - 2013 Adam Kennedy. | |
39 | License: GPL-1.0+ or Artistic-1.0 | |
40 | ||
41 | Files: COPYRIGHT | |
42 | Copyright: None | |
43 | License: public-domain | |
44 | Comment: This file! Automatically generated. | |
45 | ||
46 | Files: inc/Module/Install/Makefile.pm | |
47 | Copyright: Copyright 2002, 2003, 2004 Audrey Tang and Brian Ingerson. | |
48 | License: GPL-1.0+ or Artistic-1.0 | |
49 | ||
50 | Files: inc/Module/Install/Package.pm | |
51 | Copyright: Copyright (c) 2011. Ingy doet Net. | |
52 | License: GPL-1.0+ or Artistic-1.0 | |
53 | ||
54 | Files: inc/Module/Install/Base.pm | |
55 | Copyright: Copyright 2003, 2004 by Audrey Tang <autrijus@autrijus.org>. | |
56 | License: GPL-1.0+ or Artistic-1.0 | |
57 | ||
58 | License: Artistic-1.0 | |
59 | This software is Copyright (c) 2021 by the copyright holder(s). | |
60 | ||
61 | This is free software, licensed under: | |
62 | ||
63 | The Artistic License 1.0 | |
64 | ||
65 | License: GPL-1.0 | |
66 | This software is Copyright (c) 2021 by the copyright holder(s). | |
67 | ||
68 | This is free software, licensed under: | |
69 | ||
70 | The GNU General Public License, Version 1, February 1989 | |
71 |
0 | Module-Install-RDF | |
1 | ================== | |
2 | ||
3 | Created: 2011-09-30 | |
4 | Home page: <https://metacpan.org/release/Module-Install-RDF> | |
5 | Bug tracker: <http://rt.cpan.org/Dist/Display.html?Queue=Module-Install-RDF> | |
6 | Maintainer: Toby Inkster <mailto:tobyink@cpan.org> | |
7 | ||
8 | 0.009 2013-07-31 | |
9 | ||
10 | - (Update) Add a hard-coded prefix for doap-deps. | |
11 | - Change the hard-coded prefix for doap-bugs. | |
12 | ||
13 | 0.008 2013-03-16 | |
14 | ||
15 | - (Addition) write_meta_ttl method. | |
16 | ||
17 | 0.007 2012-07-05 Bond, James Bond | |
18 | ||
19 | - (Packaging) Bump RDF::TriN3 dependency to 0.201. | |
20 | ||
21 | 0.006 2012-07-04 | |
22 | ||
23 | - (Packaging) Add Module::Runtime dependency. | |
24 | ||
25 | 0.005 2012-07-04 | |
26 | ||
27 | - (Addition) Support metadata written in Pretdsl. | |
28 | ||
29 | 0.004 2011-12-03 | |
30 | ||
31 | - (Bugfix) use base | |
32 | ||
33 | 0.003 2011-11-26 | |
34 | ||
35 | - (Addition) rdf_project_uri function which provides heuristics to | |
36 | determine the URI of the primary doap:Project described in the meta | |
37 | directory. | |
38 | - (Regression) use parent | |
39 | - Use Object::ID::object_id instead of Scalar::Util::refaddr to uniquely | |
40 | identity Module::Install objects. (Though in a typical installation | |
41 | scenario, this shouldn't matter much.) | |
42 | ||
43 | 0.002 2011-10-06 | |
44 | ||
45 | - (Packaging) Upgrade Module::Package::RDF version. | |
46 | ||
47 | 0.001 2011-10-01 Initial release | |
48 | ||
49 |
0 | This software is copyright (c) 2021 by Toby Inkster <tobyink@cpan.org>. | |
1 | ||
2 | This is free software; you can redistribute it and/or modify it under | |
3 | the same terms as the Perl 5 programming language system itself. | |
4 | ||
5 | Terms of the Perl programming language system itself | |
6 | ||
7 | a) the GNU General Public License as published by the Free | |
8 | Software Foundation; either version 1, or (at your option) any | |
9 | later version, or | |
10 | b) the "Artistic License" | |
11 | ||
12 | --- The GNU General Public License, Version 1, February 1989 --- | |
13 | ||
14 | This software is Copyright (c) 2021 by Toby Inkster <tobyink@cpan.org>. | |
15 | ||
16 | This is free software, licensed under: | |
17 | ||
18 | The GNU General Public License, Version 1, February 1989 | |
19 | ||
20 | GNU GENERAL PUBLIC LICENSE | |
21 | Version 1, February 1989 | |
22 | ||
23 | Copyright (C) 1989 Free Software Foundation, Inc. | |
24 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
25 | ||
26 | Everyone is permitted to copy and distribute verbatim copies | |
27 | of this license document, but changing it is not allowed. | |
28 | ||
29 | Preamble | |
30 | ||
31 | The license agreements of most software companies try to keep users | |
32 | at the mercy of those companies. By contrast, our General Public | |
33 | License is intended to guarantee your freedom to share and change free | |
34 | software--to make sure the software is free for all its users. The | |
35 | General Public License applies to the Free Software Foundation's | |
36 | software and to any other program whose authors commit to using it. | |
37 | You can use it for your programs, too. | |
38 | ||
39 | When we speak of free software, we are referring to freedom, not | |
40 | price. Specifically, the General Public License is designed to make | |
41 | sure that you have the freedom to give away or sell copies of free | |
42 | software, that you receive source code or can get it if you want it, | |
43 | that you can change the software or use pieces of it in new free | |
44 | programs; and that you know you can do these things. | |
45 | ||
46 | To protect your rights, we need to make restrictions that forbid | |
47 | anyone to deny you these rights or to ask you to surrender the rights. | |
48 | These restrictions translate to certain responsibilities for you if you | |
49 | distribute copies of the software, or if you modify it. | |
50 | ||
51 | For example, if you distribute copies of a such a program, whether | |
52 | gratis or for a fee, you must give the recipients all the rights that | |
53 | you have. You must make sure that they, too, receive or can get the | |
54 | source code. And you must tell them their rights. | |
55 | ||
56 | We protect your rights with two steps: (1) copyright the software, and | |
57 | (2) offer you this license which gives you legal permission to copy, | |
58 | distribute and/or modify the software. | |
59 | ||
60 | Also, for each author's protection and ours, we want to make certain | |
61 | that everyone understands that there is no warranty for this free | |
62 | software. If the software is modified by someone else and passed on, we | |
63 | want its recipients to know that what they have is not the original, so | |
64 | that any problems introduced by others will not reflect on the original | |
65 | authors' reputations. | |
66 | ||
67 | The precise terms and conditions for copying, distribution and | |
68 | modification follow. | |
69 | ||
70 | GNU GENERAL PUBLIC LICENSE | |
71 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
72 | ||
73 | 0. This License Agreement applies to any program or other work which | |
74 | contains a notice placed by the copyright holder saying it may be | |
75 | distributed under the terms of this General Public License. The | |
76 | "Program", below, refers to any such program or work, and a "work based | |
77 | on the Program" means either the Program or any work containing the | |
78 | Program or a portion of it, either verbatim or with modifications. Each | |
79 | licensee is addressed as "you". | |
80 | ||
81 | 1. You may copy and distribute verbatim copies of the Program's source | |
82 | code as you receive it, in any medium, provided that you conspicuously and | |
83 | appropriately publish on each copy an appropriate copyright notice and | |
84 | disclaimer of warranty; keep intact all the notices that refer to this | |
85 | General Public License and to the absence of any warranty; and give any | |
86 | other recipients of the Program a copy of this General Public License | |
87 | along with the Program. You may charge a fee for the physical act of | |
88 | transferring a copy. | |
89 | ||
90 | 2. You may modify your copy or copies of the Program or any portion of | |
91 | it, and copy and distribute such modifications under the terms of Paragraph | |
92 | 1 above, provided that you also do the following: | |
93 | ||
94 | a) cause the modified files to carry prominent notices stating that | |
95 | you changed the files and the date of any change; and | |
96 | ||
97 | b) cause the whole of any work that you distribute or publish, that | |
98 | in whole or in part contains the Program or any part thereof, either | |
99 | with or without modifications, to be licensed at no charge to all | |
100 | third parties under the terms of this General Public License (except | |
101 | that you may choose to grant warranty protection to some or all | |
102 | third parties, at your option). | |
103 | ||
104 | c) If the modified program normally reads commands interactively when | |
105 | run, you must cause it, when started running for such interactive use | |
106 | in the simplest and most usual way, to print or display an | |
107 | announcement including an appropriate copyright notice and a notice | |
108 | that there is no warranty (or else, saying that you provide a | |
109 | warranty) and that users may redistribute the program under these | |
110 | conditions, and telling the user how to view a copy of this General | |
111 | Public License. | |
112 | ||
113 | d) You may charge a fee for the physical act of transferring a | |
114 | copy, and you may at your option offer warranty protection in | |
115 | exchange for a fee. | |
116 | ||
117 | Mere aggregation of another independent work with the Program (or its | |
118 | derivative) on a volume of a storage or distribution medium does not bring | |
119 | the other work under the scope of these terms. | |
120 | ||
121 | 3. You may copy and distribute the Program (or a portion or derivative of | |
122 | it, under Paragraph 2) in object code or executable form under the terms of | |
123 | Paragraphs 1 and 2 above provided that you also do one of the following: | |
124 | ||
125 | a) accompany it with the complete corresponding machine-readable | |
126 | source code, which must be distributed under the terms of | |
127 | Paragraphs 1 and 2 above; or, | |
128 | ||
129 | b) accompany it with a written offer, valid for at least three | |
130 | years, to give any third party free (except for a nominal charge | |
131 | for the cost of distribution) a complete machine-readable copy of the | |
132 | corresponding source code, to be distributed under the terms of | |
133 | Paragraphs 1 and 2 above; or, | |
134 | ||
135 | c) accompany it with the information you received as to where the | |
136 | corresponding source code may be obtained. (This alternative is | |
137 | allowed only for noncommercial distribution and only if you | |
138 | received the program in object code or executable form alone.) | |
139 | ||
140 | Source code for a work means the preferred form of the work for making | |
141 | modifications to it. For an executable file, complete source code means | |
142 | all the source code for all modules it contains; but, as a special | |
143 | exception, it need not include source code for modules which are standard | |
144 | libraries that accompany the operating system on which the executable | |
145 | file runs, or for standard header files or definitions files that | |
146 | accompany that operating system. | |
147 | ||
148 | 4. You may not copy, modify, sublicense, distribute or transfer the | |
149 | Program except as expressly provided under this General Public License. | |
150 | Any attempt otherwise to copy, modify, sublicense, distribute or transfer | |
151 | the Program is void, and will automatically terminate your rights to use | |
152 | the Program under this License. However, parties who have received | |
153 | copies, or rights to use copies, from you under this General Public | |
154 | License will not have their licenses terminated so long as such parties | |
155 | remain in full compliance. | |
156 | ||
157 | 5. By copying, distributing or modifying the Program (or any work based | |
158 | on the Program) you indicate your acceptance of this license to do so, | |
159 | and all its terms and conditions. | |
160 | ||
161 | 6. Each time you redistribute the Program (or any work based on the | |
162 | Program), the recipient automatically receives a license from the original | |
163 | licensor to copy, distribute or modify the Program subject to these | |
164 | terms and conditions. You may not impose any further restrictions on the | |
165 | recipients' exercise of the rights granted herein. | |
166 | ||
167 | 7. The Free Software Foundation may publish revised and/or new versions | |
168 | of the General Public License from time to time. Such new versions will | |
169 | be similar in spirit to the present version, but may differ in detail to | |
170 | address new problems or concerns. | |
171 | ||
172 | Each version is given a distinguishing version number. If the Program | |
173 | specifies a version number of the license which applies to it and "any | |
174 | later version", you have the option of following the terms and conditions | |
175 | either of that version or of any later version published by the Free | |
176 | Software Foundation. If the Program does not specify a version number of | |
177 | the license, you may choose any version ever published by the Free Software | |
178 | Foundation. | |
179 | ||
180 | 8. If you wish to incorporate parts of the Program into other free | |
181 | programs whose distribution conditions are different, write to the author | |
182 | to ask for permission. For software which is copyrighted by the Free | |
183 | Software Foundation, write to the Free Software Foundation; we sometimes | |
184 | make exceptions for this. Our decision will be guided by the two goals | |
185 | of preserving the free status of all derivatives of our free software and | |
186 | of promoting the sharing and reuse of software generally. | |
187 | ||
188 | NO WARRANTY | |
189 | ||
190 | 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | |
191 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | |
192 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | |
193 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | |
194 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
195 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | |
196 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | |
197 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | |
198 | REPAIR OR CORRECTION. | |
199 | ||
200 | 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |
201 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | |
202 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | |
203 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | |
204 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | |
205 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | |
206 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | |
207 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | |
208 | POSSIBILITY OF SUCH DAMAGES. | |
209 | ||
210 | END OF TERMS AND CONDITIONS | |
211 | ||
212 | Appendix: How to Apply These Terms to Your New Programs | |
213 | ||
214 | If you develop a new program, and you want it to be of the greatest | |
215 | possible use to humanity, the best way to achieve this is to make it | |
216 | free software which everyone can redistribute and change under these | |
217 | terms. | |
218 | ||
219 | To do so, attach the following notices to the program. It is safest to | |
220 | attach them to the start of each source file to most effectively convey | |
221 | the exclusion of warranty; and each file should have at least the | |
222 | "copyright" line and a pointer to where the full notice is found. | |
223 | ||
224 | <one line to give the program's name and a brief idea of what it does.> | |
225 | Copyright (C) 19yy <name of author> | |
226 | ||
227 | This program is free software; you can redistribute it and/or modify | |
228 | it under the terms of the GNU General Public License as published by | |
229 | the Free Software Foundation; either version 1, or (at your option) | |
230 | any later version. | |
231 | ||
232 | This program is distributed in the hope that it will be useful, | |
233 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
234 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
235 | GNU General Public License for more details. | |
236 | ||
237 | You should have received a copy of the GNU General Public License | |
238 | along with this program; if not, write to the Free Software | |
239 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA | |
240 | ||
241 | ||
242 | Also add information on how to contact you by electronic and paper mail. | |
243 | ||
244 | If the program is interactive, make it output a short notice like this | |
245 | when it starts in an interactive mode: | |
246 | ||
247 | Gnomovision version 69, Copyright (C) 19xx name of author | |
248 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |
249 | This is free software, and you are welcome to redistribute it | |
250 | under certain conditions; type `show c' for details. | |
251 | ||
252 | The hypothetical commands `show w' and `show c' should show the | |
253 | appropriate parts of the General Public License. Of course, the | |
254 | commands you use may be called something other than `show w' and `show | |
255 | c'; they could even be mouse-clicks or menu items--whatever suits your | |
256 | program. | |
257 | ||
258 | You should also get your employer (if you work as a programmer) or your | |
259 | school, if any, to sign a "copyright disclaimer" for the program, if | |
260 | necessary. Here a sample; alter the names: | |
261 | ||
262 | Yoyodyne, Inc., hereby disclaims all copyright interest in the | |
263 | program `Gnomovision' (a program to direct compilers to make passes | |
264 | at assemblers) written by James Hacker. | |
265 | ||
266 | <signature of Ty Coon>, 1 April 1989 | |
267 | Ty Coon, President of Vice | |
268 | ||
269 | That's all there is to it! | |
270 | ||
271 | ||
272 | --- The Artistic License 1.0 --- | |
273 | ||
274 | This software is Copyright (c) 2021 by Toby Inkster <tobyink@cpan.org>. | |
275 | ||
276 | This is free software, licensed under: | |
277 | ||
278 | The Artistic License 1.0 | |
279 | ||
280 | The Artistic License | |
281 | ||
282 | Preamble | |
283 | ||
284 | The intent of this document is to state the conditions under which a Package | |
285 | may be copied, such that the Copyright Holder maintains some semblance of | |
286 | artistic control over the development of the package, while giving the users of | |
287 | the package the right to use and distribute the Package in a more-or-less | |
288 | customary fashion, plus the right to make reasonable modifications. | |
289 | ||
290 | Definitions: | |
291 | ||
292 | - "Package" refers to the collection of files distributed by the Copyright | |
293 | Holder, and derivatives of that collection of files created through | |
294 | textual modification. | |
295 | - "Standard Version" refers to such a Package if it has not been modified, | |
296 | or has been modified in accordance with the wishes of the Copyright | |
297 | Holder. | |
298 | - "Copyright Holder" is whoever is named in the copyright or copyrights for | |
299 | the package. | |
300 | - "You" is you, if you're thinking about copying or distributing this Package. | |
301 | - "Reasonable copying fee" is whatever you can justify on the basis of media | |
302 | cost, duplication charges, time of people involved, and so on. (You will | |
303 | not be required to justify it to the Copyright Holder, but only to the | |
304 | computing community at large as a market that must bear the fee.) | |
305 | - "Freely Available" means that no fee is charged for the item itself, though | |
306 | there may be fees involved in handling the item. It also means that | |
307 | recipients of the item may redistribute it under the same conditions they | |
308 | received it. | |
309 | ||
310 | 1. You may make and give away verbatim copies of the source form of the | |
311 | Standard Version of this Package without restriction, provided that you | |
312 | duplicate all of the original copyright notices and associated disclaimers. | |
313 | ||
314 | 2. You may apply bug fixes, portability fixes and other modifications derived | |
315 | from the Public Domain or from the Copyright Holder. A Package modified in such | |
316 | a way shall still be considered the Standard Version. | |
317 | ||
318 | 3. You may otherwise modify your copy of this Package in any way, provided that | |
319 | you insert a prominent notice in each changed file stating how and when you | |
320 | changed that file, and provided that you do at least ONE of the following: | |
321 | ||
322 | a) place your modifications in the Public Domain or otherwise make them | |
323 | Freely Available, such as by posting said modifications to Usenet or an | |
324 | equivalent medium, or placing the modifications on a major archive site | |
325 | such as ftp.uu.net, or by allowing the Copyright Holder to include your | |
326 | modifications in the Standard Version of the Package. | |
327 | ||
328 | b) use the modified Package only within your corporation or organization. | |
329 | ||
330 | c) rename any non-standard executables so the names do not conflict with | |
331 | standard executables, which must also be provided, and provide a separate | |
332 | manual page for each non-standard executable that clearly documents how it | |
333 | differs from the Standard Version. | |
334 | ||
335 | d) make other distribution arrangements with the Copyright Holder. | |
336 | ||
337 | 4. You may distribute the programs of this Package in object code or executable | |
338 | form, provided that you do at least ONE of the following: | |
339 | ||
340 | a) distribute a Standard Version of the executables and library files, | |
341 | together with instructions (in the manual page or equivalent) on where to | |
342 | get the Standard Version. | |
343 | ||
344 | b) accompany the distribution with the machine-readable source of the Package | |
345 | with your modifications. | |
346 | ||
347 | c) accompany any non-standard executables with their corresponding Standard | |
348 | Version executables, giving the non-standard executables non-standard | |
349 | names, and clearly documenting the differences in manual pages (or | |
350 | equivalent), together with instructions on where to get the Standard | |
351 | Version. | |
352 | ||
353 | d) make other distribution arrangements with the Copyright Holder. | |
354 | ||
355 | 5. You may charge a reasonable copying fee for any distribution of this | |
356 | Package. You may charge any fee you choose for support of this Package. You | |
357 | may not charge a fee for this Package itself. However, you may distribute this | |
358 | Package in aggregate with other (possibly commercial) programs as part of a | |
359 | larger (possibly commercial) software distribution provided that you do not | |
360 | advertise this Package as a product of your own. | |
361 | ||
362 | 6. The scripts and library files supplied as input to or produced as output | |
363 | from the programs of this Package do not automatically fall under the copyright | |
364 | of this Package, but belong to whomever generated them, and may be sold | |
365 | commercially, and may be aggregated with this Package. | |
366 | ||
367 | 7. C or perl subroutines supplied by you and linked into this Package shall not | |
368 | be considered part of this Package. | |
369 | ||
370 | 8. The name of the Copyright Holder may not be used to endorse or promote | |
371 | products derived from this software without specific prior written permission. | |
372 | ||
373 | 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED | |
374 | WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | |
375 | MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
376 | ||
377 | The End | |
378 |
0 | Changes | |
1 | COPYRIGHT | |
2 | CREDITS | |
3 | inc/Module/AutoInstall.pm | |
4 | inc/Module/Install.pm | |
5 | inc/Module/Install/AutoInstall.pm | |
6 | inc/Module/Install/AutoManifest.pm | |
7 | inc/Module/Install/Base.pm | |
8 | inc/Module/Install/Can.pm | |
9 | inc/Module/Install/Fetch.pm | |
10 | inc/Module/Install/Include.pm | |
11 | inc/Module/Install/Makefile.pm | |
12 | inc/Module/Install/Metadata.pm | |
13 | inc/Module/Install/Package.pm | |
14 | inc/Module/Install/TrustMetaYml.pm | |
15 | inc/Module/Install/Win32.pm | |
16 | inc/Module/Install/WriteAll.pm | |
17 | inc/Module/Package.pm | |
18 | inc/Module/Package/Dist/RDF.pm | |
19 | inc/YAML/Tiny.pm | |
20 | lib/Module/Install/Admin/RDF.pm | |
21 | lib/Module/Install/RDF.pm | |
22 | LICENSE | |
23 | Makefile.PL | |
24 | MANIFEST This list of files | |
25 | META.ttl | |
26 | META.yml | |
27 | meta/changes.pret | |
28 | meta/deps.pret | |
29 | meta/doap.pret | |
30 | meta/makefile.pret | |
31 | Module-Install-RDF-0.009/Changes | |
32 | Module-Install-RDF-0.009/COPYRIGHT | |
33 | Module-Install-RDF-0.009/CREDITS | |
34 | Module-Install-RDF-0.009/inc/Module/AutoInstall.pm | |
35 | Module-Install-RDF-0.009/inc/Module/Install.pm | |
36 | Module-Install-RDF-0.009/inc/Module/Install/AutoInstall.pm | |
37 | Module-Install-RDF-0.009/inc/Module/Install/AutoManifest.pm | |
38 | Module-Install-RDF-0.009/inc/Module/Install/Base.pm | |
39 | Module-Install-RDF-0.009/inc/Module/Install/Can.pm | |
40 | Module-Install-RDF-0.009/inc/Module/Install/Fetch.pm | |
41 | Module-Install-RDF-0.009/inc/Module/Install/Include.pm | |
42 | Module-Install-RDF-0.009/inc/Module/Install/Makefile.pm | |
43 | Module-Install-RDF-0.009/inc/Module/Install/Metadata.pm | |
44 | Module-Install-RDF-0.009/inc/Module/Install/Package.pm | |
45 | Module-Install-RDF-0.009/inc/Module/Install/TrustMetaYml.pm | |
46 | Module-Install-RDF-0.009/inc/Module/Install/Win32.pm | |
47 | Module-Install-RDF-0.009/inc/Module/Install/WriteAll.pm | |
48 | Module-Install-RDF-0.009/inc/Module/Package.pm | |
49 | Module-Install-RDF-0.009/inc/Module/Package/Dist/RDF.pm | |
50 | Module-Install-RDF-0.009/inc/YAML/Tiny.pm | |
51 | Module-Install-RDF-0.009/lib/Module/Install/Admin/RDF.pm | |
52 | Module-Install-RDF-0.009/lib/Module/Install/RDF.pm | |
53 | Module-Install-RDF-0.009/LICENSE | |
54 | Module-Install-RDF-0.009/Makefile.PL | |
55 | Module-Install-RDF-0.009/MANIFEST | |
56 | Module-Install-RDF-0.009/META.ttl | |
57 | Module-Install-RDF-0.009/META.yml | |
58 | Module-Install-RDF-0.009/meta/changes.pret | |
59 | Module-Install-RDF-0.009/meta/deps.pret | |
60 | Module-Install-RDF-0.009/meta/doap.pret | |
61 | Module-Install-RDF-0.009/meta/makefile.pret | |
62 | Module-Install-RDF-0.009/README | |
63 | Module-Install-RDF-0.009/SIGNATURE | |
64 | Module-Install-RDF-0.009/t/01basic.t | |
65 | Module-Install-RDF-0.009/TODO | |
66 | README | |
67 | t/01basic.t | |
68 | TODO |
0 | @prefix bugs: <http://ontologi.es/doap-bugs#> . | |
1 | @prefix cpan: <http://purl.org/NET/cpan-uri/person/> . | |
2 | @prefix cpant: <http://purl.org/NET/cpan-uri/terms#> . | |
3 | @prefix dcs: <http://ontologi.es/doap-changeset#> . | |
4 | @prefix deps: <http://ontologi.es/doap-deps#> . | |
5 | @prefix dist: <http://purl.org/NET/cpan-uri/dist/Module-Install-RDF/> . | |
6 | @prefix doap: <http://usefulinc.com/ns/doap#> . | |
7 | @prefix foaf: <http://xmlns.com/foaf/0.1/> . | |
8 | @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . | |
9 | @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . | |
10 | ||
11 | _:r1627689586r0 a dcs:Packaging ; | |
12 | rdfs:label "Upgrade Module::Package::RDF version." . | |
13 | _:r1627689586r1 a dcs:Bugfix ; | |
14 | rdfs:label "use base" . | |
15 | _:r1627689586r10 <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName> "lib/Module/Install/RDF.pm" ; | |
16 | <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#programmingLanguage> "Perl" ; | |
17 | a <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject>, <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SourceCode> ; | |
18 | rdfs:label "Module::Install::RDF" . | |
19 | _:r1627689586r2 a dcs:Addition ; | |
20 | rdfs:label "Support metadata written in Pretdsl." . | |
21 | _:r1627689586r3 a dcs:Packaging ; | |
22 | rdfs:label "Add Module::Runtime dependency." . | |
23 | _:r1627689586r4 a dcs:Packaging ; | |
24 | rdfs:label "Bump RDF::TriN3 dependency to 0.201." . | |
25 | _:r1627689586r5 a dcs:Addition ; | |
26 | rdfs:label "write_meta_ttl method." . | |
27 | _:r1627689586r6 a dcs:Update ; | |
28 | rdfs:label "Add a hard-coded prefix for doap-deps." . | |
29 | _:r1627689586r7 a dcs:Change ; | |
30 | rdfs:label "Change the hard-coded prefix for doap-bugs." . | |
31 | _:r1627689586r8 <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName> "lib/Module/Install/RDF.pm" ; | |
32 | <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#programmingLanguage> "Perl" ; | |
33 | a <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject>, <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SourceCode> ; | |
34 | rdfs:label "Module::Install::RDF" . | |
35 | _:r1627689586r9 <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName> "lib/Module/Install/RDF.pm" ; | |
36 | <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#programmingLanguage> "Perl" ; | |
37 | a <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject>, <http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SourceCode> ; | |
38 | rdfs:label "Module::Install::RDF" . | |
39 | _:rbe72dc1a36f85473b87f4792bfc9582cer0 dcs:item _:r1627689586r0 . | |
40 | _:rbe72dc1a36f85473b87f4792bfc9582cer1 dcs:item [ | |
41 | a dcs:Regression ; | |
42 | rdfs:label "use parent" | |
43 | ], [ | |
44 | a dcs:Addition ; | |
45 | rdfs:label "rdf_project_uri function which provides heuristics to determine the URI of the primary doap:Project described in the meta directory." | |
46 | ], [ | |
47 | a dcs:Change ; | |
48 | rdfs:label "Use Object::ID::object_id instead of Scalar::Util::refaddr to uniquely identity Module::Install objects. (Though in a typical installation scenario, this shouldn't matter much.)" | |
49 | ] . | |
50 | _:rbe72dc1a36f85473b87f4792bfc9582cer10 dcs:item _:r1627689586r6, _:r1627689586r7 . | |
51 | _:rbe72dc1a36f85473b87f4792bfc9582cer11 doap:browse <https://github.com/tobyink/p5-module-install-rdf> ; | |
52 | a doap:GitRepository . | |
53 | _:rbe72dc1a36f85473b87f4792bfc9582cer12 rdfs:label "Semantic Web" . | |
54 | _:rbe72dc1a36f85473b87f4792bfc9582cer13 rdfs:label "Packaging" . | |
55 | _:rbe72dc1a36f85473b87f4792bfc9582cer5 dcs:item _:r1627689586r1 . | |
56 | _:rbe72dc1a36f85473b87f4792bfc9582cer6 dcs:item _:r1627689586r2 . | |
57 | _:rbe72dc1a36f85473b87f4792bfc9582cer7 dcs:item _:r1627689586r3 . | |
58 | _:rbe72dc1a36f85473b87f4792bfc9582cer8 dcs:item _:r1627689586r4 . | |
59 | _:rbe72dc1a36f85473b87f4792bfc9582cer9 dcs:item _:r1627689586r5 . | |
60 | dist:project cpant:perl_version_from _:r1627689586r8 ; | |
61 | cpant:readme_from _:r1627689586r10 ; | |
62 | cpant:requires "Module::Install 1.00"^^cpant:dsWithVersion, "Module::Runtime"^^cpant:dsWithoutVersion, "Object::ID"^^cpant:dsWithoutVersion, "RDF::TriN3 0.201"^^cpant:dsWithVersion, "RDF::Trine 0.135"^^cpant:dsWithVersion, "URI::file 4.0"^^cpant:dsWithVersion ; | |
63 | cpant:test_requires "Test::More 0.61"^^cpant:dsWithVersion ; | |
64 | cpant:version_from _:r1627689586r9 ; | |
65 | <http://purl.org/dc/terms/contributor> cpan:tobyink ; | |
66 | doap:bug-database <http://rt.cpan.org/Dist/Display.html?Queue=Module-Install-RDF> ; | |
67 | doap:category _:rbe72dc1a36f85473b87f4792bfc9582cer12, _:rbe72dc1a36f85473b87f4792bfc9582cer13 ; | |
68 | doap:created "2011-09-30"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
69 | doap:developer cpan:tobyink ; | |
70 | doap:documenter cpan:tobyink ; | |
71 | doap:download-page <https://metacpan.org/release/Module-Install-RDF> ; | |
72 | doap:homepage <https://metacpan.org/release/Module-Install-RDF> ; | |
73 | doap:license <http://dev.perl.org/licenses/> ; | |
74 | doap:maintainer cpan:tobyink ; | |
75 | doap:name "Module-Install-RDF" ; | |
76 | doap:programming-language "Perl" ; | |
77 | doap:release dist:v_0-001, dist:v_0-002, dist:v_0-003, dist:v_0-004, dist:v_0-005, dist:v_0-006, dist:v_0-007, dist:v_0-008, dist:v_0-009 ; | |
78 | doap:repository _:rbe72dc1a36f85473b87f4792bfc9582cer11 ; | |
79 | doap:shortdesc "advanced metadata for your distribution"@en ; | |
80 | doap:tester cpan:tobyink ; | |
81 | a doap:Project . | |
82 | dist:v_0-001 dcs:released-by cpan:tobyink ; | |
83 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.001"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
84 | <http://purl.org/dc/terms/issued> "2011-10-01"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
85 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.001.tar.gz> ; | |
86 | doap:revision "0.001"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
87 | a doap:Version ; | |
88 | rdfs:label "Initial release" . | |
89 | dist:v_0-002 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer0 ; | |
90 | dcs:released-by cpan:tobyink ; | |
91 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.002"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
92 | <http://purl.org/dc/terms/issued> "2011-10-06"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
93 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.002.tar.gz> ; | |
94 | doap:revision "0.002"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
95 | a doap:Version . | |
96 | dist:v_0-003 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer1 ; | |
97 | dcs:released-by cpan:tobyink ; | |
98 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.003"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
99 | <http://purl.org/dc/terms/issued> "2011-11-26"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
100 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.003.tar.gz> ; | |
101 | doap:revision "0.003"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
102 | a doap:Version . | |
103 | dist:v_0-004 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer5 ; | |
104 | dcs:released-by cpan:tobyink ; | |
105 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.004"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
106 | <http://purl.org/dc/terms/issued> "2011-12-03"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
107 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.004.tar.gz> ; | |
108 | doap:revision "0.004"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
109 | a doap:Version . | |
110 | dist:v_0-005 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer6 ; | |
111 | dcs:released-by cpan:tobyink ; | |
112 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.005"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
113 | <http://purl.org/dc/terms/issued> "2012-07-04"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
114 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.005.tar.gz> ; | |
115 | doap:revision "0.005"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
116 | a doap:Version . | |
117 | dist:v_0-006 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer7 ; | |
118 | dcs:released-by cpan:tobyink ; | |
119 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.006"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
120 | <http://purl.org/dc/terms/issued> "2012-07-04"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
121 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.006.tar.gz> ; | |
122 | doap:revision "0.006"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
123 | a doap:Version . | |
124 | dist:v_0-007 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer8 ; | |
125 | dcs:released-by cpan:tobyink ; | |
126 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.007"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
127 | <http://purl.org/dc/terms/issued> "2012-07-05"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
128 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.007.tar.gz> ; | |
129 | doap:revision "0.007"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
130 | a doap:Version ; | |
131 | rdfs:label "Bond, James Bond" . | |
132 | dist:v_0-008 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer9 ; | |
133 | dcs:released-by cpan:tobyink ; | |
134 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.008"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
135 | <http://purl.org/dc/terms/issued> "2013-03-16"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
136 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.008.tar.gz> ; | |
137 | doap:revision "0.008"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
138 | a doap:Version . | |
139 | dist:v_0-009 dcs:changeset _:rbe72dc1a36f85473b87f4792bfc9582cer10 ; | |
140 | dcs:released-by cpan:tobyink ; | |
141 | <http://purl.org/dc/terms/identifier> "Module-Install-RDF-0.009"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
142 | <http://purl.org/dc/terms/issued> "2013-07-31"^^<http://www.w3.org/2001/XMLSchema#date> ; | |
143 | doap:file-release <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Module-Install-RDF-0.009.tar.gz> ; | |
144 | doap:revision "0.009"^^<http://www.w3.org/2001/XMLSchema#string> ; | |
145 | a doap:Version . | |
146 | cpan:tobyink a foaf:Person ; | |
147 | foaf:homepage <http://tobyinkster.co.uk/> ; | |
148 | foaf:mbox <mailto:tobyink@cpan.org> ; | |
149 | foaf:name "Toby Inkster" ; | |
150 | foaf:nick "tobyink" ; | |
151 | foaf:page <https://metacpan.org/author/TOBYINK> . |
0 | use inc::Module::Package 'RDF:tobyink 0.011'; |
0 | NAME | |
1 | Module::Install::RDF - advanced metadata for your distribution | |
2 | ||
3 | SYNOPSIS | |
4 | In Makefile.PL: | |
5 | ||
6 | rdf_metadata; # reads "meta/*" | |
7 | write_meta_ttl; # writes "META.ttl" | |
8 | ||
9 | DESCRIPTION | |
10 | This module doesn't really do much on its own, but is a pre-requisite | |
11 | for Module::Install::DOAP. | |
12 | ||
13 | Specifically, it reads all the RDF it can find in the distribution's | |
14 | "meta" directory and exposes it for other modules to make use of. It | |
15 | also allows you to write out a combined graph using Turtle. | |
16 | ||
17 | BUGS | |
18 | Please report any bugs to <http://rt.cpan.org/>. | |
19 | ||
20 | SEE ALSO | |
21 | Module::Install, Module::Install::DOAP, Module::Install::DOAPChangeSets | |
22 | . | |
23 | ||
24 | <http://www.perlrdf.org/>. | |
25 | ||
26 | AUTHOR | |
27 | Toby Inkster <tobyink@cpan.org>. | |
28 | ||
29 | COPYRIGHT AND LICENSE | |
30 | Copyright (C) 2011-2013 by Toby Inkster | |
31 | ||
32 | This library is free software; you can redistribute it and/or modify it | |
33 | under the same terms as Perl itself. | |
34 | ||
35 | DISCLAIMER OF WARRANTIES | |
36 | THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED | |
37 | WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | |
38 | MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
39 |
0 | #line 1 | |
1 | package Module::AutoInstall; | |
2 | ||
3 | use strict; | |
4 | use Cwd (); | |
5 | use File::Spec (); | |
6 | use ExtUtils::MakeMaker (); | |
7 | ||
8 | use vars qw{$VERSION}; | |
9 | BEGIN { | |
10 | $VERSION = '1.19'; | |
11 | } | |
12 | ||
13 | # special map on pre-defined feature sets | |
14 | my %FeatureMap = ( | |
15 | '' => 'Core Features', # XXX: deprecated | |
16 | '-core' => 'Core Features', | |
17 | ); | |
18 | ||
19 | # various lexical flags | |
20 | my ( @Missing, @Existing, %DisabledTests, $UnderCPAN, $InstallDepsTarget, $HasCPANPLUS ); | |
21 | my ( | |
22 | $Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly, $AllDeps, | |
23 | $UpgradeDeps | |
24 | ); | |
25 | my ( $PostambleActions, $PostambleActionsNoTest, $PostambleActionsUpgradeDeps, | |
26 | $PostambleActionsUpgradeDepsNoTest, $PostambleActionsListDeps, | |
27 | $PostambleActionsListAllDeps, $PostambleUsed, $NoTest); | |
28 | ||
29 | # See if it's a testing or non-interactive session | |
30 | _accept_default( $ENV{AUTOMATED_TESTING} or ! -t STDIN ); | |
31 | _init(); | |
32 | ||
33 | sub _accept_default { | |
34 | $AcceptDefault = shift; | |
35 | } | |
36 | ||
37 | sub _installdeps_target { | |
38 | $InstallDepsTarget = shift; | |
39 | } | |
40 | ||
41 | sub missing_modules { | |
42 | return @Missing; | |
43 | } | |
44 | ||
45 | sub do_install { | |
46 | __PACKAGE__->install( | |
47 | [ | |
48 | $Config | |
49 | ? ( UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) | |
50 | : () | |
51 | ], | |
52 | @Missing, | |
53 | ); | |
54 | } | |
55 | ||
56 | # initialize various flags, and/or perform install | |
57 | sub _init { | |
58 | foreach my $arg ( | |
59 | @ARGV, | |
60 | split( | |
61 | /[\s\t]+/, | |
62 | $ENV{PERL_AUTOINSTALL} || $ENV{PERL_EXTUTILS_AUTOINSTALL} || '' | |
63 | ) | |
64 | ) | |
65 | { | |
66 | if ( $arg =~ /^--config=(.*)$/ ) { | |
67 | $Config = [ split( ',', $1 ) ]; | |
68 | } | |
69 | elsif ( $arg =~ /^--installdeps=(.*)$/ ) { | |
70 | __PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) ); | |
71 | exit 0; | |
72 | } | |
73 | elsif ( $arg =~ /^--upgradedeps=(.*)$/ ) { | |
74 | $UpgradeDeps = 1; | |
75 | __PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) ); | |
76 | exit 0; | |
77 | } | |
78 | elsif ( $arg =~ /^--default(?:deps)?$/ ) { | |
79 | $AcceptDefault = 1; | |
80 | } | |
81 | elsif ( $arg =~ /^--check(?:deps)?$/ ) { | |
82 | $CheckOnly = 1; | |
83 | } | |
84 | elsif ( $arg =~ /^--skip(?:deps)?$/ ) { | |
85 | $SkipInstall = 1; | |
86 | } | |
87 | elsif ( $arg =~ /^--test(?:only)?$/ ) { | |
88 | $TestOnly = 1; | |
89 | } | |
90 | elsif ( $arg =~ /^--all(?:deps)?$/ ) { | |
91 | $AllDeps = 1; | |
92 | } | |
93 | } | |
94 | } | |
95 | ||
96 | # overrides MakeMaker's prompt() to automatically accept the default choice | |
97 | sub _prompt { | |
98 | goto &ExtUtils::MakeMaker::prompt unless $AcceptDefault; | |
99 | ||
100 | my ( $prompt, $default ) = @_; | |
101 | my $y = ( $default =~ /^[Yy]/ ); | |
102 | ||
103 | print $prompt, ' [', ( $y ? 'Y' : 'y' ), '/', ( $y ? 'n' : 'N' ), '] '; | |
104 | print "$default\n"; | |
105 | return $default; | |
106 | } | |
107 | ||
108 | # the workhorse | |
109 | sub import { | |
110 | my $class = shift; | |
111 | my @args = @_ or return; | |
112 | my $core_all; | |
113 | ||
114 | print "*** $class version " . $class->VERSION . "\n"; | |
115 | print "*** Checking for Perl dependencies...\n"; | |
116 | ||
117 | my $cwd = Cwd::getcwd(); | |
118 | ||
119 | $Config = []; | |
120 | ||
121 | my $maxlen = length( | |
122 | ( | |
123 | sort { length($b) <=> length($a) } | |
124 | grep { /^[^\-]/ } | |
125 | map { | |
126 | ref($_) | |
127 | ? ( ( ref($_) eq 'HASH' ) ? keys(%$_) : @{$_} ) | |
128 | : '' | |
129 | } | |
130 | map { +{@args}->{$_} } | |
131 | grep { /^[^\-]/ or /^-core$/i } keys %{ +{@args} } | |
132 | )[0] | |
133 | ); | |
134 | ||
135 | # We want to know if we're under CPAN early to avoid prompting, but | |
136 | # if we aren't going to try and install anything anyway then skip the | |
137 | # check entirely since we don't want to have to load (and configure) | |
138 | # an old CPAN just for a cosmetic message | |
139 | ||
140 | $UnderCPAN = _check_lock(1) unless $SkipInstall || $InstallDepsTarget; | |
141 | ||
142 | while ( my ( $feature, $modules ) = splice( @args, 0, 2 ) ) { | |
143 | my ( @required, @tests, @skiptests ); | |
144 | my $default = 1; | |
145 | my $conflict = 0; | |
146 | ||
147 | if ( $feature =~ m/^-(\w+)$/ ) { | |
148 | my $option = lc($1); | |
149 | ||
150 | # check for a newer version of myself | |
151 | _update_to( $modules, @_ ) and return if $option eq 'version'; | |
152 | ||
153 | # sets CPAN configuration options | |
154 | $Config = $modules if $option eq 'config'; | |
155 | ||
156 | # promote every features to core status | |
157 | $core_all = ( $modules =~ /^all$/i ) and next | |
158 | if $option eq 'core'; | |
159 | ||
160 | next unless $option eq 'core'; | |
161 | } | |
162 | ||
163 | print "[" . ( $FeatureMap{ lc($feature) } || $feature ) . "]\n"; | |
164 | ||
165 | $modules = [ %{$modules} ] if UNIVERSAL::isa( $modules, 'HASH' ); | |
166 | ||
167 | unshift @$modules, -default => &{ shift(@$modules) } | |
168 | if ( ref( $modules->[0] ) eq 'CODE' ); # XXX: bugward compatibility | |
169 | ||
170 | while ( my ( $mod, $arg ) = splice( @$modules, 0, 2 ) ) { | |
171 | if ( $mod =~ m/^-(\w+)$/ ) { | |
172 | my $option = lc($1); | |
173 | ||
174 | $default = $arg if ( $option eq 'default' ); | |
175 | $conflict = $arg if ( $option eq 'conflict' ); | |
176 | @tests = @{$arg} if ( $option eq 'tests' ); | |
177 | @skiptests = @{$arg} if ( $option eq 'skiptests' ); | |
178 | ||
179 | next; | |
180 | } | |
181 | ||
182 | printf( "- %-${maxlen}s ...", $mod ); | |
183 | ||
184 | if ( $arg and $arg =~ /^\D/ ) { | |
185 | unshift @$modules, $arg; | |
186 | $arg = 0; | |
187 | } | |
188 | ||
189 | # XXX: check for conflicts and uninstalls(!) them. | |
190 | my $cur = _version_of($mod); | |
191 | if (_version_cmp ($cur, $arg) >= 0) | |
192 | { | |
193 | print "loaded. ($cur" . ( $arg ? " >= $arg" : '' ) . ")\n"; | |
194 | push @Existing, $mod => $arg; | |
195 | $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; | |
196 | } | |
197 | else { | |
198 | if (not defined $cur) # indeed missing | |
199 | { | |
200 | print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n"; | |
201 | } | |
202 | else | |
203 | { | |
204 | # no need to check $arg as _version_cmp ($cur, undef) would satisfy >= above | |
205 | print "too old. ($cur < $arg)\n"; | |
206 | } | |
207 | ||
208 | push @required, $mod => $arg; | |
209 | } | |
210 | } | |
211 | ||
212 | next unless @required; | |
213 | ||
214 | my $mandatory = ( $feature eq '-core' or $core_all ); | |
215 | ||
216 | if ( | |
217 | !$SkipInstall | |
218 | and ( | |
219 | $CheckOnly | |
220 | or ($mandatory and $UnderCPAN) | |
221 | or $AllDeps | |
222 | or $InstallDepsTarget | |
223 | or _prompt( | |
224 | qq{==> Auto-install the } | |
225 | . ( @required / 2 ) | |
226 | . ( $mandatory ? ' mandatory' : ' optional' ) | |
227 | . qq{ module(s) from CPAN?}, | |
228 | $default ? 'y' : 'n', | |
229 | ) =~ /^[Yy]/ | |
230 | ) | |
231 | ) | |
232 | { | |
233 | push( @Missing, @required ); | |
234 | $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; | |
235 | } | |
236 | ||
237 | elsif ( !$SkipInstall | |
238 | and $default | |
239 | and $mandatory | |
240 | and | |
241 | _prompt( qq{==> The module(s) are mandatory! Really skip?}, 'n', ) | |
242 | =~ /^[Nn]/ ) | |
243 | { | |
244 | push( @Missing, @required ); | |
245 | $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; | |
246 | } | |
247 | ||
248 | else { | |
249 | $DisabledTests{$_} = 1 for map { glob($_) } @tests; | |
250 | } | |
251 | } | |
252 | ||
253 | if ( @Missing and not( $CheckOnly or $UnderCPAN) ) { | |
254 | require Config; | |
255 | my $make = $Config::Config{make}; | |
256 | if ($InstallDepsTarget) { | |
257 | ||
258 | "*** To install dependencies type '$make installdeps' or '$make installdeps_notest'.\n"; | |
259 | } | |
260 | else { | |
261 | ||
262 | "*** Dependencies will be installed the next time you type '$make'.\n"; | |
263 | } | |
264 | ||
265 | # make an educated guess of whether we'll need root permission. | |
266 | print " (You may need to do that as the 'root' user.)\n" | |
267 | if eval '$>'; | |
268 | } | |
269 | print "*** $class configuration finished.\n"; | |
270 | ||
271 | chdir $cwd; | |
272 | ||
273 | # import to main:: | |
274 | no strict 'refs'; | |
275 | *{'main::WriteMakefile'} = \&Write if caller(0) eq 'main'; | |
276 | ||
277 | return (@Existing, @Missing); | |
278 | } | |
279 | ||
280 | sub _running_under { | |
281 | my $thing = shift; | |
282 | print <<"END_MESSAGE"; | |
283 | *** Since we're running under ${thing}, I'll just let it take care | |
284 | of the dependency's installation later. | |
285 | END_MESSAGE | |
286 | return 1; | |
287 | } | |
288 | ||
289 | # Check to see if we are currently running under CPAN.pm and/or CPANPLUS; | |
290 | # if we are, then we simply let it taking care of our dependencies | |
291 | sub _check_lock { | |
292 | return unless @Missing or @_; | |
293 | ||
294 | if ($ENV{PERL5_CPANM_IS_RUNNING}) { | |
295 | return _running_under('cpanminus'); | |
296 | } | |
297 | ||
298 | my $cpan_env = $ENV{PERL5_CPAN_IS_RUNNING}; | |
299 | ||
300 | if ($ENV{PERL5_CPANPLUS_IS_RUNNING}) { | |
301 | return _running_under($cpan_env ? 'CPAN' : 'CPANPLUS'); | |
302 | } | |
303 | ||
304 | require CPAN; | |
305 | ||
306 | if ($CPAN::VERSION > '1.89') { | |
307 | if ($cpan_env) { | |
308 | return _running_under('CPAN'); | |
309 | } | |
310 | return; # CPAN.pm new enough, don't need to check further | |
311 | } | |
312 | ||
313 | # last ditch attempt, this -will- configure CPAN, very sorry | |
314 | ||
315 | _load_cpan(1); # force initialize even though it's already loaded | |
316 | ||
317 | # Find the CPAN lock-file | |
318 | my $lock = MM->catfile( $CPAN::Config->{cpan_home}, ".lock" ); | |
319 | return unless -f $lock; | |
320 | ||
321 | # Check the lock | |
322 | local *LOCK; | |
323 | return unless open(LOCK, $lock); | |
324 | ||
325 | if ( | |
326 | ( $^O eq 'MSWin32' ? _under_cpan() : <LOCK> == getppid() ) | |
327 | and ( $CPAN::Config->{prerequisites_policy} || '' ) ne 'ignore' | |
328 | ) { | |
329 | print <<'END_MESSAGE'; | |
330 | ||
331 | *** Since we're running under CPAN, I'll just let it take care | |
332 | of the dependency's installation later. | |
333 | END_MESSAGE | |
334 | return 1; | |
335 | } | |
336 | ||
337 | close LOCK; | |
338 | return; | |
339 | } | |
340 | ||
341 | sub install { | |
342 | my $class = shift; | |
343 | ||
344 | my $i; # used below to strip leading '-' from config keys | |
345 | my @config = ( map { s/^-// if ++$i; $_ } @{ +shift } ); | |
346 | ||
347 | my ( @modules, @installed, @modules_to_upgrade ); | |
348 | while (my ($pkg, $ver) = splice(@_, 0, 2)) { | |
349 | ||
350 | # grep out those already installed | |
351 | if (_version_cmp(_version_of($pkg), $ver) >= 0) { | |
352 | push @installed, $pkg; | |
353 | if ($UpgradeDeps) { | |
354 | push @modules_to_upgrade, $pkg, $ver; | |
355 | } | |
356 | } | |
357 | else { | |
358 | push @modules, $pkg, $ver; | |
359 | } | |
360 | } | |
361 | ||
362 | if ($UpgradeDeps) { | |
363 | push @modules, @modules_to_upgrade; | |
364 | @installed = (); | |
365 | @modules_to_upgrade = (); | |
366 | } | |
367 | ||
368 | return @installed unless @modules; # nothing to do | |
369 | return @installed if _check_lock(); # defer to the CPAN shell | |
370 | ||
371 | print "*** Installing dependencies...\n"; | |
372 | ||
373 | return unless _connected_to('cpan.org'); | |
374 | ||
375 | my %args = @config; | |
376 | my %failed; | |
377 | local *FAILED; | |
378 | if ( $args{do_once} and open( FAILED, '.#autoinstall.failed' ) ) { | |
379 | while (<FAILED>) { chomp; $failed{$_}++ } | |
380 | close FAILED; | |
381 | ||
382 | my @newmod; | |
383 | while ( my ( $k, $v ) = splice( @modules, 0, 2 ) ) { | |
384 | push @newmod, ( $k => $v ) unless $failed{$k}; | |
385 | } | |
386 | @modules = @newmod; | |
387 | } | |
388 | ||
389 | if ( _has_cpanplus() and not $ENV{PERL_AUTOINSTALL_PREFER_CPAN} ) { | |
390 | _install_cpanplus( \@modules, \@config ); | |
391 | } else { | |
392 | _install_cpan( \@modules, \@config ); | |
393 | } | |
394 | ||
395 | print "*** $class installation finished.\n"; | |
396 | ||
397 | # see if we have successfully installed them | |
398 | while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { | |
399 | if ( _version_cmp( _version_of($pkg), $ver ) >= 0 ) { | |
400 | push @installed, $pkg; | |
401 | } | |
402 | elsif ( $args{do_once} and open( FAILED, '>> .#autoinstall.failed' ) ) { | |
403 | print FAILED "$pkg\n"; | |
404 | } | |
405 | } | |
406 | ||
407 | close FAILED if $args{do_once}; | |
408 | ||
409 | return @installed; | |
410 | } | |
411 | ||
412 | sub _install_cpanplus { | |
413 | my @modules = @{ +shift }; | |
414 | my @config = _cpanplus_config( @{ +shift } ); | |
415 | my $installed = 0; | |
416 | ||
417 | require CPANPLUS::Backend; | |
418 | my $cp = CPANPLUS::Backend->new; | |
419 | my $conf = $cp->configure_object; | |
420 | ||
421 | return unless $conf->can('conf') # 0.05x+ with "sudo" support | |
422 | or _can_write($conf->_get_build('base')); # 0.04x | |
423 | ||
424 | # if we're root, set UNINST=1 to avoid trouble unless user asked for it. | |
425 | my $makeflags = $conf->get_conf('makeflags') || ''; | |
426 | if ( UNIVERSAL::isa( $makeflags, 'HASH' ) ) { | |
427 | # 0.03+ uses a hashref here | |
428 | $makeflags->{UNINST} = 1 unless exists $makeflags->{UNINST}; | |
429 | ||
430 | } else { | |
431 | # 0.02 and below uses a scalar | |
432 | $makeflags = join( ' ', split( ' ', $makeflags ), 'UNINST=1' ) | |
433 | if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } ); | |
434 | ||
435 | } | |
436 | $conf->set_conf( makeflags => $makeflags ); | |
437 | $conf->set_conf( prereqs => 1 ); | |
438 | ||
439 | ||
440 | ||
441 | while ( my ( $key, $val ) = splice( @config, 0, 2 ) ) { | |
442 | $conf->set_conf( $key, $val ); | |
443 | } | |
444 | ||
445 | my $modtree = $cp->module_tree; | |
446 | while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { | |
447 | print "*** Installing $pkg...\n"; | |
448 | ||
449 | MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall; | |
450 | ||
451 | my $success; | |
452 | my $obj = $modtree->{$pkg}; | |
453 | ||
454 | if ( $obj and _version_cmp( $obj->{version}, $ver ) >= 0 ) { | |
455 | my $pathname = $pkg; | |
456 | $pathname =~ s/::/\\W/; | |
457 | ||
458 | foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) { | |
459 | delete $INC{$inc}; | |
460 | } | |
461 | ||
462 | my $rv = $cp->install( modules => [ $obj->{module} ] ); | |
463 | ||
464 | if ( $rv and ( $rv->{ $obj->{module} } or $rv->{ok} ) ) { | |
465 | print "*** $pkg successfully installed.\n"; | |
466 | $success = 1; | |
467 | } else { | |
468 | print "*** $pkg installation cancelled.\n"; | |
469 | $success = 0; | |
470 | } | |
471 | ||
472 | $installed += $success; | |
473 | } else { | |
474 | print << "."; | |
475 | *** Could not find a version $ver or above for $pkg; skipping. | |
476 | . | |
477 | } | |
478 | ||
479 | MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall; | |
480 | } | |
481 | ||
482 | return $installed; | |
483 | } | |
484 | ||
485 | sub _cpanplus_config { | |
486 | my @config = (); | |
487 | while ( @_ ) { | |
488 | my ($key, $value) = (shift(), shift()); | |
489 | if ( $key eq 'prerequisites_policy' ) { | |
490 | if ( $value eq 'follow' ) { | |
491 | $value = CPANPLUS::Internals::Constants::PREREQ_INSTALL(); | |
492 | } elsif ( $value eq 'ask' ) { | |
493 | $value = CPANPLUS::Internals::Constants::PREREQ_ASK(); | |
494 | } elsif ( $value eq 'ignore' ) { | |
495 | $value = CPANPLUS::Internals::Constants::PREREQ_IGNORE(); | |
496 | } else { | |
497 | die "*** Cannot convert option $key = '$value' to CPANPLUS version.\n"; | |
498 | } | |
499 | push @config, 'prereqs', $value; | |
500 | } elsif ( $key eq 'force' ) { | |
501 | push @config, $key, $value; | |
502 | } elsif ( $key eq 'notest' ) { | |
503 | push @config, 'skiptest', $value; | |
504 | } else { | |
505 | die "*** Cannot convert option $key to CPANPLUS version.\n"; | |
506 | } | |
507 | } | |
508 | return @config; | |
509 | } | |
510 | ||
511 | sub _install_cpan { | |
512 | my @modules = @{ +shift }; | |
513 | my @config = @{ +shift }; | |
514 | my $installed = 0; | |
515 | my %args; | |
516 | ||
517 | _load_cpan(); | |
518 | require Config; | |
519 | ||
520 | if (CPAN->VERSION < 1.80) { | |
521 | # no "sudo" support, probe for writableness | |
522 | return unless _can_write( MM->catfile( $CPAN::Config->{cpan_home}, 'sources' ) ) | |
523 | and _can_write( $Config::Config{sitelib} ); | |
524 | } | |
525 | ||
526 | # if we're root, set UNINST=1 to avoid trouble unless user asked for it. | |
527 | my $makeflags = $CPAN::Config->{make_install_arg} || ''; | |
528 | $CPAN::Config->{make_install_arg} = | |
529 | join( ' ', split( ' ', $makeflags ), 'UNINST=1' ) | |
530 | if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } ); | |
531 | ||
532 | # don't show start-up info | |
533 | $CPAN::Config->{inhibit_startup_message} = 1; | |
534 | ||
535 | # set additional options | |
536 | while ( my ( $opt, $arg ) = splice( @config, 0, 2 ) ) { | |
537 | ( $args{$opt} = $arg, next ) | |
538 | if $opt =~ /^(?:force|notest)$/; # pseudo-option | |
539 | $CPAN::Config->{$opt} = $opt eq 'urllist' ? [$arg] : $arg; | |
540 | } | |
541 | ||
542 | if ($args{notest} && (not CPAN::Shell->can('notest'))) { | |
543 | die "Your version of CPAN is too old to support the 'notest' pragma"; | |
544 | } | |
545 | ||
546 | local $CPAN::Config->{prerequisites_policy} = 'follow'; | |
547 | ||
548 | while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { | |
549 | MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall; | |
550 | ||
551 | print "*** Installing $pkg...\n"; | |
552 | ||
553 | my $obj = CPAN::Shell->expand( Module => $pkg ); | |
554 | my $success = 0; | |
555 | ||
556 | if ( $obj and _version_cmp( $obj->cpan_version, $ver ) >= 0 ) { | |
557 | my $pathname = $pkg; | |
558 | $pathname =~ s/::/\\W/; | |
559 | ||
560 | foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) { | |
561 | delete $INC{$inc}; | |
562 | } | |
563 | ||
564 | my $rv = do { | |
565 | if ($args{force}) { | |
566 | CPAN::Shell->force( install => $pkg ) | |
567 | } elsif ($args{notest}) { | |
568 | CPAN::Shell->notest( install => $pkg ) | |
569 | } else { | |
570 | CPAN::Shell->install($pkg) | |
571 | } | |
572 | }; | |
573 | ||
574 | $rv ||= eval { | |
575 | $CPAN::META->instance( 'CPAN::Distribution', $obj->cpan_file, ) | |
576 | ->{install} | |
577 | if $CPAN::META; | |
578 | }; | |
579 | ||
580 | if ( $rv eq 'YES' ) { | |
581 | print "*** $pkg successfully installed.\n"; | |
582 | $success = 1; | |
583 | } | |
584 | else { | |
585 | print "*** $pkg installation failed.\n"; | |
586 | $success = 0; | |
587 | } | |
588 | ||
589 | $installed += $success; | |
590 | } | |
591 | else { | |
592 | print << "."; | |
593 | *** Could not find a version $ver or above for $pkg; skipping. | |
594 | . | |
595 | } | |
596 | ||
597 | MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall; | |
598 | } | |
599 | ||
600 | return $installed; | |
601 | } | |
602 | ||
603 | sub _has_cpanplus { | |
604 | return ( | |
605 | $HasCPANPLUS = ( | |
606 | $INC{'CPANPLUS/Config.pm'} | |
607 | or _load('CPANPLUS::Shell::Default') | |
608 | ) | |
609 | ); | |
610 | } | |
611 | ||
612 | # make guesses on whether we're under the CPAN installation directory | |
613 | sub _under_cpan { | |
614 | require Cwd; | |
615 | require File::Spec; | |
616 | ||
617 | my $cwd = File::Spec->canonpath( Cwd::getcwd() ); | |
618 | my $cpan = File::Spec->canonpath( $CPAN::Config->{cpan_home} ); | |
619 | ||
620 | return ( index( $cwd, $cpan ) > -1 ); | |
621 | } | |
622 | ||
623 | sub _update_to { | |
624 | my $class = __PACKAGE__; | |
625 | my $ver = shift; | |
626 | ||
627 | return | |
628 | if _version_cmp( _version_of($class), $ver ) >= 0; # no need to upgrade | |
629 | ||
630 | if ( | |
631 | _prompt( "==> A newer version of $class ($ver) is required. Install?", | |
632 | 'y' ) =~ /^[Nn]/ | |
633 | ) | |
634 | { | |
635 | die "*** Please install $class $ver manually.\n"; | |
636 | } | |
637 | ||
638 | print << "."; | |
639 | *** Trying to fetch it from CPAN... | |
640 | . | |
641 | ||
642 | # install ourselves | |
643 | _load($class) and return $class->import(@_) | |
644 | if $class->install( [], $class, $ver ); | |
645 | ||
646 | print << '.'; exit 1; | |
647 | ||
648 | *** Cannot bootstrap myself. :-( Installation terminated. | |
649 | . | |
650 | } | |
651 | ||
652 | # check if we're connected to some host, using inet_aton | |
653 | sub _connected_to { | |
654 | my $site = shift; | |
655 | ||
656 | return ( | |
657 | ( _load('Socket') and Socket::inet_aton($site) ) or _prompt( | |
658 | qq( | |
659 | *** Your host cannot resolve the domain name '$site', which | |
660 | probably means the Internet connections are unavailable. | |
661 | ==> Should we try to install the required module(s) anyway?), 'n' | |
662 | ) =~ /^[Yy]/ | |
663 | ); | |
664 | } | |
665 | ||
666 | # check if a directory is writable; may create it on demand | |
667 | sub _can_write { | |
668 | my $path = shift; | |
669 | mkdir( $path, 0755 ) unless -e $path; | |
670 | ||
671 | return 1 if -w $path; | |
672 | ||
673 | print << "."; | |
674 | *** You are not allowed to write to the directory '$path'; | |
675 | the installation may fail due to insufficient permissions. | |
676 | . | |
677 | ||
678 | if ( | |
679 | eval '$>' and lc(`sudo -V`) =~ /version/ and _prompt( | |
680 | qq( | |
681 | ==> Should we try to re-execute the autoinstall process with 'sudo'?), | |
682 | ((-t STDIN) ? 'y' : 'n') | |
683 | ) =~ /^[Yy]/ | |
684 | ) | |
685 | { | |
686 | ||
687 | # try to bootstrap ourselves from sudo | |
688 | print << "."; | |
689 | *** Trying to re-execute the autoinstall process with 'sudo'... | |
690 | . | |
691 | my $missing = join( ',', @Missing ); | |
692 | my $config = join( ',', | |
693 | UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) | |
694 | if $Config; | |
695 | ||
696 | return | |
697 | unless system( 'sudo', $^X, $0, "--config=$config", | |
698 | "--installdeps=$missing" ); | |
699 | ||
700 | print << "."; | |
701 | *** The 'sudo' command exited with error! Resuming... | |
702 | . | |
703 | } | |
704 | ||
705 | return _prompt( | |
706 | qq( | |
707 | ==> Should we try to install the required module(s) anyway?), 'n' | |
708 | ) =~ /^[Yy]/; | |
709 | } | |
710 | ||
711 | # load a module and return the version it reports | |
712 | sub _load { | |
713 | my $mod = pop; # method/function doesn't matter | |
714 | my $file = $mod; | |
715 | $file =~ s|::|/|g; | |
716 | $file .= '.pm'; | |
717 | local $@; | |
718 | return eval { require $file; $mod->VERSION } || ( $@ ? undef: 0 ); | |
719 | } | |
720 | ||
721 | # report version without loading a module | |
722 | sub _version_of { | |
723 | my $mod = pop; # method/function doesn't matter | |
724 | my $file = $mod; | |
725 | $file =~ s|::|/|g; | |
726 | $file .= '.pm'; | |
727 | foreach my $dir ( @INC ) { | |
728 | next if ref $dir; | |
729 | my $path = File::Spec->catfile($dir, $file); | |
730 | next unless -e $path; | |
731 | require ExtUtils::MM_Unix; | |
732 | return ExtUtils::MM_Unix->parse_version($path); | |
733 | } | |
734 | return undef; | |
735 | } | |
736 | ||
737 | # Load CPAN.pm and it's configuration | |
738 | sub _load_cpan { | |
739 | return if $CPAN::VERSION and $CPAN::Config and not @_; | |
740 | require CPAN; | |
741 | ||
742 | # CPAN-1.82+ adds CPAN::Config::AUTOLOAD to redirect to | |
743 | # CPAN::HandleConfig->load. CPAN reports that the redirection | |
744 | # is deprecated in a warning printed at the user. | |
745 | ||
746 | # CPAN-1.81 expects CPAN::HandleConfig->load, does not have | |
747 | # $CPAN::HandleConfig::VERSION but cannot handle | |
748 | # CPAN::Config->load | |
749 | ||
750 | # Which "versions expect CPAN::Config->load? | |
751 | ||
752 | if ( $CPAN::HandleConfig::VERSION | |
753 | || CPAN::HandleConfig->can('load') | |
754 | ) { | |
755 | # Newer versions of CPAN have a HandleConfig module | |
756 | CPAN::HandleConfig->load; | |
757 | } else { | |
758 | # Older versions had the load method in Config directly | |
759 | CPAN::Config->load; | |
760 | } | |
761 | } | |
762 | ||
763 | # compare two versions, either use Sort::Versions or plain comparison | |
764 | # return values same as <=> | |
765 | sub _version_cmp { | |
766 | my ( $cur, $min ) = @_; | |
767 | return -1 unless defined $cur; # if 0 keep comparing | |
768 | return 1 unless $min; | |
769 | ||
770 | $cur =~ s/\s+$//; | |
771 | ||
772 | # check for version numbers that are not in decimal format | |
773 | if ( ref($cur) or ref($min) or $cur =~ /v|\..*\./ or $min =~ /v|\..*\./ ) { | |
774 | if ( ( $version::VERSION or defined( _load('version') )) and | |
775 | version->can('new') | |
776 | ) { | |
777 | ||
778 | # use version.pm if it is installed. | |
779 | return version->new($cur) <=> version->new($min); | |
780 | } | |
781 | elsif ( $Sort::Versions::VERSION or defined( _load('Sort::Versions') ) ) | |
782 | { | |
783 | ||
784 | # use Sort::Versions as the sorting algorithm for a.b.c versions | |
785 | return Sort::Versions::versioncmp( $cur, $min ); | |
786 | } | |
787 | ||
788 | warn "Cannot reliably compare non-decimal formatted versions.\n" | |
789 | . "Please install version.pm or Sort::Versions.\n"; | |
790 | } | |
791 | ||
792 | # plain comparison | |
793 | local $^W = 0; # shuts off 'not numeric' bugs | |
794 | return $cur <=> $min; | |
795 | } | |
796 | ||
797 | # nothing; this usage is deprecated. | |
798 | sub main::PREREQ_PM { return {}; } | |
799 | ||
800 | sub _make_args { | |
801 | my %args = @_; | |
802 | ||
803 | $args{PREREQ_PM} = { %{ $args{PREREQ_PM} || {} }, @Existing, @Missing } | |
804 | if $UnderCPAN or $TestOnly; | |
805 | ||
806 | if ( $args{EXE_FILES} and -e 'MANIFEST' ) { | |
807 | require ExtUtils::Manifest; | |
808 | my $manifest = ExtUtils::Manifest::maniread('MANIFEST'); | |
809 | ||
810 | $args{EXE_FILES} = | |
811 | [ grep { exists $manifest->{$_} } @{ $args{EXE_FILES} } ]; | |
812 | } | |
813 | ||
814 | $args{test}{TESTS} ||= 't/*.t'; | |
815 | $args{test}{TESTS} = join( ' ', | |
816 | grep { !exists( $DisabledTests{$_} ) } | |
817 | map { glob($_) } split( /\s+/, $args{test}{TESTS} ) ); | |
818 | ||
819 | my $missing = join( ',', @Missing ); | |
820 | my $config = | |
821 | join( ',', UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) | |
822 | if $Config; | |
823 | ||
824 | $PostambleActions = ( | |
825 | ($missing and not $UnderCPAN) | |
826 | ? "\$(PERL) $0 --config=$config --installdeps=$missing" | |
827 | : "\$(NOECHO) \$(NOOP)" | |
828 | ); | |
829 | ||
830 | my $deps_list = join( ',', @Missing, @Existing ); | |
831 | ||
832 | $PostambleActionsUpgradeDeps = | |
833 | "\$(PERL) $0 --config=$config --upgradedeps=$deps_list"; | |
834 | ||
835 | my $config_notest = | |
836 | join( ',', (UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config}), | |
837 | 'notest', 1 ) | |
838 | if $Config; | |
839 | ||
840 | $PostambleActionsNoTest = ( | |
841 | ($missing and not $UnderCPAN) | |
842 | ? "\$(PERL) $0 --config=$config_notest --installdeps=$missing" | |
843 | : "\$(NOECHO) \$(NOOP)" | |
844 | ); | |
845 | ||
846 | $PostambleActionsUpgradeDepsNoTest = | |
847 | "\$(PERL) $0 --config=$config_notest --upgradedeps=$deps_list"; | |
848 | ||
849 | $PostambleActionsListDeps = | |
850 | '@$(PERL) -le "print for @ARGV" ' | |
851 | . join(' ', map $Missing[$_], grep $_ % 2 == 0, 0..$#Missing); | |
852 | ||
853 | my @all = (@Missing, @Existing); | |
854 | ||
855 | $PostambleActionsListAllDeps = | |
856 | '@$(PERL) -le "print for @ARGV" ' | |
857 | . join(' ', map $all[$_], grep $_ % 2 == 0, 0..$#all); | |
858 | ||
859 | return %args; | |
860 | } | |
861 | ||
862 | # a wrapper to ExtUtils::MakeMaker::WriteMakefile | |
863 | sub Write { | |
864 | require Carp; | |
865 | Carp::croak "WriteMakefile: Need even number of args" if @_ % 2; | |
866 | ||
867 | if ($CheckOnly) { | |
868 | print << "."; | |
869 | *** Makefile not written in check-only mode. | |
870 | . | |
871 | return; | |
872 | } | |
873 | ||
874 | my %args = _make_args(@_); | |
875 | ||
876 | no strict 'refs'; | |
877 | ||
878 | $PostambleUsed = 0; | |
879 | local *MY::postamble = \&postamble unless defined &MY::postamble; | |
880 | ExtUtils::MakeMaker::WriteMakefile(%args); | |
881 | ||
882 | print << "." unless $PostambleUsed; | |
883 | *** WARNING: Makefile written with customized MY::postamble() without | |
884 | including contents from Module::AutoInstall::postamble() -- | |
885 | auto installation features disabled. Please contact the author. | |
886 | . | |
887 | ||
888 | return 1; | |
889 | } | |
890 | ||
891 | sub postamble { | |
892 | $PostambleUsed = 1; | |
893 | my $fragment; | |
894 | ||
895 | $fragment .= <<"AUTO_INSTALL" if !$InstallDepsTarget; | |
896 | ||
897 | config :: installdeps | |
898 | \t\$(NOECHO) \$(NOOP) | |
899 | AUTO_INSTALL | |
900 | ||
901 | $fragment .= <<"END_MAKE"; | |
902 | ||
903 | checkdeps :: | |
904 | \t\$(PERL) $0 --checkdeps | |
905 | ||
906 | installdeps :: | |
907 | \t$PostambleActions | |
908 | ||
909 | installdeps_notest :: | |
910 | \t$PostambleActionsNoTest | |
911 | ||
912 | upgradedeps :: | |
913 | \t$PostambleActionsUpgradeDeps | |
914 | ||
915 | upgradedeps_notest :: | |
916 | \t$PostambleActionsUpgradeDepsNoTest | |
917 | ||
918 | listdeps :: | |
919 | \t$PostambleActionsListDeps | |
920 | ||
921 | listalldeps :: | |
922 | \t$PostambleActionsListAllDeps | |
923 | ||
924 | END_MAKE | |
925 | ||
926 | return $fragment; | |
927 | } | |
928 | ||
929 | 1; | |
930 | ||
931 | __END__ | |
932 | ||
933 | #line 1197 |
0 | #line 1 | |
1 | package Module::Install::AutoInstall; | |
2 | ||
3 | use strict; | |
4 | use Module::Install::Base (); | |
5 | ||
6 | use vars qw{$VERSION @ISA $ISCORE}; | |
7 | BEGIN { | |
8 | $VERSION = '1.19'; | |
9 | @ISA = 'Module::Install::Base'; | |
10 | $ISCORE = 1; | |
11 | } | |
12 | ||
13 | sub AutoInstall { $_[0] } | |
14 | ||
15 | sub run { | |
16 | my $self = shift; | |
17 | $self->auto_install_now(@_); | |
18 | } | |
19 | ||
20 | sub write { | |
21 | my $self = shift; | |
22 | $self->auto_install(@_); | |
23 | } | |
24 | ||
25 | sub auto_install { | |
26 | my $self = shift; | |
27 | return if $self->{done}++; | |
28 | ||
29 | # Flatten array of arrays into a single array | |
30 | my @core = map @$_, map @$_, grep ref, | |
31 | $self->build_requires, $self->requires; | |
32 | ||
33 | my @config = @_; | |
34 | ||
35 | # We'll need Module::AutoInstall | |
36 | $self->include('Module::AutoInstall'); | |
37 | require Module::AutoInstall; | |
38 | ||
39 | my @features_require = Module::AutoInstall->import( | |
40 | (@config ? (-config => \@config) : ()), | |
41 | (@core ? (-core => \@core) : ()), | |
42 | $self->features, | |
43 | ); | |
44 | ||
45 | my %seen; | |
46 | my @requires = map @$_, map @$_, grep ref, $self->requires; | |
47 | while (my ($mod, $ver) = splice(@requires, 0, 2)) { | |
48 | $seen{$mod}{$ver}++; | |
49 | } | |
50 | my @build_requires = map @$_, map @$_, grep ref, $self->build_requires; | |
51 | while (my ($mod, $ver) = splice(@build_requires, 0, 2)) { | |
52 | $seen{$mod}{$ver}++; | |
53 | } | |
54 | my @configure_requires = map @$_, map @$_, grep ref, $self->configure_requires; | |
55 | while (my ($mod, $ver) = splice(@configure_requires, 0, 2)) { | |
56 | $seen{$mod}{$ver}++; | |
57 | } | |
58 | ||
59 | my @deduped; | |
60 | while (my ($mod, $ver) = splice(@features_require, 0, 2)) { | |
61 | push @deduped, $mod => $ver unless $seen{$mod}{$ver}++; | |
62 | } | |
63 | ||
64 | $self->requires(@deduped); | |
65 | ||
66 | $self->makemaker_args( Module::AutoInstall::_make_args() ); | |
67 | ||
68 | my $class = ref($self); | |
69 | $self->postamble( | |
70 | "# --- $class section:\n" . | |
71 | Module::AutoInstall::postamble() | |
72 | ); | |
73 | } | |
74 | ||
75 | sub installdeps_target { | |
76 | my ($self, @args) = @_; | |
77 | ||
78 | $self->include('Module::AutoInstall'); | |
79 | require Module::AutoInstall; | |
80 | ||
81 | Module::AutoInstall::_installdeps_target(1); | |
82 | ||
83 | $self->auto_install(@args); | |
84 | } | |
85 | ||
86 | sub auto_install_now { | |
87 | my $self = shift; | |
88 | $self->auto_install(@_); | |
89 | Module::AutoInstall::do_install(); | |
90 | } | |
91 | ||
92 | 1; |
0 | #line 1 | |
1 | package Module::Install::Can; | |
2 | ||
3 | use strict; | |
4 | use Config (); | |
5 | use ExtUtils::MakeMaker (); | |
6 | use Module::Install::Base (); | |
7 | ||
8 | use vars qw{$VERSION @ISA $ISCORE}; | |
9 | BEGIN { | |
10 | $VERSION = '1.19'; | |
11 | @ISA = 'Module::Install::Base'; | |
12 | $ISCORE = 1; | |
13 | } | |
14 | ||
15 | # check if we can load some module | |
16 | ### Upgrade this to not have to load the module if possible | |
17 | sub can_use { | |
18 | my ($self, $mod, $ver) = @_; | |
19 | $mod =~ s{::|\\}{/}g; | |
20 | $mod .= '.pm' unless $mod =~ /\.pm$/i; | |
21 | ||
22 | my $pkg = $mod; | |
23 | $pkg =~ s{/}{::}g; | |
24 | $pkg =~ s{\.pm$}{}i; | |
25 | ||
26 | local $@; | |
27 | eval { require $mod; $pkg->VERSION($ver || 0); 1 }; | |
28 | } | |
29 | ||
30 | # Check if we can run some command | |
31 | sub can_run { | |
32 | my ($self, $cmd) = @_; | |
33 | ||
34 | my $_cmd = $cmd; | |
35 | return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd)); | |
36 | ||
37 | for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { | |
38 | next if $dir eq ''; | |
39 | require File::Spec; | |
40 | my $abs = File::Spec->catfile($dir, $cmd); | |
41 | return $abs if (-x $abs or $abs = MM->maybe_command($abs)); | |
42 | } | |
43 | ||
44 | return; | |
45 | } | |
46 | ||
47 | # Can our C compiler environment build XS files | |
48 | sub can_xs { | |
49 | my $self = shift; | |
50 | ||
51 | # Ensure we have the CBuilder module | |
52 | $self->configure_requires( 'ExtUtils::CBuilder' => 0.27 ); | |
53 | ||
54 | # Do we have the configure_requires checker? | |
55 | local $@; | |
56 | eval "require ExtUtils::CBuilder;"; | |
57 | if ( $@ ) { | |
58 | # They don't obey configure_requires, so it is | |
59 | # someone old and delicate. Try to avoid hurting | |
60 | # them by falling back to an older simpler test. | |
61 | return $self->can_cc(); | |
62 | } | |
63 | ||
64 | # Do we have a working C compiler | |
65 | my $builder = ExtUtils::CBuilder->new( | |
66 | quiet => 1, | |
67 | ); | |
68 | unless ( $builder->have_compiler ) { | |
69 | # No working C compiler | |
70 | return 0; | |
71 | } | |
72 | ||
73 | # Write a C file representative of what XS becomes | |
74 | require File::Temp; | |
75 | my ( $FH, $tmpfile ) = File::Temp::tempfile( | |
76 | "compilexs-XXXXX", | |
77 | SUFFIX => '.c', | |
78 | ); | |
79 | binmode $FH; | |
80 | print $FH <<'END_C'; | |
81 | #include "EXTERN.h" | |
82 | #include "perl.h" | |
83 | #include "XSUB.h" | |
84 | ||
85 | int main(int argc, char **argv) { | |
86 | return 0; | |
87 | } | |
88 | ||
89 | int boot_sanexs() { | |
90 | return 1; | |
91 | } | |
92 | ||
93 | END_C | |
94 | close $FH; | |
95 | ||
96 | # Can the C compiler access the same headers XS does | |
97 | my @libs = (); | |
98 | my $object = undef; | |
99 | eval { | |
100 | local $^W = 0; | |
101 | $object = $builder->compile( | |
102 | source => $tmpfile, | |
103 | ); | |
104 | @libs = $builder->link( | |
105 | objects => $object, | |
106 | module_name => 'sanexs', | |
107 | ); | |
108 | }; | |
109 | my $result = $@ ? 0 : 1; | |
110 | ||
111 | # Clean up all the build files | |
112 | foreach ( $tmpfile, $object, @libs ) { | |
113 | next unless defined $_; | |
114 | 1 while unlink; | |
115 | } | |
116 | ||
117 | return $result; | |
118 | } | |
119 | ||
120 | # Can we locate a (the) C compiler | |
121 | sub can_cc { | |
122 | my $self = shift; | |
123 | ||
124 | if ($^O eq 'VMS') { | |
125 | require ExtUtils::CBuilder; | |
126 | my $builder = ExtUtils::CBuilder->new( | |
127 | quiet => 1, | |
128 | ); | |
129 | return $builder->have_compiler; | |
130 | } | |
131 | ||
132 | my @chunks = split(/ /, $Config::Config{cc}) or return; | |
133 | ||
134 | # $Config{cc} may contain args; try to find out the program part | |
135 | while (@chunks) { | |
136 | return $self->can_run("@chunks") || (pop(@chunks), next); | |
137 | } | |
138 | ||
139 | return; | |
140 | } | |
141 | ||
142 | # Fix Cygwin bug on maybe_command(); | |
143 | if ( $^O eq 'cygwin' ) { | |
144 | require ExtUtils::MM_Cygwin; | |
145 | require ExtUtils::MM_Win32; | |
146 | if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) { | |
147 | *ExtUtils::MM_Cygwin::maybe_command = sub { | |
148 | my ($self, $file) = @_; | |
149 | if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) { | |
150 | ExtUtils::MM_Win32->maybe_command($file); | |
151 | } else { | |
152 | ExtUtils::MM_Unix->maybe_command($file); | |
153 | } | |
154 | } | |
155 | } | |
156 | } | |
157 | ||
158 | 1; | |
159 | ||
160 | __END__ | |
161 | ||
162 | #line 245 |
0 | #line 1 | |
1 | package Module::Install::Fetch; | |
2 | ||
3 | use strict; | |
4 | use Module::Install::Base (); | |
5 | ||
6 | use vars qw{$VERSION @ISA $ISCORE}; | |
7 | BEGIN { | |
8 | $VERSION = '1.19'; | |
9 | @ISA = 'Module::Install::Base'; | |
10 | $ISCORE = 1; | |
11 | } | |
12 | ||
13 | sub get_file { | |
14 | my ($self, %args) = @_; | |
15 | my ($scheme, $host, $path, $file) = | |
16 | $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; | |
17 | ||
18 | if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) { | |
19 | $args{url} = $args{ftp_url} | |
20 | or (warn("LWP support unavailable!\n"), return); | |
21 | ($scheme, $host, $path, $file) = | |
22 | $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; | |
23 | } | |
24 | ||
25 | $|++; | |
26 | print "Fetching '$file' from $host... "; | |
27 | ||
28 | unless (eval { require Socket; Socket::inet_aton($host) }) { | |
29 | warn "'$host' resolve failed!\n"; | |
30 | return; | |
31 | } | |
32 | ||
33 | return unless $scheme eq 'ftp' or $scheme eq 'http'; | |
34 | ||
35 | require Cwd; | |
36 | my $dir = Cwd::getcwd(); | |
37 | chdir $args{local_dir} or return if exists $args{local_dir}; | |
38 | ||
39 | if (eval { require LWP::Simple; 1 }) { | |
40 | LWP::Simple::mirror($args{url}, $file); | |
41 | } | |
42 | elsif (eval { require Net::FTP; 1 }) { eval { | |
43 | # use Net::FTP to get past firewall | |
44 | my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600); | |
45 | $ftp->login("anonymous", 'anonymous@example.com'); | |
46 | $ftp->cwd($path); | |
47 | $ftp->binary; | |
48 | $ftp->get($file) or (warn("$!\n"), return); | |
49 | $ftp->quit; | |
50 | } } | |
51 | elsif (my $ftp = $self->can_run('ftp')) { eval { | |
52 | # no Net::FTP, fallback to ftp.exe | |
53 | require FileHandle; | |
54 | my $fh = FileHandle->new; | |
55 | ||
56 | local $SIG{CHLD} = 'IGNORE'; | |
57 | unless ($fh->open("|$ftp -n")) { | |
58 | warn "Couldn't open ftp: $!\n"; | |
59 | chdir $dir; return; | |
60 | } | |
61 | ||
62 | my @dialog = split(/\n/, <<"END_FTP"); | |
63 | open $host | |
64 | user anonymous anonymous\@example.com | |
65 | cd $path | |
66 | binary | |
67 | get $file $file | |
68 | quit | |
69 | END_FTP | |
70 | foreach (@dialog) { $fh->print("$_\n") } | |
71 | $fh->close; | |
72 | } } | |
73 | else { | |
74 | warn "No working 'ftp' program available!\n"; | |
75 | chdir $dir; return; | |
76 | } | |
77 | ||
78 | unless (-f $file) { | |
79 | warn "Fetching failed: $@\n"; | |
80 | chdir $dir; return; | |
81 | } | |
82 | ||
83 | return if exists $args{size} and -s $file != $args{size}; | |
84 | system($args{run}) if exists $args{run}; | |
85 | unlink($file) if $args{remove}; | |
86 | ||
87 | print(((!exists $args{check_for} or -e $args{check_for}) | |
88 | ? "done!" : "failed! ($!)"), "\n"); | |
89 | chdir $dir; return !$?; | |
90 | } | |
91 | ||
92 | 1; |
0 | #line 1 | |
1 | package Module::Install::Makefile; | |
2 | ||
3 | use strict 'vars'; | |
4 | use ExtUtils::MakeMaker (); | |
5 | use Module::Install::Base (); | |
6 | use Fcntl qw/:flock :seek/; | |
7 | ||
8 | use vars qw{$VERSION @ISA $ISCORE}; | |
9 | BEGIN { | |
10 | $VERSION = '1.19'; | |
11 | @ISA = 'Module::Install::Base'; | |
12 | $ISCORE = 1; | |
13 | } | |
14 | ||
15 | sub Makefile { $_[0] } | |
16 | ||
17 | my %seen = (); | |
18 | ||
19 | sub prompt { | |
20 | shift; | |
21 | ||
22 | # Infinite loop protection | |
23 | my @c = caller(); | |
24 | if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) { | |
25 | die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])"; | |
26 | } | |
27 | ||
28 | # In automated testing or non-interactive session, always use defaults | |
29 | if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) { | |
30 | local $ENV{PERL_MM_USE_DEFAULT} = 1; | |
31 | goto &ExtUtils::MakeMaker::prompt; | |
32 | } else { | |
33 | goto &ExtUtils::MakeMaker::prompt; | |
34 | } | |
35 | } | |
36 | ||
37 | # Store a cleaned up version of the MakeMaker version, | |
38 | # since we need to behave differently in a variety of | |
39 | # ways based on the MM version. | |
40 | my $makemaker = eval $ExtUtils::MakeMaker::VERSION; | |
41 | ||
42 | # If we are passed a param, do a "newer than" comparison. | |
43 | # Otherwise, just return the MakeMaker version. | |
44 | sub makemaker { | |
45 | ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0 | |
46 | } | |
47 | ||
48 | # Ripped from ExtUtils::MakeMaker 6.56, and slightly modified | |
49 | # as we only need to know here whether the attribute is an array | |
50 | # or a hash or something else (which may or may not be appendable). | |
51 | my %makemaker_argtype = ( | |
52 | C => 'ARRAY', | |
53 | CONFIG => 'ARRAY', | |
54 | # CONFIGURE => 'CODE', # ignore | |
55 | DIR => 'ARRAY', | |
56 | DL_FUNCS => 'HASH', | |
57 | DL_VARS => 'ARRAY', | |
58 | EXCLUDE_EXT => 'ARRAY', | |
59 | EXE_FILES => 'ARRAY', | |
60 | FUNCLIST => 'ARRAY', | |
61 | H => 'ARRAY', | |
62 | IMPORTS => 'HASH', | |
63 | INCLUDE_EXT => 'ARRAY', | |
64 | LIBS => 'ARRAY', # ignore '' | |
65 | MAN1PODS => 'HASH', | |
66 | MAN3PODS => 'HASH', | |
67 | META_ADD => 'HASH', | |
68 | META_MERGE => 'HASH', | |
69 | PL_FILES => 'HASH', | |
70 | PM => 'HASH', | |
71 | PMLIBDIRS => 'ARRAY', | |
72 | PMLIBPARENTDIRS => 'ARRAY', | |
73 | PREREQ_PM => 'HASH', | |
74 | CONFIGURE_REQUIRES => 'HASH', | |
75 | SKIP => 'ARRAY', | |
76 | TYPEMAPS => 'ARRAY', | |
77 | XS => 'HASH', | |
78 | # VERSION => ['version',''], # ignore | |
79 | # _KEEP_AFTER_FLUSH => '', | |
80 | ||
81 | clean => 'HASH', | |
82 | depend => 'HASH', | |
83 | dist => 'HASH', | |
84 | dynamic_lib=> 'HASH', | |
85 | linkext => 'HASH', | |
86 | macro => 'HASH', | |
87 | postamble => 'HASH', | |
88 | realclean => 'HASH', | |
89 | test => 'HASH', | |
90 | tool_autosplit => 'HASH', | |
91 | ||
92 | # special cases where you can use makemaker_append | |
93 | CCFLAGS => 'APPENDABLE', | |
94 | DEFINE => 'APPENDABLE', | |
95 | INC => 'APPENDABLE', | |
96 | LDDLFLAGS => 'APPENDABLE', | |
97 | LDFROM => 'APPENDABLE', | |
98 | ); | |
99 | ||
100 | sub makemaker_args { | |
101 | my ($self, %new_args) = @_; | |
102 | my $args = ( $self->{makemaker_args} ||= {} ); | |
103 | foreach my $key (keys %new_args) { | |
104 | if ($makemaker_argtype{$key}) { | |
105 | if ($makemaker_argtype{$key} eq 'ARRAY') { | |
106 | $args->{$key} = [] unless defined $args->{$key}; | |
107 | unless (ref $args->{$key} eq 'ARRAY') { | |
108 | $args->{$key} = [$args->{$key}] | |
109 | } | |
110 | push @{$args->{$key}}, | |
111 | ref $new_args{$key} eq 'ARRAY' | |
112 | ? @{$new_args{$key}} | |
113 | : $new_args{$key}; | |
114 | } | |
115 | elsif ($makemaker_argtype{$key} eq 'HASH') { | |
116 | $args->{$key} = {} unless defined $args->{$key}; | |
117 | foreach my $skey (keys %{ $new_args{$key} }) { | |
118 | $args->{$key}{$skey} = $new_args{$key}{$skey}; | |
119 | } | |
120 | } | |
121 | elsif ($makemaker_argtype{$key} eq 'APPENDABLE') { | |
122 | $self->makemaker_append($key => $new_args{$key}); | |
123 | } | |
124 | } | |
125 | else { | |
126 | if (defined $args->{$key}) { | |
127 | warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n}; | |
128 | } | |
129 | $args->{$key} = $new_args{$key}; | |
130 | } | |
131 | } | |
132 | return $args; | |
133 | } | |
134 | ||
135 | # For mm args that take multiple space-separated args, | |
136 | # append an argument to the current list. | |
137 | sub makemaker_append { | |
138 | my $self = shift; | |
139 | my $name = shift; | |
140 | my $args = $self->makemaker_args; | |
141 | $args->{$name} = defined $args->{$name} | |
142 | ? join( ' ', $args->{$name}, @_ ) | |
143 | : join( ' ', @_ ); | |
144 | } | |
145 | ||
146 | sub build_subdirs { | |
147 | my $self = shift; | |
148 | my $subdirs = $self->makemaker_args->{DIR} ||= []; | |
149 | for my $subdir (@_) { | |
150 | push @$subdirs, $subdir; | |
151 | } | |
152 | } | |
153 | ||
154 | sub clean_files { | |
155 | my $self = shift; | |
156 | my $clean = $self->makemaker_args->{clean} ||= {}; | |
157 | %$clean = ( | |
158 | %$clean, | |
159 | FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_), | |
160 | ); | |
161 | } | |
162 | ||
163 | sub realclean_files { | |
164 | my $self = shift; | |
165 | my $realclean = $self->makemaker_args->{realclean} ||= {}; | |
166 | %$realclean = ( | |
167 | %$realclean, | |
168 | FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_), | |
169 | ); | |
170 | } | |
171 | ||
172 | sub libs { | |
173 | my $self = shift; | |
174 | my $libs = ref $_[0] ? shift : [ shift ]; | |
175 | $self->makemaker_args( LIBS => $libs ); | |
176 | } | |
177 | ||
178 | sub inc { | |
179 | my $self = shift; | |
180 | $self->makemaker_args( INC => shift ); | |
181 | } | |
182 | ||
183 | sub _wanted_t { | |
184 | } | |
185 | ||
186 | sub tests_recursive { | |
187 | my $self = shift; | |
188 | my $dir = shift || 't'; | |
189 | unless ( -d $dir ) { | |
190 | die "tests_recursive dir '$dir' does not exist"; | |
191 | } | |
192 | my %tests = map { $_ => 1 } split / /, ($self->tests || ''); | |
193 | require File::Find; | |
194 | File::Find::find( | |
195 | sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 }, | |
196 | $dir | |
197 | ); | |
198 | $self->tests( join ' ', sort keys %tests ); | |
199 | } | |
200 | ||
201 | sub write { | |
202 | my $self = shift; | |
203 | die "&Makefile->write() takes no arguments\n" if @_; | |
204 | ||
205 | # Check the current Perl version | |
206 | my $perl_version = $self->perl_version; | |
207 | if ( $perl_version ) { | |
208 | eval "use $perl_version; 1" | |
209 | or die "ERROR: perl: Version $] is installed, " | |
210 | . "but we need version >= $perl_version"; | |
211 | } | |
212 | ||
213 | # Make sure we have a new enough MakeMaker | |
214 | require ExtUtils::MakeMaker; | |
215 | ||
216 | if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) { | |
217 | # This previous attempted to inherit the version of | |
218 | # ExtUtils::MakeMaker in use by the module author, but this | |
219 | # was found to be untenable as some authors build releases | |
220 | # using future dev versions of EU:MM that nobody else has. | |
221 | # Instead, #toolchain suggests we use 6.59 which is the most | |
222 | # stable version on CPAN at time of writing and is, to quote | |
223 | # ribasushi, "not terminally fucked, > and tested enough". | |
224 | # TODO: We will now need to maintain this over time to push | |
225 | # the version up as new versions are released. | |
226 | $self->build_requires( 'ExtUtils::MakeMaker' => 6.59 ); | |
227 | $self->configure_requires( 'ExtUtils::MakeMaker' => 6.59 ); | |
228 | } else { | |
229 | # Allow legacy-compatibility with 5.005 by depending on the | |
230 | # most recent EU:MM that supported 5.005. | |
231 | $self->build_requires( 'ExtUtils::MakeMaker' => 6.36 ); | |
232 | $self->configure_requires( 'ExtUtils::MakeMaker' => 6.36 ); | |
233 | } | |
234 | ||
235 | # Generate the MakeMaker params | |
236 | my $args = $self->makemaker_args; | |
237 | $args->{DISTNAME} = $self->name; | |
238 | $args->{NAME} = $self->module_name || $self->name; | |
239 | $args->{NAME} =~ s/-/::/g; | |
240 | $args->{VERSION} = $self->version or die <<'EOT'; | |
241 | ERROR: Can't determine distribution version. Please specify it | |
242 | explicitly via 'version' in Makefile.PL, or set a valid $VERSION | |
243 | in a module, and provide its file path via 'version_from' (or | |
244 | 'all_from' if you prefer) in Makefile.PL. | |
245 | EOT | |
246 | ||
247 | if ( $self->tests ) { | |
248 | my @tests = split ' ', $self->tests; | |
249 | my %seen; | |
250 | $args->{test} = { | |
251 | TESTS => (join ' ', grep {!$seen{$_}++} @tests), | |
252 | }; | |
253 | } elsif ( $Module::Install::ExtraTests::use_extratests ) { | |
254 | # Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness. | |
255 | # So, just ignore our xt tests here. | |
256 | } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) { | |
257 | $args->{test} = { | |
258 | TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ), | |
259 | }; | |
260 | } | |
261 | if ( $] >= 5.005 ) { | |
262 | $args->{ABSTRACT} = $self->abstract; | |
263 | $args->{AUTHOR} = join ', ', @{$self->author || []}; | |
264 | } | |
265 | if ( $self->makemaker(6.10) ) { | |
266 | $args->{NO_META} = 1; | |
267 | #$args->{NO_MYMETA} = 1; | |
268 | } | |
269 | if ( $self->makemaker(6.17) and $self->sign ) { | |
270 | $args->{SIGN} = 1; | |
271 | } | |
272 | unless ( $self->is_admin ) { | |
273 | delete $args->{SIGN}; | |
274 | } | |
275 | if ( $self->makemaker(6.31) and $self->license ) { | |
276 | $args->{LICENSE} = $self->license; | |
277 | } | |
278 | ||
279 | my $prereq = ($args->{PREREQ_PM} ||= {}); | |
280 | %$prereq = ( %$prereq, | |
281 | map { @$_ } # flatten [module => version] | |
282 | map { @$_ } | |
283 | grep $_, | |
284 | ($self->requires) | |
285 | ); | |
286 | ||
287 | # Remove any reference to perl, PREREQ_PM doesn't support it | |
288 | delete $args->{PREREQ_PM}->{perl}; | |
289 | ||
290 | # Merge both kinds of requires into BUILD_REQUIRES | |
291 | my $build_prereq = ($args->{BUILD_REQUIRES} ||= {}); | |
292 | %$build_prereq = ( %$build_prereq, | |
293 | map { @$_ } # flatten [module => version] | |
294 | map { @$_ } | |
295 | grep $_, | |
296 | ($self->configure_requires, $self->build_requires) | |
297 | ); | |
298 | ||
299 | # Remove any reference to perl, BUILD_REQUIRES doesn't support it | |
300 | delete $args->{BUILD_REQUIRES}->{perl}; | |
301 | ||
302 | # Delete bundled dists from prereq_pm, add it to Makefile DIR | |
303 | my $subdirs = ($args->{DIR} || []); | |
304 | if ($self->bundles) { | |
305 | my %processed; | |
306 | foreach my $bundle (@{ $self->bundles }) { | |
307 | my ($mod_name, $dist_dir) = @$bundle; | |
308 | delete $prereq->{$mod_name}; | |
309 | $dist_dir = File::Basename::basename($dist_dir); # dir for building this module | |
310 | if (not exists $processed{$dist_dir}) { | |
311 | if (-d $dist_dir) { | |
312 | # List as sub-directory to be processed by make | |
313 | push @$subdirs, $dist_dir; | |
314 | } | |
315 | # Else do nothing: the module is already present on the system | |
316 | $processed{$dist_dir} = undef; | |
317 | } | |
318 | } | |
319 | } | |
320 | ||
321 | unless ( $self->makemaker('6.55_03') ) { | |
322 | %$prereq = (%$prereq,%$build_prereq); | |
323 | delete $args->{BUILD_REQUIRES}; | |
324 | } | |
325 | ||
326 | if ( my $perl_version = $self->perl_version ) { | |
327 | eval "use $perl_version; 1" | |
328 | or die "ERROR: perl: Version $] is installed, " | |
329 | . "but we need version >= $perl_version"; | |
330 | ||
331 | if ( $self->makemaker(6.48) ) { | |
332 | $args->{MIN_PERL_VERSION} = $perl_version; | |
333 | } | |
334 | } | |
335 | ||
336 | if ($self->installdirs) { | |
337 | warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS}; | |
338 | $args->{INSTALLDIRS} = $self->installdirs; | |
339 | } | |
340 | ||
341 | my %args = map { | |
342 | ( $_ => $args->{$_} ) } grep {defined($args->{$_} ) | |
343 | } keys %$args; | |
344 | ||
345 | my $user_preop = delete $args{dist}->{PREOP}; | |
346 | if ( my $preop = $self->admin->preop($user_preop) ) { | |
347 | foreach my $key ( keys %$preop ) { | |
348 | $args{dist}->{$key} = $preop->{$key}; | |
349 | } | |
350 | } | |
351 | ||
352 | my $mm = ExtUtils::MakeMaker::WriteMakefile(%args); | |
353 | $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile'); | |
354 | } | |
355 | ||
356 | sub fix_up_makefile { | |
357 | my $self = shift; | |
358 | my $makefile_name = shift; | |
359 | my $top_class = ref($self->_top) || ''; | |
360 | my $top_version = $self->_top->VERSION || ''; | |
361 | ||
362 | my $preamble = $self->preamble | |
363 | ? "# Preamble by $top_class $top_version\n" | |
364 | . $self->preamble | |
365 | : ''; | |
366 | my $postamble = "# Postamble by $top_class $top_version\n" | |
367 | . ($self->postamble || ''); | |
368 | ||
369 | local *MAKEFILE; | |
370 | open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!"; | |
371 | eval { flock MAKEFILE, LOCK_EX }; | |
372 | my $makefile = do { local $/; <MAKEFILE> }; | |
373 | ||
374 | $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /; | |
375 | $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g; | |
376 | $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g; | |
377 | $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m; | |
378 | $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m; | |
379 | ||
380 | # Module::Install will never be used to build the Core Perl | |
381 | # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks | |
382 | # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist | |
383 | $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m; | |
384 | #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m; | |
385 | ||
386 | # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well. | |
387 | $makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g; | |
388 | ||
389 | # XXX - This is currently unused; not sure if it breaks other MM-users | |
390 | # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg; | |
391 | ||
392 | seek MAKEFILE, 0, SEEK_SET; | |
393 | truncate MAKEFILE, 0; | |
394 | print MAKEFILE "$preamble$makefile$postamble" or die $!; | |
395 | close MAKEFILE or die $!; | |
396 | ||
397 | 1; | |
398 | } | |
399 | ||
400 | sub preamble { | |
401 | my ($self, $text) = @_; | |
402 | $self->{preamble} = $text . $self->{preamble} if defined $text; | |
403 | $self->{preamble}; | |
404 | } | |
405 | ||
406 | sub postamble { | |
407 | my ($self, $text) = @_; | |
408 | $self->{postamble} ||= $self->admin->postamble; | |
409 | $self->{postamble} .= $text if defined $text; | |
410 | $self->{postamble} | |
411 | } | |
412 | ||
413 | 1; | |
414 | ||
415 | __END__ | |
416 | ||
417 | #line 544 |
0 | #line 1 | |
1 | package Module::Install::Metadata; | |
2 | ||
3 | use strict 'vars'; | |
4 | use Module::Install::Base (); | |
5 | ||
6 | use vars qw{$VERSION @ISA $ISCORE}; | |
7 | BEGIN { | |
8 | $VERSION = '1.19'; | |
9 | @ISA = 'Module::Install::Base'; | |
10 | $ISCORE = 1; | |
11 | } | |
12 | ||
13 | my @boolean_keys = qw{ | |
14 | sign | |
15 | }; | |
16 | ||
17 | my @scalar_keys = qw{ | |
18 | name | |
19 | module_name | |
20 | abstract | |
21 | version | |
22 | distribution_type | |
23 | tests | |
24 | installdirs | |
25 | }; | |
26 | ||
27 | my @tuple_keys = qw{ | |
28 | configure_requires | |
29 | build_requires | |
30 | requires | |
31 | recommends | |
32 | bundles | |
33 | resources | |
34 | }; | |
35 | ||
36 | my @resource_keys = qw{ | |
37 | homepage | |
38 | bugtracker | |
39 | repository | |
40 | }; | |
41 | ||
42 | my @array_keys = qw{ | |
43 | keywords | |
44 | author | |
45 | }; | |
46 | ||
47 | *authors = \&author; | |
48 | ||
49 | sub Meta { shift } | |
50 | sub Meta_BooleanKeys { @boolean_keys } | |
51 | sub Meta_ScalarKeys { @scalar_keys } | |
52 | sub Meta_TupleKeys { @tuple_keys } | |
53 | sub Meta_ResourceKeys { @resource_keys } | |
54 | sub Meta_ArrayKeys { @array_keys } | |
55 | ||
56 | foreach my $key ( @boolean_keys ) { | |
57 | *$key = sub { | |
58 | my $self = shift; | |
59 | if ( defined wantarray and not @_ ) { | |
60 | return $self->{values}->{$key}; | |
61 | } | |
62 | $self->{values}->{$key} = ( @_ ? $_[0] : 1 ); | |
63 | return $self; | |
64 | }; | |
65 | } | |
66 | ||
67 | foreach my $key ( @scalar_keys ) { | |
68 | *$key = sub { | |
69 | my $self = shift; | |
70 | return $self->{values}->{$key} if defined wantarray and !@_; | |
71 | $self->{values}->{$key} = shift; | |
72 | return $self; | |
73 | }; | |
74 | } | |
75 | ||
76 | foreach my $key ( @array_keys ) { | |
77 | *$key = sub { | |
78 | my $self = shift; | |
79 | return $self->{values}->{$key} if defined wantarray and !@_; | |
80 | $self->{values}->{$key} ||= []; | |
81 | push @{$self->{values}->{$key}}, @_; | |
82 | return $self; | |
83 | }; | |
84 | } | |
85 | ||
86 | foreach my $key ( @resource_keys ) { | |
87 | *$key = sub { | |
88 | my $self = shift; | |
89 | unless ( @_ ) { | |
90 | return () unless $self->{values}->{resources}; | |
91 | return map { $_->[1] } | |
92 | grep { $_->[0] eq $key } | |
93 | @{ $self->{values}->{resources} }; | |
94 | } | |
95 | return $self->{values}->{resources}->{$key} unless @_; | |
96 | my $uri = shift or die( | |
97 | "Did not provide a value to $key()" | |
98 | ); | |
99 | $self->resources( $key => $uri ); | |
100 | return 1; | |
101 | }; | |
102 | } | |
103 | ||
104 | foreach my $key ( grep { $_ ne "resources" } @tuple_keys) { | |
105 | *$key = sub { | |
106 | my $self = shift; | |
107 | return $self->{values}->{$key} unless @_; | |
108 | my @added; | |
109 | while ( @_ ) { | |
110 | my $module = shift or last; | |
111 | my $version = shift || 0; | |
112 | push @added, [ $module, $version ]; | |
113 | } | |
114 | push @{ $self->{values}->{$key} }, @added; | |
115 | return map {@$_} @added; | |
116 | }; | |
117 | } | |
118 | ||
119 | # Resource handling | |
120 | my %lc_resource = map { $_ => 1 } qw{ | |
121 | homepage | |
122 | license | |
123 | bugtracker | |
124 | repository | |
125 | }; | |
126 | ||
127 | sub resources { | |
128 | my $self = shift; | |
129 | while ( @_ ) { | |
130 | my $name = shift or last; | |
131 | my $value = shift or next; | |
132 | if ( $name eq lc $name and ! $lc_resource{$name} ) { | |
133 | die("Unsupported reserved lowercase resource '$name'"); | |
134 | } | |
135 | $self->{values}->{resources} ||= []; | |
136 | push @{ $self->{values}->{resources} }, [ $name, $value ]; | |
137 | } | |
138 | $self->{values}->{resources}; | |
139 | } | |
140 | ||
141 | # Aliases for build_requires that will have alternative | |
142 | # meanings in some future version of META.yml. | |
143 | sub test_requires { shift->build_requires(@_) } | |
144 | sub install_requires { shift->build_requires(@_) } | |
145 | ||
146 | # Aliases for installdirs options | |
147 | sub install_as_core { $_[0]->installdirs('perl') } | |
148 | sub install_as_cpan { $_[0]->installdirs('site') } | |
149 | sub install_as_site { $_[0]->installdirs('site') } | |
150 | sub install_as_vendor { $_[0]->installdirs('vendor') } | |
151 | ||
152 | sub dynamic_config { | |
153 | my $self = shift; | |
154 | my $value = @_ ? shift : 1; | |
155 | if ( $self->{values}->{dynamic_config} ) { | |
156 | # Once dynamic we never change to static, for safety | |
157 | return 0; | |
158 | } | |
159 | $self->{values}->{dynamic_config} = $value ? 1 : 0; | |
160 | return 1; | |
161 | } | |
162 | ||
163 | # Convenience command | |
164 | sub static_config { | |
165 | shift->dynamic_config(0); | |
166 | } | |
167 | ||
168 | sub perl_version { | |
169 | my $self = shift; | |
170 | return $self->{values}->{perl_version} unless @_; | |
171 | my $version = shift or die( | |
172 | "Did not provide a value to perl_version()" | |
173 | ); | |
174 | ||
175 | # Normalize the version | |
176 | $version = $self->_perl_version($version); | |
177 | ||
178 | # We don't support the really old versions | |
179 | unless ( $version >= 5.005 ) { | |
180 | die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n"; | |
181 | } | |
182 | ||
183 | $self->{values}->{perl_version} = $version; | |
184 | } | |
185 | ||
186 | sub all_from { | |
187 | my ( $self, $file ) = @_; | |
188 | ||
189 | unless ( defined($file) ) { | |
190 | my $name = $self->name or die( | |
191 | "all_from called with no args without setting name() first" | |
192 | ); | |
193 | $file = join('/', 'lib', split(/-/, $name)) . '.pm'; | |
194 | $file =~ s{.*/}{} unless -e $file; | |
195 | unless ( -e $file ) { | |
196 | die("all_from cannot find $file from $name"); | |
197 | } | |
198 | } | |
199 | unless ( -f $file ) { | |
200 | die("The path '$file' does not exist, or is not a file"); | |
201 | } | |
202 | ||
203 | $self->{values}{all_from} = $file; | |
204 | ||
205 | # Some methods pull from POD instead of code. | |
206 | # If there is a matching .pod, use that instead | |
207 | my $pod = $file; | |
208 | $pod =~ s/\.pm$/.pod/i; | |
209 | $pod = $file unless -e $pod; | |
210 | ||
211 | # Pull the different values | |
212 | $self->name_from($file) unless $self->name; | |
213 | $self->version_from($file) unless $self->version; | |
214 | $self->perl_version_from($file) unless $self->perl_version; | |
215 | $self->author_from($pod) unless @{$self->author || []}; | |
216 | $self->license_from($pod) unless $self->license; | |
217 | $self->abstract_from($pod) unless $self->abstract; | |
218 | ||
219 | return 1; | |
220 | } | |
221 | ||
222 | sub provides { | |
223 | my $self = shift; | |
224 | my $provides = ( $self->{values}->{provides} ||= {} ); | |
225 | %$provides = (%$provides, @_) if @_; | |
226 | return $provides; | |
227 | } | |
228 | ||
229 | sub auto_provides { | |
230 | my $self = shift; | |
231 | return $self unless $self->is_admin; | |
232 | unless (-e 'MANIFEST') { | |
233 | warn "Cannot deduce auto_provides without a MANIFEST, skipping\n"; | |
234 | return $self; | |
235 | } | |
236 | # Avoid spurious warnings as we are not checking manifest here. | |
237 | local $SIG{__WARN__} = sub {1}; | |
238 | require ExtUtils::Manifest; | |
239 | local *ExtUtils::Manifest::manicheck = sub { return }; | |
240 | ||
241 | require Module::Build; | |
242 | my $build = Module::Build->new( | |
243 | dist_name => $self->name, | |
244 | dist_version => $self->version, | |
245 | license => $self->license, | |
246 | ); | |
247 | $self->provides( %{ $build->find_dist_packages || {} } ); | |
248 | } | |
249 | ||
250 | sub feature { | |
251 | my $self = shift; | |
252 | my $name = shift; | |
253 | my $features = ( $self->{values}->{features} ||= [] ); | |
254 | my $mods; | |
255 | ||
256 | if ( @_ == 1 and ref( $_[0] ) ) { | |
257 | # The user used ->feature like ->features by passing in the second | |
258 | # argument as a reference. Accomodate for that. | |
259 | $mods = $_[0]; | |
260 | } else { | |
261 | $mods = \@_; | |
262 | } | |
263 | ||
264 | my $count = 0; | |
265 | push @$features, ( | |
266 | $name => [ | |
267 | map { | |
268 | ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_ | |
269 | } @$mods | |
270 | ] | |
271 | ); | |
272 | ||
273 | return @$features; | |
274 | } | |
275 | ||
276 | sub features { | |
277 | my $self = shift; | |
278 | while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) { | |
279 | $self->feature( $name, @$mods ); | |
280 | } | |
281 | return $self->{values}->{features} | |
282 | ? @{ $self->{values}->{features} } | |
283 | : (); | |
284 | } | |
285 | ||
286 | sub no_index { | |
287 | my $self = shift; | |
288 | my $type = shift; | |
289 | push @{ $self->{values}->{no_index}->{$type} }, @_ if $type; | |
290 | return $self->{values}->{no_index}; | |
291 | } | |
292 | ||
293 | sub read { | |
294 | my $self = shift; | |
295 | $self->include_deps( 'YAML::Tiny', 0 ); | |
296 | ||
297 | require YAML::Tiny; | |
298 | my $data = YAML::Tiny::LoadFile('META.yml'); | |
299 | ||
300 | # Call methods explicitly in case user has already set some values. | |
301 | while ( my ( $key, $value ) = each %$data ) { | |
302 | next unless $self->can($key); | |
303 | if ( ref $value eq 'HASH' ) { | |
304 | while ( my ( $module, $version ) = each %$value ) { | |
305 | $self->can($key)->($self, $module => $version ); | |
306 | } | |
307 | } else { | |
308 | $self->can($key)->($self, $value); | |
309 | } | |
310 | } | |
311 | return $self; | |
312 | } | |
313 | ||
314 | sub write { | |
315 | my $self = shift; | |
316 | return $self unless $self->is_admin; | |
317 | $self->admin->write_meta; | |
318 | return $self; | |
319 | } | |
320 | ||
321 | sub version_from { | |
322 | require ExtUtils::MM_Unix; | |
323 | my ( $self, $file ) = @_; | |
324 | $self->version( ExtUtils::MM_Unix->parse_version($file) ); | |
325 | ||
326 | # for version integrity check | |
327 | $self->makemaker_args( VERSION_FROM => $file ); | |
328 | } | |
329 | ||
330 | sub abstract_from { | |
331 | require ExtUtils::MM_Unix; | |
332 | my ( $self, $file ) = @_; | |
333 | $self->abstract( | |
334 | bless( | |
335 | { DISTNAME => $self->name }, | |
336 | 'ExtUtils::MM_Unix' | |
337 | )->parse_abstract($file) | |
338 | ); | |
339 | } | |
340 | ||
341 | # Add both distribution and module name | |
342 | sub name_from { | |
343 | my ($self, $file) = @_; | |
344 | if ( | |
345 | Module::Install::_read($file) =~ m/ | |
346 | ^ \s* | |
347 | package \s* | |
348 | ([\w:]+) | |
349 | [\s|;]* | |
350 | /ixms | |
351 | ) { | |
352 | my ($name, $module_name) = ($1, $1); | |
353 | $name =~ s{::}{-}g; | |
354 | $self->name($name); | |
355 | unless ( $self->module_name ) { | |
356 | $self->module_name($module_name); | |
357 | } | |
358 | } else { | |
359 | die("Cannot determine name from $file\n"); | |
360 | } | |
361 | } | |
362 | ||
363 | sub _extract_perl_version { | |
364 | if ( | |
365 | $_[0] =~ m/ | |
366 | ^\s* | |
367 | (?:use|require) \s* | |
368 | v? | |
369 | ([\d_\.]+) | |
370 | \s* ; | |
371 | /ixms | |
372 | ) { | |
373 | my $perl_version = $1; | |
374 | $perl_version =~ s{_}{}g; | |
375 | return $perl_version; | |
376 | } else { | |
377 | return; | |
378 | } | |
379 | } | |
380 | ||
381 | sub perl_version_from { | |
382 | my $self = shift; | |
383 | my $perl_version=_extract_perl_version(Module::Install::_read($_[0])); | |
384 | if ($perl_version) { | |
385 | $self->perl_version($perl_version); | |
386 | } else { | |
387 | warn "Cannot determine perl version info from $_[0]\n"; | |
388 | return; | |
389 | } | |
390 | } | |
391 | ||
392 | sub author_from { | |
393 | my $self = shift; | |
394 | my $content = Module::Install::_read($_[0]); | |
395 | if ($content =~ m/ | |
396 | =head \d \s+ (?:authors?)\b \s* | |
397 | ([^\n]*) | |
398 | | | |
399 | =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s* | |
400 | .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s* | |
401 | ([^\n]*) | |
402 | /ixms) { | |
403 | my $author = $1 || $2; | |
404 | ||
405 | # XXX: ugly but should work anyway... | |
406 | if (eval "require Pod::Escapes; 1") { | |
407 | # Pod::Escapes has a mapping table. | |
408 | # It's in core of perl >= 5.9.3, and should be installed | |
409 | # as one of the Pod::Simple's prereqs, which is a prereq | |
410 | # of Pod::Text 3.x (see also below). | |
411 | $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } | |
412 | { | |
413 | defined $2 | |
414 | ? chr($2) | |
415 | : defined $Pod::Escapes::Name2character_number{$1} | |
416 | ? chr($Pod::Escapes::Name2character_number{$1}) | |
417 | : do { | |
418 | warn "Unknown escape: E<$1>"; | |
419 | "E<$1>"; | |
420 | }; | |
421 | }gex; | |
422 | } | |
423 | elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) { | |
424 | # Pod::Text < 3.0 has yet another mapping table, | |
425 | # though the table name of 2.x and 1.x are different. | |
426 | # (1.x is in core of Perl < 5.6, 2.x is in core of | |
427 | # Perl < 5.9.3) | |
428 | my $mapping = ($Pod::Text::VERSION < 2) | |
429 | ? \%Pod::Text::HTML_Escapes | |
430 | : \%Pod::Text::ESCAPES; | |
431 | $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } | |
432 | { | |
433 | defined $2 | |
434 | ? chr($2) | |
435 | : defined $mapping->{$1} | |
436 | ? $mapping->{$1} | |
437 | : do { | |
438 | warn "Unknown escape: E<$1>"; | |
439 | "E<$1>"; | |
440 | }; | |
441 | }gex; | |
442 | } | |
443 | else { | |
444 | $author =~ s{E<lt>}{<}g; | |
445 | $author =~ s{E<gt>}{>}g; | |
446 | } | |
447 | $self->author($author); | |
448 | } else { | |
449 | warn "Cannot determine author info from $_[0]\n"; | |
450 | } | |
451 | } | |
452 | ||
453 | #Stolen from M::B | |
454 | my %license_urls = ( | |
455 | perl => 'http://dev.perl.org/licenses/', | |
456 | apache => 'http://apache.org/licenses/LICENSE-2.0', | |
457 | apache_1_1 => 'http://apache.org/licenses/LICENSE-1.1', | |
458 | artistic => 'http://opensource.org/licenses/artistic-license.php', | |
459 | artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php', | |
460 | lgpl => 'http://opensource.org/licenses/lgpl-license.php', | |
461 | lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php', | |
462 | lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html', | |
463 | bsd => 'http://opensource.org/licenses/bsd-license.php', | |
464 | gpl => 'http://opensource.org/licenses/gpl-license.php', | |
465 | gpl2 => 'http://opensource.org/licenses/gpl-2.0.php', | |
466 | gpl3 => 'http://opensource.org/licenses/gpl-3.0.html', | |
467 | mit => 'http://opensource.org/licenses/mit-license.php', | |
468 | mozilla => 'http://opensource.org/licenses/mozilla1.1.php', | |
469 | open_source => undef, | |
470 | unrestricted => undef, | |
471 | restrictive => undef, | |
472 | unknown => undef, | |
473 | ); | |
474 | ||
475 | sub license { | |
476 | my $self = shift; | |
477 | return $self->{values}->{license} unless @_; | |
478 | my $license = shift or die( | |
479 | 'Did not provide a value to license()' | |
480 | ); | |
481 | $license = __extract_license($license) || lc $license; | |
482 | $self->{values}->{license} = $license; | |
483 | ||
484 | # Automatically fill in license URLs | |
485 | if ( $license_urls{$license} ) { | |
486 | $self->resources( license => $license_urls{$license} ); | |
487 | } | |
488 | ||
489 | return 1; | |
490 | } | |
491 | ||
492 | sub _extract_license { | |
493 | my $pod = shift; | |
494 | my $matched; | |
495 | return __extract_license( | |
496 | ($matched) = $pod =~ m/ | |
497 | (=head \d \s+ L(?i:ICEN[CS]E|ICENSING)\b.*?) | |
498 | (=head \d.*|=cut.*|)\z | |
499 | /xms | |
500 | ) || __extract_license( | |
501 | ($matched) = $pod =~ m/ | |
502 | (=head \d \s+ (?:C(?i:OPYRIGHTS?)|L(?i:EGAL))\b.*?) | |
503 | (=head \d.*|=cut.*|)\z | |
504 | /xms | |
505 | ); | |
506 | } | |
507 | ||
508 | sub __extract_license { | |
509 | my $license_text = shift or return; | |
510 | my @phrases = ( | |
511 | '(?:under )?the same (?:terms|license) as (?:perl|the perl (?:\d )?programming language)' => 'perl', 1, | |
512 | '(?:under )?the terms of (?:perl|the perl programming language) itself' => 'perl', 1, | |
513 | 'Artistic and GPL' => 'perl', 1, | |
514 | 'GNU general public license' => 'gpl', 1, | |
515 | 'GNU public license' => 'gpl', 1, | |
516 | 'GNU lesser general public license' => 'lgpl', 1, | |
517 | 'GNU lesser public license' => 'lgpl', 1, | |
518 | 'GNU library general public license' => 'lgpl', 1, | |
519 | 'GNU library public license' => 'lgpl', 1, | |
520 | 'GNU Free Documentation license' => 'unrestricted', 1, | |
521 | 'GNU Affero General Public License' => 'open_source', 1, | |
522 | '(?:Free)?BSD license' => 'bsd', 1, | |
523 | 'Artistic license 2\.0' => 'artistic_2', 1, | |
524 | 'Artistic license' => 'artistic', 1, | |
525 | 'Apache (?:Software )?license' => 'apache', 1, | |
526 | 'GPL' => 'gpl', 1, | |
527 | 'LGPL' => 'lgpl', 1, | |
528 | 'BSD' => 'bsd', 1, | |
529 | 'Artistic' => 'artistic', 1, | |
530 | 'MIT' => 'mit', 1, | |
531 | 'Mozilla Public License' => 'mozilla', 1, | |
532 | 'Q Public License' => 'open_source', 1, | |
533 | 'OpenSSL License' => 'unrestricted', 1, | |
534 | 'SSLeay License' => 'unrestricted', 1, | |
535 | 'zlib License' => 'open_source', 1, | |
536 | 'proprietary' => 'proprietary', 0, | |
537 | ); | |
538 | while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) { | |
539 | $pattern =~ s#\s+#\\s+#gs; | |
540 | if ( $license_text =~ /\b$pattern\b/i ) { | |
541 | return $license; | |
542 | } | |
543 | } | |
544 | return ''; | |
545 | } | |
546 | ||
547 | sub license_from { | |
548 | my $self = shift; | |
549 | if (my $license=_extract_license(Module::Install::_read($_[0]))) { | |
550 | $self->license($license); | |
551 | } else { | |
552 | warn "Cannot determine license info from $_[0]\n"; | |
553 | return 'unknown'; | |
554 | } | |
555 | } | |
556 | ||
557 | sub _extract_bugtracker { | |
558 | my @links = $_[0] =~ m#L<( | |
559 | https?\Q://rt.cpan.org/\E[^>]+| | |
560 | https?\Q://github.com/\E[\w_]+/[\w_]+/issues| | |
561 | https?\Q://code.google.com/p/\E[\w_\-]+/issues/list | |
562 | )>#gx; | |
563 | my %links; | |
564 | @links{@links}=(); | |
565 | @links=keys %links; | |
566 | return @links; | |
567 | } | |
568 | ||
569 | sub bugtracker_from { | |
570 | my $self = shift; | |
571 | my $content = Module::Install::_read($_[0]); | |
572 | my @links = _extract_bugtracker($content); | |
573 | unless ( @links ) { | |
574 | warn "Cannot determine bugtracker info from $_[0]\n"; | |
575 | return 0; | |
576 | } | |
577 | if ( @links > 1 ) { | |
578 | warn "Found more than one bugtracker link in $_[0]\n"; | |
579 | return 0; | |
580 | } | |
581 | ||
582 | # Set the bugtracker | |
583 | bugtracker( $links[0] ); | |
584 | return 1; | |
585 | } | |
586 | ||
587 | sub requires_from { | |
588 | my $self = shift; | |
589 | my $content = Module::Install::_readperl($_[0]); | |
590 | my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+(v?[\d\.]+)/mg; | |
591 | while ( @requires ) { | |
592 | my $module = shift @requires; | |
593 | my $version = shift @requires; | |
594 | $self->requires( $module => $version ); | |
595 | } | |
596 | } | |
597 | ||
598 | sub test_requires_from { | |
599 | my $self = shift; | |
600 | my $content = Module::Install::_readperl($_[0]); | |
601 | my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; | |
602 | while ( @requires ) { | |
603 | my $module = shift @requires; | |
604 | my $version = shift @requires; | |
605 | $self->test_requires( $module => $version ); | |
606 | } | |
607 | } | |
608 | ||
609 | # Convert triple-part versions (eg, 5.6.1 or 5.8.9) to | |
610 | # numbers (eg, 5.006001 or 5.008009). | |
611 | # Also, convert double-part versions (eg, 5.8) | |
612 | sub _perl_version { | |
613 | my $v = $_[-1]; | |
614 | $v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e; | |
615 | $v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e; | |
616 | $v =~ s/(\.\d\d\d)000$/$1/; | |
617 | $v =~ s/_.+$//; | |
618 | if ( ref($v) ) { | |
619 | # Numify | |
620 | $v = $v + 0; | |
621 | } | |
622 | return $v; | |
623 | } | |
624 | ||
625 | sub add_metadata { | |
626 | my $self = shift; | |
627 | my %hash = @_; | |
628 | for my $key (keys %hash) { | |
629 | warn "add_metadata: $key is not prefixed with 'x_'.\n" . | |
630 | "Use appopriate function to add non-private metadata.\n" unless $key =~ /^x_/; | |
631 | $self->{values}->{$key} = $hash{$key}; | |
632 | } | |
633 | } | |
634 | ||
635 | ||
636 | ###################################################################### | |
637 | # MYMETA Support | |
638 | ||
639 | sub WriteMyMeta { | |
640 | die "WriteMyMeta has been deprecated"; | |
641 | } | |
642 | ||
643 | sub write_mymeta_yaml { | |
644 | my $self = shift; | |
645 | ||
646 | # We need YAML::Tiny to write the MYMETA.yml file | |
647 | unless ( eval { require YAML::Tiny; 1; } ) { | |
648 | return 1; | |
649 | } | |
650 | ||
651 | # Generate the data | |
652 | my $meta = $self->_write_mymeta_data or return 1; | |
653 | ||
654 | # Save as the MYMETA.yml file | |
655 | print "Writing MYMETA.yml\n"; | |
656 | YAML::Tiny::DumpFile('MYMETA.yml', $meta); | |
657 | } | |
658 | ||
659 | sub write_mymeta_json { | |
660 | my $self = shift; | |
661 | ||
662 | # We need JSON to write the MYMETA.json file | |
663 | unless ( eval { require JSON; 1; } ) { | |
664 | return 1; | |
665 | } | |
666 | ||
667 | # Generate the data | |
668 | my $meta = $self->_write_mymeta_data or return 1; | |
669 | ||
670 | # Save as the MYMETA.yml file | |
671 | print "Writing MYMETA.json\n"; | |
672 | Module::Install::_write( | |
673 | 'MYMETA.json', | |
674 | JSON->new->pretty(1)->canonical->encode($meta), | |
675 | ); | |
676 | } | |
677 | ||
678 | sub _write_mymeta_data { | |
679 | my $self = shift; | |
680 | ||
681 | # If there's no existing META.yml there is nothing we can do | |
682 | return undef unless -f 'META.yml'; | |
683 | ||
684 | # We need Parse::CPAN::Meta to load the file | |
685 | unless ( eval { require Parse::CPAN::Meta; 1; } ) { | |
686 | return undef; | |
687 | } | |
688 | ||
689 | # Merge the perl version into the dependencies | |
690 | my $val = $self->Meta->{values}; | |
691 | my $perl = delete $val->{perl_version}; | |
692 | if ( $perl ) { | |
693 | $val->{requires} ||= []; | |
694 | my $requires = $val->{requires}; | |
695 | ||
696 | # Canonize to three-dot version after Perl 5.6 | |
697 | if ( $perl >= 5.006 ) { | |
698 | $perl =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e | |
699 | } | |
700 | unshift @$requires, [ perl => $perl ]; | |
701 | } | |
702 | ||
703 | # Load the advisory META.yml file | |
704 | my @yaml = Parse::CPAN::Meta::LoadFile('META.yml'); | |
705 | my $meta = $yaml[0]; | |
706 | ||
707 | # Overwrite the non-configure dependency hashes | |
708 | delete $meta->{requires}; | |
709 | delete $meta->{build_requires}; | |
710 | delete $meta->{recommends}; | |
711 | if ( exists $val->{requires} ) { | |
712 | $meta->{requires} = { map { @$_ } @{ $val->{requires} } }; | |
713 | } | |
714 | if ( exists $val->{build_requires} ) { | |
715 | $meta->{build_requires} = { map { @$_ } @{ $val->{build_requires} } }; | |
716 | } | |
717 | ||
718 | return $meta; | |
719 | } | |
720 | ||
721 | 1; |
0 | #line 1 | |
1 | package Module::Install::TrustMetaYml; | |
2 | ||
3 | use 5.005; | |
4 | use strict; | |
5 | ||
6 | BEGIN { | |
7 | $Module::Install::TrustMetaYml::AUTHORITY = 'cpan:TOBYINK'; | |
8 | $Module::Install::TrustMetaYml::VERSION = '0.003'; | |
9 | } | |
10 | ||
11 | use base qw(Module::Install::Base); | |
12 | ||
13 | sub trust_meta_yml | |
14 | { | |
15 | my ($self, $where) = @_; | |
16 | $where ||= 'META.yml'; | |
17 | ||
18 | $self->perl_version('5.005') unless defined $self->perl_version; | |
19 | ||
20 | $self->include('YAML::Tiny', 0); | |
21 | return $self if $self->is_admin; | |
22 | ||
23 | require YAML::Tiny; | |
24 | my $data = YAML::Tiny::LoadFile($where); | |
25 | ||
26 | $self->perl_version($data->{requires}{perl} || '5.005'); | |
27 | ||
28 | KEY: foreach my $key (qw(requires recommends build_requires)) | |
29 | { | |
30 | next KEY unless ref $data->{$key} eq 'HASH'; | |
31 | my %deps = %{$data->{$key}}; | |
32 | DEP: while (my ($pkg, $ver) = each %deps) | |
33 | { | |
34 | next if $pkg eq 'perl'; | |
35 | $self->$key($pkg, $ver); | |
36 | } | |
37 | } | |
38 | ||
39 | return $self; | |
40 | } | |
41 | ||
42 | *trust_meta_yaml = \&trust_meta_yml; | |
43 | ||
44 | 1; | |
45 | ||
46 | __END__ | |
47 | ||
48 | =encoding utf8 | |
49 |
0 | #line 1 | |
1 | package Module::Install::Win32; | |
2 | ||
3 | use strict; | |
4 | use Module::Install::Base (); | |
5 | ||
6 | use vars qw{$VERSION @ISA $ISCORE}; | |
7 | BEGIN { | |
8 | $VERSION = '1.19'; | |
9 | @ISA = 'Module::Install::Base'; | |
10 | $ISCORE = 1; | |
11 | } | |
12 | ||
13 | # determine if the user needs nmake, and download it if needed | |
14 | sub check_nmake { | |
15 | my $self = shift; | |
16 | $self->load('can_run'); | |
17 | $self->load('get_file'); | |
18 | ||
19 | require Config; | |
20 | return unless ( | |
21 | $^O eq 'MSWin32' and | |
22 | $Config::Config{make} and | |
23 | $Config::Config{make} =~ /^nmake\b/i and | |
24 | ! $self->can_run('nmake') | |
25 | ); | |
26 | ||
27 | print "The required 'nmake' executable not found, fetching it...\n"; | |
28 | ||
29 | require File::Basename; | |
30 | my $rv = $self->get_file( | |
31 | url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe', | |
32 | ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe', | |
33 | local_dir => File::Basename::dirname($^X), | |
34 | size => 51928, | |
35 | run => 'Nmake15.exe /o > nul', | |
36 | check_for => 'Nmake.exe', | |
37 | remove => 1, | |
38 | ); | |
39 | ||
40 | die <<'END_MESSAGE' unless $rv; | |
41 | ||
42 | ------------------------------------------------------------------------------- | |
43 | ||
44 | Since you are using Microsoft Windows, you will need the 'nmake' utility | |
45 | before installation. It's available at: | |
46 | ||
47 | http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe | |
48 | or | |
49 | ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe | |
50 | ||
51 | Please download the file manually, save it to a directory in %PATH% (e.g. | |
52 | C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to | |
53 | that directory, and run "Nmake15.exe" from there; that will create the | |
54 | 'nmake.exe' file needed by this module. | |
55 | ||
56 | You may then resume the installation process described in README. | |
57 | ||
58 | ------------------------------------------------------------------------------- | |
59 | END_MESSAGE | |
60 | ||
61 | } | |
62 | ||
63 | 1; |
0 | #line 1 | |
1 | package Module::Install; | |
2 | ||
3 | # For any maintainers: | |
4 | # The load order for Module::Install is a bit magic. | |
5 | # It goes something like this... | |
6 | # | |
7 | # IF ( host has Module::Install installed, creating author mode ) { | |
8 | # 1. Makefile.PL calls "use inc::Module::Install" | |
9 | # 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install | |
10 | # 3. The installed version of inc::Module::Install loads | |
11 | # 4. inc::Module::Install calls "require Module::Install" | |
12 | # 5. The ./inc/ version of Module::Install loads | |
13 | # } ELSE { | |
14 | # 1. Makefile.PL calls "use inc::Module::Install" | |
15 | # 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install | |
16 | # 3. The ./inc/ version of Module::Install loads | |
17 | # } | |
18 | ||
19 | use 5.006; | |
20 | use strict 'vars'; | |
21 | use Cwd (); | |
22 | use File::Find (); | |
23 | use File::Path (); | |
24 | ||
25 | use vars qw{$VERSION $MAIN}; | |
26 | BEGIN { | |
27 | # All Module::Install core packages now require synchronised versions. | |
28 | # This will be used to ensure we don't accidentally load old or | |
29 | # different versions of modules. | |
30 | # This is not enforced yet, but will be some time in the next few | |
31 | # releases once we can make sure it won't clash with custom | |
32 | # Module::Install extensions. | |
33 | $VERSION = '1.19'; | |
34 | ||
35 | # Storage for the pseudo-singleton | |
36 | $MAIN = undef; | |
37 | ||
38 | *inc::Module::Install::VERSION = *VERSION; | |
39 | @inc::Module::Install::ISA = __PACKAGE__; | |
40 | ||
41 | } | |
42 | ||
43 | sub import { | |
44 | my $class = shift; | |
45 | my $self = $class->new(@_); | |
46 | my $who = $self->_caller; | |
47 | ||
48 | #------------------------------------------------------------- | |
49 | # all of the following checks should be included in import(), | |
50 | # to allow "eval 'require Module::Install; 1' to test | |
51 | # installation of Module::Install. (RT #51267) | |
52 | #------------------------------------------------------------- | |
53 | ||
54 | # Whether or not inc::Module::Install is actually loaded, the | |
55 | # $INC{inc/Module/Install.pm} is what will still get set as long as | |
56 | # the caller loaded module this in the documented manner. | |
57 | # If not set, the caller may NOT have loaded the bundled version, and thus | |
58 | # they may not have a MI version that works with the Makefile.PL. This would | |
59 | # result in false errors or unexpected behaviour. And we don't want that. | |
60 | my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm'; | |
61 | unless ( $INC{$file} ) { die <<"END_DIE" } | |
62 | ||
63 | Please invoke ${\__PACKAGE__} with: | |
64 | ||
65 | use inc::${\__PACKAGE__}; | |
66 | ||
67 | not: | |
68 | ||
69 | use ${\__PACKAGE__}; | |
70 | ||
71 | END_DIE | |
72 | ||
73 | # This reportedly fixes a rare Win32 UTC file time issue, but | |
74 | # as this is a non-cross-platform XS module not in the core, | |
75 | # we shouldn't really depend on it. See RT #24194 for detail. | |
76 | # (Also, this module only supports Perl 5.6 and above). | |
77 | eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006; | |
78 | ||
79 | # If the script that is loading Module::Install is from the future, | |
80 | # then make will detect this and cause it to re-run over and over | |
81 | # again. This is bad. Rather than taking action to touch it (which | |
82 | # is unreliable on some platforms and requires write permissions) | |
83 | # for now we should catch this and refuse to run. | |
84 | if ( -f $0 ) { | |
85 | my $s = (stat($0))[9]; | |
86 | ||
87 | # If the modification time is only slightly in the future, | |
88 | # sleep briefly to remove the problem. | |
89 | my $a = $s - time; | |
90 | if ( $a > 0 and $a < 5 ) { sleep 5 } | |
91 | ||
92 | # Too far in the future, throw an error. | |
93 | my $t = time; | |
94 | if ( $s > $t ) { die <<"END_DIE" } | |
95 | ||
96 | Your installer $0 has a modification time in the future ($s > $t). | |
97 | ||
98 | This is known to create infinite loops in make. | |
99 | ||
100 | Please correct this, then run $0 again. | |
101 | ||
102 | END_DIE | |
103 | } | |
104 | ||
105 | ||
106 | # Build.PL was formerly supported, but no longer is due to excessive | |
107 | # difficulty in implementing every single feature twice. | |
108 | if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" } | |
109 | ||
110 | Module::Install no longer supports Build.PL. | |
111 | ||
112 | It was impossible to maintain duel backends, and has been deprecated. | |
113 | ||
114 | Please remove all Build.PL files and only use the Makefile.PL installer. | |
115 | ||
116 | END_DIE | |
117 | ||
118 | #------------------------------------------------------------- | |
119 | ||
120 | # To save some more typing in Module::Install installers, every... | |
121 | # use inc::Module::Install | |
122 | # ...also acts as an implicit use strict. | |
123 | $^H |= strict::bits(qw(refs subs vars)); | |
124 | ||
125 | #------------------------------------------------------------- | |
126 | ||
127 | unless ( -f $self->{file} ) { | |
128 | foreach my $key (keys %INC) { | |
129 | delete $INC{$key} if $key =~ /Module\/Install/; | |
130 | } | |
131 | ||
132 | local $^W; | |
133 | require "$self->{path}/$self->{dispatch}.pm"; | |
134 | File::Path::mkpath("$self->{prefix}/$self->{author}"); | |
135 | $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self ); | |
136 | $self->{admin}->init; | |
137 | @_ = ($class, _self => $self); | |
138 | goto &{"$self->{name}::import"}; | |
139 | } | |
140 | ||
141 | local $^W; | |
142 | *{"${who}::AUTOLOAD"} = $self->autoload; | |
143 | $self->preload; | |
144 | ||
145 | # Unregister loader and worker packages so subdirs can use them again | |
146 | delete $INC{'inc/Module/Install.pm'}; | |
147 | delete $INC{'Module/Install.pm'}; | |
148 | ||
149 | # Save to the singleton | |
150 | $MAIN = $self; | |
151 | ||
152 | return 1; | |
153 | } | |
154 | ||
155 | sub autoload { | |
156 | my $self = shift; | |
157 | my $who = $self->_caller; | |
158 | my $cwd = Cwd::getcwd(); | |
159 | my $sym = "${who}::AUTOLOAD"; | |
160 | $sym->{$cwd} = sub { | |
161 | my $pwd = Cwd::getcwd(); | |
162 | if ( my $code = $sym->{$pwd} ) { | |
163 | # Delegate back to parent dirs | |
164 | goto &$code unless $cwd eq $pwd; | |
165 | } | |
166 | unless ($$sym =~ s/([^:]+)$//) { | |
167 | # XXX: it looks like we can't retrieve the missing function | |
168 | # via $$sym (usually $main::AUTOLOAD) in this case. | |
169 | # I'm still wondering if we should slurp Makefile.PL to | |
170 | # get some context or not ... | |
171 | my ($package, $file, $line) = caller; | |
172 | die <<"EOT"; | |
173 | Unknown function is found at $file line $line. | |
174 | Execution of $file aborted due to runtime errors. | |
175 | ||
176 | If you're a contributor to a project, you may need to install | |
177 | some Module::Install extensions from CPAN (or other repository). | |
178 | If you're a user of a module, please contact the author. | |
179 | EOT | |
180 | } | |
181 | my $method = $1; | |
182 | if ( uc($method) eq $method ) { | |
183 | # Do nothing | |
184 | return; | |
185 | } elsif ( $method =~ /^_/ and $self->can($method) ) { | |
186 | # Dispatch to the root M:I class | |
187 | return $self->$method(@_); | |
188 | } | |
189 | ||
190 | # Dispatch to the appropriate plugin | |
191 | unshift @_, ( $self, $1 ); | |
192 | goto &{$self->can('call')}; | |
193 | }; | |
194 | } | |
195 | ||
196 | sub preload { | |
197 | my $self = shift; | |
198 | unless ( $self->{extensions} ) { | |
199 | $self->load_extensions( | |
200 | "$self->{prefix}/$self->{path}", $self | |
201 | ); | |
202 | } | |
203 | ||
204 | my @exts = @{$self->{extensions}}; | |
205 | unless ( @exts ) { | |
206 | @exts = $self->{admin}->load_all_extensions; | |
207 | } | |
208 | ||
209 | my %seen; | |
210 | foreach my $obj ( @exts ) { | |
211 | while (my ($method, $glob) = each %{ref($obj) . '::'}) { | |
212 | next unless $obj->can($method); | |
213 | next if $method =~ /^_/; | |
214 | next if $method eq uc($method); | |
215 | $seen{$method}++; | |
216 | } | |
217 | } | |
218 | ||
219 | my $who = $self->_caller; | |
220 | foreach my $name ( sort keys %seen ) { | |
221 | local $^W; | |
222 | *{"${who}::$name"} = sub { | |
223 | ${"${who}::AUTOLOAD"} = "${who}::$name"; | |
224 | goto &{"${who}::AUTOLOAD"}; | |
225 | }; | |
226 | } | |
227 | } | |
228 | ||
229 | sub new { | |
230 | my ($class, %args) = @_; | |
231 | ||
232 | delete $INC{'FindBin.pm'}; | |
233 | { | |
234 | # to suppress the redefine warning | |
235 | local $SIG{__WARN__} = sub {}; | |
236 | require FindBin; | |
237 | } | |
238 | ||
239 | # ignore the prefix on extension modules built from top level. | |
240 | my $base_path = Cwd::abs_path($FindBin::Bin); | |
241 | unless ( Cwd::abs_path(Cwd::getcwd()) eq $base_path ) { | |
242 | delete $args{prefix}; | |
243 | } | |
244 | return $args{_self} if $args{_self}; | |
245 | ||
246 | $base_path = VMS::Filespec::unixify($base_path) if $^O eq 'VMS'; | |
247 | ||
248 | $args{dispatch} ||= 'Admin'; | |
249 | $args{prefix} ||= 'inc'; | |
250 | $args{author} ||= ($^O eq 'VMS' ? '_author' : '.author'); | |
251 | $args{bundle} ||= 'inc/BUNDLES'; | |
252 | $args{base} ||= $base_path; | |
253 | $class =~ s/^\Q$args{prefix}\E:://; | |
254 | $args{name} ||= $class; | |
255 | $args{version} ||= $class->VERSION; | |
256 | unless ( $args{path} ) { | |
257 | $args{path} = $args{name}; | |
258 | $args{path} =~ s!::!/!g; | |
259 | } | |
260 | $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm"; | |
261 | $args{wrote} = 0; | |
262 | ||
263 | bless( \%args, $class ); | |
264 | } | |
265 | ||
266 | sub call { | |
267 | my ($self, $method) = @_; | |
268 | my $obj = $self->load($method) or return; | |
269 | splice(@_, 0, 2, $obj); | |
270 | goto &{$obj->can($method)}; | |
271 | } | |
272 | ||
273 | sub load { | |
274 | my ($self, $method) = @_; | |
275 | ||
276 | $self->load_extensions( | |
277 | "$self->{prefix}/$self->{path}", $self | |
278 | ) unless $self->{extensions}; | |
279 | ||
280 | foreach my $obj (@{$self->{extensions}}) { | |
281 | return $obj if $obj->can($method); | |
282 | } | |
283 | ||
284 | my $admin = $self->{admin} or die <<"END_DIE"; | |
285 | The '$method' method does not exist in the '$self->{prefix}' path! | |
286 | Please remove the '$self->{prefix}' directory and run $0 again to load it. | |
287 | END_DIE | |
288 | ||
289 | my $obj = $admin->load($method, 1); | |
290 | push @{$self->{extensions}}, $obj; | |
291 | ||
292 | $obj; | |
293 | } | |
294 | ||
295 | sub load_extensions { | |
296 | my ($self, $path, $top) = @_; | |
297 | ||
298 | my $should_reload = 0; | |
299 | unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) { | |
300 | unshift @INC, $self->{prefix}; | |
301 | $should_reload = 1; | |
302 | } | |
303 | ||
304 | foreach my $rv ( $self->find_extensions($path) ) { | |
305 | my ($file, $pkg) = @{$rv}; | |
306 | next if $self->{pathnames}{$pkg}; | |
307 | ||
308 | local $@; | |
309 | my $new = eval { local $^W; require $file; $pkg->can('new') }; | |
310 | unless ( $new ) { | |
311 | warn $@ if $@; | |
312 | next; | |
313 | } | |
314 | $self->{pathnames}{$pkg} = | |
315 | $should_reload ? delete $INC{$file} : $INC{$file}; | |
316 | push @{$self->{extensions}}, &{$new}($pkg, _top => $top ); | |
317 | } | |
318 | ||
319 | $self->{extensions} ||= []; | |
320 | } | |
321 | ||
322 | sub find_extensions { | |
323 | my ($self, $path) = @_; | |
324 | ||
325 | my @found; | |
326 | File::Find::find( {no_chdir => 1, wanted => sub { | |
327 | my $file = $File::Find::name; | |
328 | return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is; | |
329 | my $subpath = $1; | |
330 | return if lc($subpath) eq lc($self->{dispatch}); | |
331 | ||
332 | $file = "$self->{path}/$subpath.pm"; | |
333 | my $pkg = "$self->{name}::$subpath"; | |
334 | $pkg =~ s!/!::!g; | |
335 | ||
336 | # If we have a mixed-case package name, assume case has been preserved | |
337 | # correctly. Otherwise, root through the file to locate the case-preserved | |
338 | # version of the package name. | |
339 | if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) { | |
340 | my $content = Module::Install::_read($File::Find::name); | |
341 | my $in_pod = 0; | |
342 | foreach ( split /\n/, $content ) { | |
343 | $in_pod = 1 if /^=\w/; | |
344 | $in_pod = 0 if /^=cut/; | |
345 | next if ($in_pod || /^=cut/); # skip pod text | |
346 | next if /^\s*#/; # and comments | |
347 | if ( m/^\s*package\s+($pkg)\s*;/i ) { | |
348 | $pkg = $1; | |
349 | last; | |
350 | } | |
351 | } | |
352 | } | |
353 | ||
354 | push @found, [ $file, $pkg ]; | |
355 | }}, $path ) if -d $path; | |
356 | ||
357 | @found; | |
358 | } | |
359 | ||
360 | ||
361 | ||
362 | ||
363 | ||
364 | ##################################################################### | |
365 | # Common Utility Functions | |
366 | ||
367 | sub _caller { | |
368 | my $depth = 0; | |
369 | my $call = caller($depth); | |
370 | while ( $call eq __PACKAGE__ ) { | |
371 | $depth++; | |
372 | $call = caller($depth); | |
373 | } | |
374 | return $call; | |
375 | } | |
376 | ||
377 | sub _read { | |
378 | local *FH; | |
379 | open( FH, '<', $_[0] ) or die "open($_[0]): $!"; | |
380 | binmode FH; | |
381 | my $string = do { local $/; <FH> }; | |
382 | close FH or die "close($_[0]): $!"; | |
383 | return $string; | |
384 | } | |
385 | ||
386 | sub _readperl { | |
387 | my $string = Module::Install::_read($_[0]); | |
388 | $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; | |
389 | $string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s; | |
390 | $string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg; | |
391 | return $string; | |
392 | } | |
393 | ||
394 | sub _readpod { | |
395 | my $string = Module::Install::_read($_[0]); | |
396 | $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; | |
397 | return $string if $_[0] =~ /\.pod\z/; | |
398 | $string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg; | |
399 | $string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg; | |
400 | $string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg; | |
401 | $string =~ s/^\n+//s; | |
402 | return $string; | |
403 | } | |
404 | ||
405 | sub _write { | |
406 | local *FH; | |
407 | open( FH, '>', $_[0] ) or die "open($_[0]): $!"; | |
408 | binmode FH; | |
409 | foreach ( 1 .. $#_ ) { | |
410 | print FH $_[$_] or die "print($_[0]): $!"; | |
411 | } | |
412 | close FH or die "close($_[0]): $!"; | |
413 | } | |
414 | ||
415 | # _version is for processing module versions (eg, 1.03_05) not | |
416 | # Perl versions (eg, 5.8.1). | |
417 | sub _version { | |
418 | my $s = shift || 0; | |
419 | my $d =()= $s =~ /(\.)/g; | |
420 | if ( $d >= 2 ) { | |
421 | # Normalise multipart versions | |
422 | $s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg; | |
423 | } | |
424 | $s =~ s/^(\d+)\.?//; | |
425 | my $l = $1 || 0; | |
426 | my @v = map { | |
427 | $_ . '0' x (3 - length $_) | |
428 | } $s =~ /(\d{1,3})\D?/g; | |
429 | $l = $l . '.' . join '', @v if @v; | |
430 | return $l + 0; | |
431 | } | |
432 | ||
433 | sub _cmp { | |
434 | _version($_[1]) <=> _version($_[2]); | |
435 | } | |
436 | ||
437 | # Cloned from Params::Util::_CLASS | |
438 | sub _CLASS { | |
439 | ( | |
440 | defined $_[0] | |
441 | and | |
442 | ! ref $_[0] | |
443 | and | |
444 | $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s | |
445 | ) ? $_[0] : undef; | |
446 | } | |
447 | ||
448 | 1; | |
449 | ||
450 | # Copyright 2008 - 2012 Adam Kennedy. |
0 | #line 1 | |
1 | package Module::Package::Dist::RDF; | |
2 | ||
3 | my $explanation = q< | |
4 | This is the component of Module::Package::RDF which gets | |
5 | bundled with the distribution. | |
6 | >; | |
7 | ||
8 | use 5.005; | |
9 | use strict; | |
10 | ||
11 | BEGIN { | |
12 | $Module::Package::Dist::RDF::AUTHORITY = 'cpan:TOBYINK'; | |
13 | $Module::Package::Dist::RDF::VERSION = '0.014'; | |
14 | @Module::Package::Dist::RDF::ISA = 'Module::Package::Dist'; | |
15 | } | |
16 | ||
17 | sub _main | |
18 | { | |
19 | my ($self) = @_; | |
20 | $self->mi->trust_meta_yml; | |
21 | $self->mi->auto_install; | |
22 | } | |
23 | ||
24 | { | |
25 | package Module::Package::Dist::RDF::standard; | |
26 | use 5.005; | |
27 | use strict; | |
28 | BEGIN { | |
29 | $Module::Package::Dist::RDF::standard::AUTHORITY = 'cpan:TOBYINK'; | |
30 | $Module::Package::Dist::RDF::standard::VERSION = '0.014'; | |
31 | @Module::Package::Dist::RDF::standard::ISA = 'Module::Package::Dist::RDF'; | |
32 | } | |
33 | } | |
34 | ||
35 | { | |
36 | package Module::Package::Dist::RDF::tobyink; | |
37 | use 5.005; | |
38 | use strict; | |
39 | BEGIN { | |
40 | $Module::Package::Dist::RDF::tobyink::AUTHORITY = 'cpan:TOBYINK'; | |
41 | $Module::Package::Dist::RDF::tobyink::VERSION = '0.014'; | |
42 | @Module::Package::Dist::RDF::tobyink::ISA = 'Module::Package::Dist::RDF'; | |
43 | } | |
44 | } | |
45 | ||
46 | 1; |
0 | `Module-Install-RDF` | |
1 | doap:shortdesc "advanced metadata for your distribution"@en; | |
2 | doap:programming-language "Perl"; | |
3 | doap:homepage <https://metacpan.org/release/Module-Install-RDF>; | |
4 | doap:download-page <https://metacpan.org/release/Module-Install-RDF>; | |
5 | doap:bug-database <http://rt.cpan.org/Dist/Display.html?Queue=Module-Install-RDF>; | |
6 | doap:repository [ a doap:GitRepository; doap:browse <https://github.com/tobyink/p5-module-install-rdf> ]; | |
7 | doap:maintainer cpan:tobyink ; | |
8 | doap:developer cpan:tobyink ; | |
9 | doap:documenter cpan:tobyink ; | |
10 | doap:tester cpan:tobyink ; | |
11 | doap:created 2011-09-30 ; | |
12 | doap:license <http://dev.perl.org/licenses/>; | |
13 | doap:category [label "Semantic Web"], [label "Packaging"]. | |
14 | ||
15 | cpan:tobyink | |
16 | foaf:name "Toby Inkster"; | |
17 | foaf:mbox <mailto:tobyink@cpan.org>; | |
18 | foaf:homepage <http://tobyinkster.co.uk/>. |
0 | `Module-Install-RDF` | |
1 | perl_version_from m`Module::Install::RDF`; | |
2 | version_from m`Module::Install::RDF`; | |
3 | readme_from m`Module::Install::RDF`. |
0 | 0 | This file contains message digests of all files listed in MANIFEST, |
1 | signed via the Module::Signature module, version 0.70. | |
1 | signed via the Module::Signature module, version 0.87. | |
2 | 2 | |
3 | 3 | To verify the content in this distribution, first make sure you have |
4 | 4 | Module::Signature installed, then type: |
11 | 11 | not run its Makefile.PL or Build.PL. |
12 | 12 | |
13 | 13 | -----BEGIN PGP SIGNED MESSAGE----- |
14 | Hash: SHA1 | |
14 | Hash: RIPEMD160 | |
15 | 15 | |
16 | SHA1 294505f858f11dd062e9916e3f50d88210a9ef54 CONTRIBUTING | |
17 | SHA1 8ed4b381569aefee5149338f8881c9c60e3f6a2e COPYRIGHT | |
18 | SHA1 9e307a5415ca4fa0a76a08bd7236f23f15544ea8 CREDITS | |
19 | SHA1 23d5bdb57336643b9dde70697ac26069c3eba05f Changes | |
20 | SHA1 937d452c5c4069f4cda9ffaf45a33f1eb5f060e8 LICENSE | |
21 | SHA1 f513ba260eee9e440322894fabe2944b5c75f90d MANIFEST | |
22 | SHA1 a950aef0884cd0538ec47f761e7199ae1d71f369 META.ttl | |
23 | SHA1 45ed94dd39d090c91f0d5ddebee6ae0f3ff62066 META.yml | |
24 | SHA1 7d65b6447bdb20b1734b465650073c4b6989ea0c Makefile.PL | |
25 | SHA1 099d10ed070f831b40aaa662973289d9b46b477b README | |
26 | SHA1 1d1d860c3b00f22531e13185f1a7ae411e1a6363 TODO | |
27 | SHA1 06c410f05488c1612ed66b06d3a86b2580581e4a inc/Module/AutoInstall.pm | |
28 | SHA1 8a924add836b60fb23b25c8506d45945e02f42f4 inc/Module/Install.pm | |
29 | SHA1 61ab1dd37e33ddbe155907ce51df8a3e56ac8bbf inc/Module/Install/AutoInstall.pm | |
30 | SHA1 c04f94f91fa97b9f8cfb5a36071098ab0e6c78e3 inc/Module/Install/AutoManifest.pm | |
31 | SHA1 2d0fad3bf255f8c1e7e1e34eafccc4f595603ddc inc/Module/Install/Base.pm | |
32 | SHA1 f0e01fff7d73cd145fbf22331579918d4628ddb0 inc/Module/Install/Can.pm | |
33 | SHA1 7328966e4fda0c8451a6d3850704da0b84ac1540 inc/Module/Install/Fetch.pm | |
34 | SHA1 66d3d335a03492583a3be121a7d888f63f08412c inc/Module/Install/Include.pm | |
35 | SHA1 b62ca5e2d58fa66766ccf4d64574f9e1a2250b34 inc/Module/Install/Makefile.pm | |
36 | SHA1 1aa925be410bb3bfcd84a16985921f66073cc1d2 inc/Module/Install/Metadata.pm | |
37 | SHA1 3b9281ddf7dd6d6f5de0a9642c69333023193c80 inc/Module/Install/Package.pm | |
38 | SHA1 41f76ff6b39368a65da86377e43b34bacc2fb0eb inc/Module/Install/TrustMetaYml.pm | |
39 | SHA1 e4196994fa75e98bdfa2be0bdeeffef66de88171 inc/Module/Install/Win32.pm | |
40 | SHA1 c3a6d0d5b84feb3280622e9599e86247d58b0d18 inc/Module/Install/WriteAll.pm | |
41 | SHA1 26d58a041cd6b3d21db98b32e8fd1841aae21204 inc/Module/Package.pm | |
42 | SHA1 5a2f84a7a82eee0d1e5ed3628fe503a608efc10f inc/Module/Package/Dist/RDF.pm | |
43 | SHA1 feb933cefe2e3762e8322bd6071a2499f3440da1 inc/YAML/Tiny.pm | |
44 | SHA1 54f00c91d7679afc97750ed81cbe6d4ac6cfa27d lib/Module/Install/Admin/RDF.pm | |
45 | SHA1 3c22f4014d39103aa3cdc064c6c59ff8b729c536 lib/Module/Install/RDF.pm | |
46 | SHA1 c336208dfee320c84d7dad5580fbb24095c50618 meta/changes.pret | |
47 | SHA1 a0b8d060905f7d38f5d7a2541d3b67f66b5f87be meta/deps.pret | |
48 | SHA1 5a30d14ba5152ce7eba4a7428ec2e36ab0946100 meta/doap.pret | |
49 | SHA1 370405b43e499ee72fd9554967d6158a62c0fc61 meta/makefile.pret | |
50 | SHA1 7f545d93d1dcdf124740caaceeac507686c4cc04 t/01basic.t | |
51 | -----BEGIN PGP SIGNATURE----- | |
52 | Version: GnuPG v1.4.12 (GNU/Linux) | |
53 | ||
54 | iEYEARECAAYFAlH417cACgkQzr+BKGoqfTnXNACgr1Mmn5JKCnjnuAQZuqKKyhf0 | |
55 | KkwAoLcVMn9Cu8rax2nfHg8wJUu4WVH0 | |
56 | =5GSo | |
57 | -----END PGP SIGNATURE----- | |
16 | SHA256 9cda904accd03e9762e2b308d6bb10885ecb718958e464df6c8c19cc578c249a COPYRIGHT | |
17 | SHA256 25af90ec7f74c91fe7fcb8de787ba5fae1aef82185a08bc71b5405d08e0ecd04 CREDITS | |
18 | SHA256 ece4ec8c82282d6f42592fa6cedde3fb882ceeed4b92f40b888ee64c40a68389 Changes | |
19 | SHA256 0eaea1ad501498a926f33ddd4d759f4885180785b9dc33c31156802ff806a42e LICENSE | |
20 | SHA256 1cebc8e721ce3874c3242e830c51785efd46a021b0c7fab4ec86d8b39d47fe28 MANIFEST | |
21 | SHA256 f88eb27340e5007900fd62ae1841d5dd78e21d73163bf3cf8a859ed012ebcc3e META.ttl | |
22 | SHA256 2636a376133b5c854382b91e3c347898f0670ec9ab0831dd9a2ded365529398f META.yml | |
23 | SHA256 7b08112ad3fe5cc3b7000d2f926a4d4c456ca5a06175c4ff4de8d145faec5e21 Makefile.PL | |
24 | SHA256 9cda904accd03e9762e2b308d6bb10885ecb718958e464df6c8c19cc578c249a Module-Install-RDF-0.009/COPYRIGHT | |
25 | SHA256 ece4ec8c82282d6f42592fa6cedde3fb882ceeed4b92f40b888ee64c40a68389 Module-Install-RDF-0.009/Changes | |
26 | SHA256 0eaea1ad501498a926f33ddd4d759f4885180785b9dc33c31156802ff806a42e Module-Install-RDF-0.009/LICENSE | |
27 | SHA256 c5868da18d83525c79a9750cce11078ca72399111eddbb5d049af4f30d2a558a Module-Install-RDF-0.009/MANIFEST | |
28 | SHA256 f88eb27340e5007900fd62ae1841d5dd78e21d73163bf3cf8a859ed012ebcc3e Module-Install-RDF-0.009/META.ttl | |
29 | SHA256 7b08112ad3fe5cc3b7000d2f926a4d4c456ca5a06175c4ff4de8d145faec5e21 Module-Install-RDF-0.009/Makefile.PL | |
30 | SHA256 76d5a555934695badce7ce71c72ffe709fac3405a15ebdf41418323ae3338ac5 Module-Install-RDF-0.009/README | |
31 | SHA256 7fe8013fad8ecb0b9ef8bad3fd7287486c1c61c776f76beb7d9d24e06ee3ab44 Module-Install-RDF-0.009/inc/Module/AutoInstall.pm | |
32 | SHA256 67d139199c03b8bf8447a5a62f0d0b6dc1bd5bf6dbe04de6d21998c577823ed6 Module-Install-RDF-0.009/inc/Module/Install.pm | |
33 | SHA256 1e48ae2cb24e1d16193d476e735579dfcd0eefb3685921ad4736390df75d939b Module-Install-RDF-0.009/inc/Module/Install/AutoInstall.pm | |
34 | SHA256 d3f8c839d03fd21c197d05362dbb277cd7cadb15da6390d124b61e851f15146e Module-Install-RDF-0.009/inc/Module/Install/Can.pm | |
35 | SHA256 e9e72e18921c10c87bc4ea4c20af83e52015b9f5775d00ac64073042403717ca Module-Install-RDF-0.009/inc/Module/Install/Fetch.pm | |
36 | SHA256 a7a681bf2c9eee58a372cb642ffe42b0301d1200432ba8de9f7791cd1ecc9827 Module-Install-RDF-0.009/inc/Module/Install/Makefile.pm | |
37 | SHA256 aa887fa65a5eb6bbd1805706ce298b3f3cd55b353ecfd37aa7d35ae419331a49 Module-Install-RDF-0.009/inc/Module/Install/Metadata.pm | |
38 | SHA256 10b9bb7cebcfe617d71f30b31a0a390a72336881ea20ee48826501550c2fe716 Module-Install-RDF-0.009/inc/Module/Install/TrustMetaYml.pm | |
39 | SHA256 26b166ff62aacdb55317d1659f160aa4935097eea9810ea980e6d747206b5dc0 Module-Install-RDF-0.009/inc/Module/Install/Win32.pm | |
40 | SHA256 713961cf4af8cf4a495e6072d6b793e8a2ccb4b3ac2e567d30fbe69439b18a81 Module-Install-RDF-0.009/inc/Module/Package/Dist/RDF.pm | |
41 | SHA256 483290e1e2712b5ae6210a870d2757c204048ace9cacf3b28e1997d3c6e55016 Module-Install-RDF-0.009/meta/doap.pret | |
42 | SHA256 d6cfd91f7f540dbceaf860c45fe8504f4325113446c15f35bfdc6fb86cfbb331 Module-Install-RDF-0.009/meta/makefile.pret | |
43 | SHA256 76d5a555934695badce7ce71c72ffe709fac3405a15ebdf41418323ae3338ac5 README | |
44 | SHA256 0a1c7e5d857bd3f765e1316bfa7af1722aa24a8f19b7ace61c33025e9eab1dcf TODO | |
45 | SHA256 7fe8013fad8ecb0b9ef8bad3fd7287486c1c61c776f76beb7d9d24e06ee3ab44 inc/Module/AutoInstall.pm | |
46 | SHA256 67d139199c03b8bf8447a5a62f0d0b6dc1bd5bf6dbe04de6d21998c577823ed6 inc/Module/Install.pm | |
47 | SHA256 1e48ae2cb24e1d16193d476e735579dfcd0eefb3685921ad4736390df75d939b inc/Module/Install/AutoInstall.pm | |
48 | SHA256 5ba8a77513f5cf4e60d0e84bd64c1b8316b23d74af42272ac528a4dd1609b708 inc/Module/Install/AutoManifest.pm | |
49 | SHA256 6ebcc53a161dd5dc0aae69e4704575f2b00181901d768a82e26722a309cfdbe4 inc/Module/Install/Base.pm | |
50 | SHA256 d3f8c839d03fd21c197d05362dbb277cd7cadb15da6390d124b61e851f15146e inc/Module/Install/Can.pm | |
51 | SHA256 e9e72e18921c10c87bc4ea4c20af83e52015b9f5775d00ac64073042403717ca inc/Module/Install/Fetch.pm | |
52 | SHA256 a97bf661b739643c3adee064addf7a85f22e25e1bbffc137974cd8754ffa5c66 inc/Module/Install/Include.pm | |
53 | SHA256 a7a681bf2c9eee58a372cb642ffe42b0301d1200432ba8de9f7791cd1ecc9827 inc/Module/Install/Makefile.pm | |
54 | SHA256 aa887fa65a5eb6bbd1805706ce298b3f3cd55b353ecfd37aa7d35ae419331a49 inc/Module/Install/Metadata.pm | |
55 | SHA256 4f3968e504200c6456f6dd41d3cd24e5366a4848042dc2cb7c346c3165ef3e25 inc/Module/Install/Package.pm | |
56 | SHA256 10b9bb7cebcfe617d71f30b31a0a390a72336881ea20ee48826501550c2fe716 inc/Module/Install/TrustMetaYml.pm | |
57 | SHA256 26b166ff62aacdb55317d1659f160aa4935097eea9810ea980e6d747206b5dc0 inc/Module/Install/Win32.pm | |
58 | SHA256 5f73a6851a91ea44e65b924f918743ad6e860620ad7a38a39d0295e0c5652a9f inc/Module/Install/WriteAll.pm | |
59 | SHA256 59d9db60b1bf7e664805b8c573df7a4009b975dd003046468817e44d04847940 inc/Module/Package.pm | |
60 | SHA256 713961cf4af8cf4a495e6072d6b793e8a2ccb4b3ac2e567d30fbe69439b18a81 inc/Module/Package/Dist/RDF.pm | |
61 | SHA256 3164c32202bf4604ab1f90b926a81e15493b191e0bc2f90ae42d8358f18259d6 inc/YAML/Tiny.pm | |
62 | SHA256 807524a7f11ebd57430fc9ab5c30b72697bd3f7aa24777430ec2894e97915210 lib/Module/Install/Admin/RDF.pm | |
63 | SHA256 cc2aef87fa5a0a37077fdb8e5aa3e6d1123979bef90a1ad7fee2891ac4f316ce lib/Module/Install/RDF.pm | |
64 | SHA256 9a5bc2710d0ac72b0de9ca0e7b5c78820413d06b2989f820bcd805293432d922 meta/changes.pret | |
65 | SHA256 54c27a6f4f1880dde46ce3d088e3d9cd85068a76591ed40a068e6afbc81dcac6 meta/deps.pret | |
66 | SHA256 483290e1e2712b5ae6210a870d2757c204048ace9cacf3b28e1997d3c6e55016 meta/doap.pret | |
67 | SHA256 d6cfd91f7f540dbceaf860c45fe8504f4325113446c15f35bfdc6fb86cfbb331 meta/makefile.pret | |
68 | SHA256 8416a9c119bc8df0c329a628b2f1ae9fcb1914ecd02a1dc1e88adc698c629cdd t/01basic.t |
7 | 7 | |
8 | 8 | use vars qw{$VERSION}; |
9 | 9 | BEGIN { |
10 | $VERSION = '1.06'; | |
10 | $VERSION = '1.19'; | |
11 | 11 | } |
12 | 12 | |
13 | 13 | # special map on pre-defined feature sets |
114 | 114 | print "*** $class version " . $class->VERSION . "\n"; |
115 | 115 | print "*** Checking for Perl dependencies...\n"; |
116 | 116 | |
117 | my $cwd = Cwd::cwd(); | |
117 | my $cwd = Cwd::getcwd(); | |
118 | 118 | |
119 | 119 | $Config = []; |
120 | 120 | |
165 | 165 | $modules = [ %{$modules} ] if UNIVERSAL::isa( $modules, 'HASH' ); |
166 | 166 | |
167 | 167 | unshift @$modules, -default => &{ shift(@$modules) } |
168 | if ( ref( $modules->[0] ) eq 'CODE' ); # XXX: bugward combatability | |
168 | if ( ref( $modules->[0] ) eq 'CODE' ); # XXX: bugward compatibility | |
169 | 169 | |
170 | 170 | while ( my ( $mod, $arg ) = splice( @$modules, 0, 2 ) ) { |
171 | 171 | if ( $mod =~ m/^-(\w+)$/ ) { |
344 | 344 | my $i; # used below to strip leading '-' from config keys |
345 | 345 | my @config = ( map { s/^-// if ++$i; $_ } @{ +shift } ); |
346 | 346 | |
347 | my ( @modules, @installed ); | |
348 | while ( my ( $pkg, $ver ) = splice( @_, 0, 2 ) ) { | |
349 | ||
350 | # grep out those already installed | |
351 | if ( _version_cmp( _version_of($pkg), $ver ) >= 0 ) { | |
352 | push @installed, $pkg; | |
353 | } | |
354 | else { | |
355 | push @modules, $pkg, $ver; | |
356 | } | |
357 | } | |
358 | ||
359 | if ($UpgradeDeps) { | |
360 | push @modules, @installed; | |
361 | @installed = (); | |
362 | } | |
347 | my ( @modules, @installed, @modules_to_upgrade ); | |
348 | while (my ($pkg, $ver) = splice(@_, 0, 2)) { | |
349 | ||
350 | # grep out those already installed | |
351 | if (_version_cmp(_version_of($pkg), $ver) >= 0) { | |
352 | push @installed, $pkg; | |
353 | if ($UpgradeDeps) { | |
354 | push @modules_to_upgrade, $pkg, $ver; | |
355 | } | |
356 | } | |
357 | else { | |
358 | push @modules, $pkg, $ver; | |
359 | } | |
360 | } | |
361 | ||
362 | if ($UpgradeDeps) { | |
363 | push @modules, @modules_to_upgrade; | |
364 | @installed = (); | |
365 | @modules_to_upgrade = (); | |
366 | } | |
363 | 367 | |
364 | 368 | return @installed unless @modules; # nothing to do |
365 | 369 | return @installed if _check_lock(); # defer to the CPAN shell |
532 | 536 | while ( my ( $opt, $arg ) = splice( @config, 0, 2 ) ) { |
533 | 537 | ( $args{$opt} = $arg, next ) |
534 | 538 | if $opt =~ /^(?:force|notest)$/; # pseudo-option |
535 | $CPAN::Config->{$opt} = $arg; | |
539 | $CPAN::Config->{$opt} = $opt eq 'urllist' ? [$arg] : $arg; | |
536 | 540 | } |
537 | 541 | |
538 | 542 | if ($args{notest} && (not CPAN::Shell->can('notest'))) { |
610 | 614 | require Cwd; |
611 | 615 | require File::Spec; |
612 | 616 | |
613 | my $cwd = File::Spec->canonpath( Cwd::cwd() ); | |
617 | my $cwd = File::Spec->canonpath( Cwd::getcwd() ); | |
614 | 618 | my $cpan = File::Spec->canonpath( $CPAN::Config->{cpan_home} ); |
615 | 619 | |
616 | 620 | return ( index( $cwd, $cpan ) > -1 ); |
926 | 930 | |
927 | 931 | __END__ |
928 | 932 | |
929 | #line 1193 | |
933 | #line 1197 |
5 | 5 | |
6 | 6 | use vars qw{$VERSION @ISA $ISCORE}; |
7 | 7 | BEGIN { |
8 | $VERSION = '1.06'; | |
8 | $VERSION = '1.19'; | |
9 | 9 | @ISA = 'Module::Install::Base'; |
10 | 10 | $ISCORE = 1; |
11 | 11 | } |
3 | 3 | use strict 'vars'; |
4 | 4 | use vars qw{$VERSION}; |
5 | 5 | BEGIN { |
6 | $VERSION = '1.06'; | |
6 | $VERSION = '1.19'; | |
7 | 7 | } |
8 | 8 | |
9 | 9 | # Suspend handler for "redefined" warnings |
7 | 7 | |
8 | 8 | use vars qw{$VERSION @ISA $ISCORE}; |
9 | 9 | BEGIN { |
10 | $VERSION = '1.06'; | |
10 | $VERSION = '1.19'; | |
11 | 11 | @ISA = 'Module::Install::Base'; |
12 | 12 | $ISCORE = 1; |
13 | 13 | } |
120 | 120 | # Can we locate a (the) C compiler |
121 | 121 | sub can_cc { |
122 | 122 | my $self = shift; |
123 | ||
124 | if ($^O eq 'VMS') { | |
125 | require ExtUtils::CBuilder; | |
126 | my $builder = ExtUtils::CBuilder->new( | |
127 | quiet => 1, | |
128 | ); | |
129 | return $builder->have_compiler; | |
130 | } | |
131 | ||
123 | 132 | my @chunks = split(/ /, $Config::Config{cc}) or return; |
124 | 133 | |
125 | 134 | # $Config{cc} may contain args; try to find out the program part |
150 | 159 | |
151 | 160 | __END__ |
152 | 161 | |
153 | #line 236 | |
162 | #line 245 |
5 | 5 | |
6 | 6 | use vars qw{$VERSION @ISA $ISCORE}; |
7 | 7 | BEGIN { |
8 | $VERSION = '1.06'; | |
8 | $VERSION = '1.19'; | |
9 | 9 | @ISA = 'Module::Install::Base'; |
10 | 10 | $ISCORE = 1; |
11 | 11 | } |
5 | 5 | |
6 | 6 | use vars qw{$VERSION @ISA $ISCORE}; |
7 | 7 | BEGIN { |
8 | $VERSION = '1.06'; | |
8 | $VERSION = '1.19'; | |
9 | 9 | @ISA = 'Module::Install::Base'; |
10 | 10 | $ISCORE = 1; |
11 | 11 | } |
7 | 7 | |
8 | 8 | use vars qw{$VERSION @ISA $ISCORE}; |
9 | 9 | BEGIN { |
10 | $VERSION = '1.06'; | |
10 | $VERSION = '1.19'; | |
11 | 11 | @ISA = 'Module::Install::Base'; |
12 | 12 | $ISCORE = 1; |
13 | 13 | } |
132 | 132 | return $args; |
133 | 133 | } |
134 | 134 | |
135 | # For mm args that take multiple space-seperated args, | |
135 | # For mm args that take multiple space-separated args, | |
136 | 136 | # append an argument to the current list. |
137 | 137 | sub makemaker_append { |
138 | 138 | my $self = shift; |
5 | 5 | |
6 | 6 | use vars qw{$VERSION @ISA $ISCORE}; |
7 | 7 | BEGIN { |
8 | $VERSION = '1.06'; | |
8 | $VERSION = '1.19'; | |
9 | 9 | @ISA = 'Module::Install::Base'; |
10 | 10 | $ISCORE = 1; |
11 | 11 | } |
346 | 346 | ^ \s* |
347 | 347 | package \s* |
348 | 348 | ([\w:]+) |
349 | \s* ; | |
349 | [\s|;]* | |
350 | 350 | /ixms |
351 | 351 | ) { |
352 | 352 | my ($name, $module_name) = ($1, $1); |
704 | 704 | my @yaml = Parse::CPAN::Meta::LoadFile('META.yml'); |
705 | 705 | my $meta = $yaml[0]; |
706 | 706 | |
707 | # Overwrite the non-configure dependency hashs | |
707 | # Overwrite the non-configure dependency hashes | |
708 | 708 | delete $meta->{requires}; |
709 | 709 | delete $meta->{build_requires}; |
710 | 710 | delete $meta->{recommends}; |
5 | 5 | |
6 | 6 | use vars qw{$VERSION @ISA $ISCORE}; |
7 | 7 | BEGIN { |
8 | $VERSION = '1.06'; | |
8 | $VERSION = '1.19'; | |
9 | 9 | @ISA = 'Module::Install::Base'; |
10 | 10 | $ISCORE = 1; |
11 | 11 | } |
5 | 5 | |
6 | 6 | use vars qw{$VERSION @ISA $ISCORE}; |
7 | 7 | BEGIN { |
8 | $VERSION = '1.06'; | |
8 | $VERSION = '1.19'; | |
9 | 9 | @ISA = qw{Module::Install::Base}; |
10 | 10 | $ISCORE = 1; |
11 | 11 | } |
16 | 16 | # 3. The ./inc/ version of Module::Install loads |
17 | 17 | # } |
18 | 18 | |
19 | use 5.005; | |
19 | use 5.006; | |
20 | 20 | use strict 'vars'; |
21 | 21 | use Cwd (); |
22 | 22 | use File::Find (); |
30 | 30 | # This is not enforced yet, but will be some time in the next few |
31 | 31 | # releases once we can make sure it won't clash with custom |
32 | 32 | # Module::Install extensions. |
33 | $VERSION = '1.06'; | |
33 | $VERSION = '1.19'; | |
34 | 34 | |
35 | 35 | # Storage for the pseudo-singleton |
36 | 36 | $MAIN = undef; |
155 | 155 | sub autoload { |
156 | 156 | my $self = shift; |
157 | 157 | my $who = $self->_caller; |
158 | my $cwd = Cwd::cwd(); | |
158 | my $cwd = Cwd::getcwd(); | |
159 | 159 | my $sym = "${who}::AUTOLOAD"; |
160 | 160 | $sym->{$cwd} = sub { |
161 | my $pwd = Cwd::cwd(); | |
161 | my $pwd = Cwd::getcwd(); | |
162 | 162 | if ( my $code = $sym->{$pwd} ) { |
163 | 163 | # Delegate back to parent dirs |
164 | 164 | goto &$code unless $cwd eq $pwd; |
238 | 238 | |
239 | 239 | # ignore the prefix on extension modules built from top level. |
240 | 240 | my $base_path = Cwd::abs_path($FindBin::Bin); |
241 | unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) { | |
241 | unless ( Cwd::abs_path(Cwd::getcwd()) eq $base_path ) { | |
242 | 242 | delete $args{prefix}; |
243 | 243 | } |
244 | 244 | return $args{_self} if $args{_self}; |
245 | ||
246 | $base_path = VMS::Filespec::unixify($base_path) if $^O eq 'VMS'; | |
245 | 247 | |
246 | 248 | $args{dispatch} ||= 'Admin'; |
247 | 249 | $args{prefix} ||= 'inc'; |
321 | 323 | my ($self, $path) = @_; |
322 | 324 | |
323 | 325 | my @found; |
324 | File::Find::find( sub { | |
326 | File::Find::find( {no_chdir => 1, wanted => sub { | |
325 | 327 | my $file = $File::Find::name; |
326 | 328 | return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is; |
327 | 329 | my $subpath = $1; |
335 | 337 | # correctly. Otherwise, root through the file to locate the case-preserved |
336 | 338 | # version of the package name. |
337 | 339 | if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) { |
338 | my $content = Module::Install::_read($subpath . '.pm'); | |
340 | my $content = Module::Install::_read($File::Find::name); | |
339 | 341 | my $in_pod = 0; |
340 | foreach ( split //, $content ) { | |
342 | foreach ( split /\n/, $content ) { | |
341 | 343 | $in_pod = 1 if /^=\w/; |
342 | 344 | $in_pod = 0 if /^=cut/; |
343 | 345 | next if ($in_pod || /^=cut/); # skip pod text |
350 | 352 | } |
351 | 353 | |
352 | 354 | push @found, [ $file, $pkg ]; |
353 | }, $path ) if -d $path; | |
355 | }}, $path ) if -d $path; | |
354 | 356 | |
355 | 357 | @found; |
356 | 358 | } |
372 | 374 | return $call; |
373 | 375 | } |
374 | 376 | |
375 | # Done in evals to avoid confusing Perl::MinimumVersion | |
376 | eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; | |
377 | 377 | sub _read { |
378 | 378 | local *FH; |
379 | 379 | open( FH, '<', $_[0] ) or die "open($_[0]): $!"; |
380 | binmode FH; | |
380 | 381 | my $string = do { local $/; <FH> }; |
381 | 382 | close FH or die "close($_[0]): $!"; |
382 | 383 | return $string; |
383 | 384 | } |
384 | END_NEW | |
385 | sub _read { | |
386 | local *FH; | |
387 | open( FH, "< $_[0]" ) or die "open($_[0]): $!"; | |
388 | my $string = do { local $/; <FH> }; | |
389 | close FH or die "close($_[0]): $!"; | |
390 | return $string; | |
391 | } | |
392 | END_OLD | |
393 | 385 | |
394 | 386 | sub _readperl { |
395 | 387 | my $string = Module::Install::_read($_[0]); |
410 | 402 | return $string; |
411 | 403 | } |
412 | 404 | |
413 | # Done in evals to avoid confusing Perl::MinimumVersion | |
414 | eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; | |
415 | 405 | sub _write { |
416 | 406 | local *FH; |
417 | 407 | open( FH, '>', $_[0] ) or die "open($_[0]): $!"; |
408 | binmode FH; | |
418 | 409 | foreach ( 1 .. $#_ ) { |
419 | 410 | print FH $_[$_] or die "print($_[0]): $!"; |
420 | 411 | } |
421 | 412 | close FH or die "close($_[0]): $!"; |
422 | 413 | } |
423 | END_NEW | |
424 | sub _write { | |
425 | local *FH; | |
426 | open( FH, "> $_[0]" ) or die "open($_[0]): $!"; | |
427 | foreach ( 1 .. $#_ ) { | |
428 | print FH $_[$_] or die "print($_[0]): $!"; | |
429 | } | |
430 | close FH or die "close($_[0]): $!"; | |
431 | } | |
432 | END_OLD | |
433 | 414 | |
434 | 415 | # _version is for processing module versions (eg, 1.03_05) not |
435 | 416 | # Perl versions (eg, 5.8.1). |
436 | sub _version ($) { | |
417 | sub _version { | |
437 | 418 | my $s = shift || 0; |
438 | 419 | my $d =()= $s =~ /(\.)/g; |
439 | 420 | if ( $d >= 2 ) { |
449 | 430 | return $l + 0; |
450 | 431 | } |
451 | 432 | |
452 | sub _cmp ($$) { | |
433 | sub _cmp { | |
453 | 434 | _version($_[1]) <=> _version($_[2]); |
454 | 435 | } |
455 | 436 | |
456 | 437 | # Cloned from Params::Util::_CLASS |
457 | sub _CLASS ($) { | |
438 | sub _CLASS { | |
458 | 439 | ( |
459 | 440 | defined $_[0] |
460 | 441 | and |
10 | 10 | |
11 | 11 | BEGIN { |
12 | 12 | $Module::Package::Dist::RDF::AUTHORITY = 'cpan:TOBYINK'; |
13 | $Module::Package::Dist::RDF::VERSION = '0.012'; | |
13 | $Module::Package::Dist::RDF::VERSION = '0.014'; | |
14 | 14 | @Module::Package::Dist::RDF::ISA = 'Module::Package::Dist'; |
15 | 15 | } |
16 | 16 | |
27 | 27 | use strict; |
28 | 28 | BEGIN { |
29 | 29 | $Module::Package::Dist::RDF::standard::AUTHORITY = 'cpan:TOBYINK'; |
30 | $Module::Package::Dist::RDF::standard::VERSION = '0.012'; | |
30 | $Module::Package::Dist::RDF::standard::VERSION = '0.014'; | |
31 | 31 | @Module::Package::Dist::RDF::standard::ISA = 'Module::Package::Dist::RDF'; |
32 | 32 | } |
33 | 33 | } |
38 | 38 | use strict; |
39 | 39 | BEGIN { |
40 | 40 | $Module::Package::Dist::RDF::tobyink::AUTHORITY = 'cpan:TOBYINK'; |
41 | $Module::Package::Dist::RDF::tobyink::VERSION = '0.012'; | |
41 | $Module::Package::Dist::RDF::tobyink::VERSION = '0.014'; | |
42 | 42 | @Module::Package::Dist::RDF::tobyink::ISA = 'Module::Package::Dist::RDF'; |
43 | 43 | } |
44 | 44 | } |
0 | 0 | #line 1 |
1 | package YAML::Tiny; | |
2 | ||
1 | use 5.008001; # sane UTF-8 support | |
3 | 2 | use strict; |
4 | ||
5 | # UTF Support? | |
6 | sub HAVE_UTF8 () { $] >= 5.007003 } | |
3 | use warnings; | |
4 | package YAML::Tiny; # git description: v1.72-7-g8682f63 | |
5 | # XXX-INGY is 5.8.1 too old/broken for utf8? | |
6 | # XXX-XDG Lancaster consensus was that it was sufficient until | |
7 | # proven otherwise | |
8 | ||
9 | our $VERSION = '1.73'; | |
10 | ||
11 | ##################################################################### | |
12 | # The YAML::Tiny API. | |
13 | # | |
14 | # These are the currently documented API functions/methods and | |
15 | # exports: | |
16 | ||
17 | use Exporter; | |
18 | our @ISA = qw{ Exporter }; | |
19 | our @EXPORT = qw{ Load Dump }; | |
20 | our @EXPORT_OK = qw{ LoadFile DumpFile freeze thaw }; | |
21 | ||
22 | ### | |
23 | # Functional/Export API: | |
24 | ||
25 | sub Dump { | |
26 | return YAML::Tiny->new(@_)->_dump_string; | |
27 | } | |
28 | ||
29 | # XXX-INGY Returning last document seems a bad behavior. | |
30 | # XXX-XDG I think first would seem more natural, but I don't know | |
31 | # that it's worth changing now | |
32 | sub Load { | |
33 | my $self = YAML::Tiny->_load_string(@_); | |
34 | if ( wantarray ) { | |
35 | return @$self; | |
36 | } else { | |
37 | # To match YAML.pm, return the last document | |
38 | return $self->[-1]; | |
39 | } | |
40 | } | |
41 | ||
42 | # XXX-INGY Do we really need freeze and thaw? | |
43 | # XXX-XDG I don't think so. I'd support deprecating them. | |
7 | 44 | BEGIN { |
8 | if ( HAVE_UTF8 ) { | |
9 | # The string eval helps hide this from Test::MinimumVersion | |
10 | eval "require utf8;"; | |
11 | die "Failed to load UTF-8 support" if $@; | |
12 | } | |
13 | ||
14 | # Class structure | |
15 | require 5.004; | |
16 | require Exporter; | |
17 | require Carp; | |
18 | $YAML::Tiny::VERSION = '1.51'; | |
19 | # $YAML::Tiny::VERSION = eval $YAML::Tiny::VERSION; | |
20 | @YAML::Tiny::ISA = qw{ Exporter }; | |
21 | @YAML::Tiny::EXPORT = qw{ Load Dump }; | |
22 | @YAML::Tiny::EXPORT_OK = qw{ LoadFile DumpFile freeze thaw }; | |
23 | ||
24 | # Error storage | |
25 | $YAML::Tiny::errstr = ''; | |
26 | } | |
27 | ||
28 | # The character class of all characters we need to escape | |
29 | # NOTE: Inlined, since it's only used once | |
30 | # my $RE_ESCAPE = '[\\x00-\\x08\\x0b-\\x0d\\x0e-\\x1f\"\n]'; | |
45 | *freeze = \&Dump; | |
46 | *thaw = \&Load; | |
47 | } | |
48 | ||
49 | sub DumpFile { | |
50 | my $file = shift; | |
51 | return YAML::Tiny->new(@_)->_dump_file($file); | |
52 | } | |
53 | ||
54 | sub LoadFile { | |
55 | my $file = shift; | |
56 | my $self = YAML::Tiny->_load_file($file); | |
57 | if ( wantarray ) { | |
58 | return @$self; | |
59 | } else { | |
60 | # Return only the last document to match YAML.pm, | |
61 | return $self->[-1]; | |
62 | } | |
63 | } | |
64 | ||
65 | ||
66 | ### | |
67 | # Object Oriented API: | |
68 | ||
69 | # Create an empty YAML::Tiny object | |
70 | # XXX-INGY Why do we use ARRAY object? | |
71 | # NOTE: I get it now, but I think it's confusing and not needed. | |
72 | # Will change it on a branch later, for review. | |
73 | # | |
74 | # XXX-XDG I don't support changing it yet. It's a very well-documented | |
75 | # "API" of YAML::Tiny. I'd support deprecating it, but Adam suggested | |
76 | # we not change it until YAML.pm's own OO API is established so that | |
77 | # users only have one API change to digest, not two | |
78 | sub new { | |
79 | my $class = shift; | |
80 | bless [ @_ ], $class; | |
81 | } | |
82 | ||
83 | # XXX-INGY It probably doesn't matter, and it's probably too late to | |
84 | # change, but 'read/write' are the wrong names. Read and Write | |
85 | # are actions that take data from storage to memory | |
86 | # characters/strings. These take the data to/from storage to native | |
87 | # Perl objects, which the terms dump and load are meant. As long as | |
88 | # this is a legacy quirk to YAML::Tiny it's ok, but I'd prefer not | |
89 | # to add new {read,write}_* methods to this API. | |
90 | ||
91 | sub read_string { | |
92 | my $self = shift; | |
93 | $self->_load_string(@_); | |
94 | } | |
95 | ||
96 | sub write_string { | |
97 | my $self = shift; | |
98 | $self->_dump_string(@_); | |
99 | } | |
100 | ||
101 | sub read { | |
102 | my $self = shift; | |
103 | $self->_load_file(@_); | |
104 | } | |
105 | ||
106 | sub write { | |
107 | my $self = shift; | |
108 | $self->_dump_file(@_); | |
109 | } | |
110 | ||
111 | ||
112 | ||
113 | ||
114 | ##################################################################### | |
115 | # Constants | |
31 | 116 | |
32 | 117 | # Printed form of the unprintable characters in the lowest range |
33 | 118 | # of ASCII characters, listed by ASCII ordinal position. |
34 | 119 | my @UNPRINTABLE = qw( |
35 | z x01 x02 x03 x04 x05 x06 a | |
36 | x08 t n v f r x0e x0f | |
37 | x10 x11 x12 x13 x14 x15 x16 x17 | |
38 | x18 x19 x1a e x1c x1d x1e x1f | |
120 | 0 x01 x02 x03 x04 x05 x06 a | |
121 | b t n v f r x0E x0F | |
122 | x10 x11 x12 x13 x14 x15 x16 x17 | |
123 | x18 x19 x1A e x1C x1D x1E x1F | |
39 | 124 | ); |
40 | 125 | |
41 | 126 | # Printable characters for escapes |
42 | 127 | my %UNESCAPES = ( |
43 | z => "\x00", a => "\x07", t => "\x09", | |
44 | n => "\x0a", v => "\x0b", f => "\x0c", | |
45 | r => "\x0d", e => "\x1b", '\\' => '\\', | |
128 | 0 => "\x00", z => "\x00", N => "\x85", | |
129 | a => "\x07", b => "\x08", t => "\x09", | |
130 | n => "\x0a", v => "\x0b", f => "\x0c", | |
131 | r => "\x0d", e => "\x1b", '\\' => '\\', | |
46 | 132 | ); |
47 | 133 | |
48 | # Special magic boolean words | |
134 | # XXX-INGY | |
135 | # I(ngy) need to decide if these values should be quoted in | |
136 | # YAML::Tiny or not. Probably yes. | |
137 | ||
138 | # These 3 values have special meaning when unquoted and using the | |
139 | # default YAML schema. They need quotes if they are strings. | |
49 | 140 | my %QUOTE = map { $_ => 1 } qw{ |
50 | null Null NULL | |
51 | y Y yes Yes YES n N no No NO | |
52 | true True TRUE false False FALSE | |
53 | on On ON off Off OFF | |
141 | null true false | |
54 | 142 | }; |
55 | 143 | |
144 | # The commented out form is simpler, but overloaded the Perl regex | |
145 | # engine due to recursion and backtracking problems on strings | |
146 | # larger than 32,000ish characters. Keep it for reference purposes. | |
147 | # qr/\"((?:\\.|[^\"])*)\"/ | |
148 | my $re_capture_double_quoted = qr/\"([^\\"]*(?:\\.[^\\"]*)*)\"/; | |
149 | my $re_capture_single_quoted = qr/\'([^\']*(?:\'\'[^\']*)*)\'/; | |
150 | # unquoted re gets trailing space that needs to be stripped | |
151 | my $re_capture_unquoted_key = qr/([^:]+(?::+\S(?:[^:]*|.*?(?=:)))*)(?=\s*\:(?:\s+|$))/; | |
152 | my $re_trailing_comment = qr/(?:\s+\#.*)?/; | |
153 | my $re_key_value_separator = qr/\s*:(?:\s+(?:\#.*)?|$)/; | |
154 | ||
56 | 155 | |
57 | 156 | |
58 | 157 | |
59 | 158 | |
60 | 159 | ##################################################################### |
61 | # Implementation | |
62 | ||
63 | # Create an empty YAML::Tiny object | |
64 | sub new { | |
65 | my $class = shift; | |
66 | bless [ @_ ], $class; | |
67 | } | |
160 | # YAML::Tiny Implementation. | |
161 | # | |
162 | # These are the private methods that do all the work. They may change | |
163 | # at any time. | |
164 | ||
165 | ||
166 | ### | |
167 | # Loader functions: | |
68 | 168 | |
69 | 169 | # Create an object from a file |
70 | sub read { | |
71 | my $class = ref $_[0] ? ref shift : shift; | |
72 | ||
73 | # Check the file | |
74 | my $file = shift or return $class->_error( 'You did not specify a file name' ); | |
75 | return $class->_error( "File '$file' does not exist" ) unless -e $file; | |
76 | return $class->_error( "'$file' is a directory, not a file" ) unless -f _; | |
77 | return $class->_error( "Insufficient permissions to read '$file'" ) unless -r _; | |
78 | ||
79 | # Slurp in the file | |
80 | local $/ = undef; | |
81 | local *CFG; | |
82 | unless ( open(CFG, $file) ) { | |
83 | return $class->_error("Failed to open file '$file': $!"); | |
84 | } | |
85 | my $contents = <CFG>; | |
86 | unless ( close(CFG) ) { | |
87 | return $class->_error("Failed to close file '$file': $!"); | |
88 | } | |
89 | ||
90 | $class->read_string( $contents ); | |
170 | sub _load_file { | |
171 | my $class = ref $_[0] ? ref shift : shift; | |
172 | ||
173 | # Check the file | |
174 | my $file = shift or $class->_error( 'You did not specify a file name' ); | |
175 | $class->_error( "File '$file' does not exist" ) | |
176 | unless -e $file; | |
177 | $class->_error( "'$file' is a directory, not a file" ) | |
178 | unless -f _; | |
179 | $class->_error( "Insufficient permissions to read '$file'" ) | |
180 | unless -r _; | |
181 | ||
182 | # Open unbuffered with strict UTF-8 decoding and no translation layers | |
183 | open( my $fh, "<:unix:encoding(UTF-8)", $file ); | |
184 | unless ( $fh ) { | |
185 | $class->_error("Failed to open file '$file': $!"); | |
186 | } | |
187 | ||
188 | # flock if available (or warn if not possible for OS-specific reasons) | |
189 | if ( _can_flock() ) { | |
190 | flock( $fh, Fcntl::LOCK_SH() ) | |
191 | or warn "Couldn't lock '$file' for reading: $!"; | |
192 | } | |
193 | ||
194 | # slurp the contents | |
195 | my $contents = eval { | |
196 | use warnings FATAL => 'utf8'; | |
197 | local $/; | |
198 | <$fh> | |
199 | }; | |
200 | if ( my $err = $@ ) { | |
201 | $class->_error("Error reading from file '$file': $err"); | |
202 | } | |
203 | ||
204 | # close the file (release the lock) | |
205 | unless ( close $fh ) { | |
206 | $class->_error("Failed to close file '$file': $!"); | |
207 | } | |
208 | ||
209 | $class->_load_string( $contents ); | |
91 | 210 | } |
92 | 211 | |
93 | 212 | # Create an object from a string |
94 | sub read_string { | |
95 | my $class = ref $_[0] ? ref shift : shift; | |
96 | my $self = bless [], $class; | |
97 | my $string = $_[0]; | |
98 | eval { | |
99 | unless ( defined $string ) { | |
100 | die \"Did not provide a string to load"; | |
101 | } | |
102 | ||
103 | # Byte order marks | |
104 | # NOTE: Keeping this here to educate maintainers | |
105 | # my %BOM = ( | |
106 | # "\357\273\277" => 'UTF-8', | |
107 | # "\376\377" => 'UTF-16BE', | |
108 | # "\377\376" => 'UTF-16LE', | |
109 | # "\377\376\0\0" => 'UTF-32LE' | |
110 | # "\0\0\376\377" => 'UTF-32BE', | |
111 | # ); | |
112 | if ( $string =~ /^(?:\376\377|\377\376|\377\376\0\0|\0\0\376\377)/ ) { | |
113 | die \"Stream has a non UTF-8 BOM"; | |
114 | } else { | |
115 | # Strip UTF-8 bom if found, we'll just ignore it | |
116 | $string =~ s/^\357\273\277//; | |
117 | } | |
118 | ||
119 | # Try to decode as utf8 | |
120 | utf8::decode($string) if HAVE_UTF8; | |
121 | ||
122 | # Check for some special cases | |
123 | return $self unless length $string; | |
124 | unless ( $string =~ /[\012\015]+\z/ ) { | |
125 | die \"Stream does not end with newline character"; | |
126 | } | |
127 | ||
128 | # Split the file into lines | |
129 | my @lines = grep { ! /^\s*(?:\#.*)?\z/ } | |
130 | split /(?:\015{1,2}\012|\015|\012)/, $string; | |
131 | ||
132 | # Strip the initial YAML header | |
133 | @lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines; | |
134 | ||
135 | # A nibbling parser | |
136 | while ( @lines ) { | |
137 | # Do we have a document header? | |
138 | if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) { | |
139 | # Handle scalar documents | |
140 | shift @lines; | |
141 | if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) { | |
142 | push @$self, $self->_read_scalar( "$1", [ undef ], \@lines ); | |
143 | next; | |
144 | } | |
145 | } | |
146 | ||
147 | if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) { | |
148 | # A naked document | |
149 | push @$self, undef; | |
150 | while ( @lines and $lines[0] !~ /^---/ ) { | |
151 | shift @lines; | |
152 | } | |
153 | ||
154 | } elsif ( $lines[0] =~ /^\s*\-/ ) { | |
155 | # An array at the root | |
156 | my $document = [ ]; | |
157 | push @$self, $document; | |
158 | $self->_read_array( $document, [ 0 ], \@lines ); | |
159 | ||
160 | } elsif ( $lines[0] =~ /^(\s*)\S/ ) { | |
161 | # A hash at the root | |
162 | my $document = { }; | |
163 | push @$self, $document; | |
164 | $self->_read_hash( $document, [ length($1) ], \@lines ); | |
165 | ||
166 | } else { | |
167 | die \"YAML::Tiny failed to classify the line '$lines[0]'"; | |
168 | } | |
169 | } | |
170 | }; | |
171 | if ( ref $@ eq 'SCALAR' ) { | |
172 | return $self->_error(${$@}); | |
173 | } elsif ( $@ ) { | |
174 | require Carp; | |
175 | Carp::croak($@); | |
176 | } | |
177 | ||
178 | return $self; | |
179 | } | |
180 | ||
181 | # Deparse a scalar string to the actual scalar | |
182 | sub _read_scalar { | |
183 | my ($self, $string, $indent, $lines) = @_; | |
184 | ||
185 | # Trim trailing whitespace | |
186 | $string =~ s/\s*\z//; | |
187 | ||
188 | # Explitic null/undef | |
189 | return undef if $string eq '~'; | |
190 | ||
191 | # Single quote | |
192 | if ( $string =~ /^\'(.*?)\'(?:\s+\#.*)?\z/ ) { | |
193 | return '' unless defined $1; | |
194 | $string = $1; | |
195 | $string =~ s/\'\'/\'/g; | |
196 | return $string; | |
197 | } | |
198 | ||
199 | # Double quote. | |
200 | # The commented out form is simpler, but overloaded the Perl regex | |
201 | # engine due to recursion and backtracking problems on strings | |
202 | # larger than 32,000ish characters. Keep it for reference purposes. | |
203 | # if ( $string =~ /^\"((?:\\.|[^\"])*)\"\z/ ) { | |
204 | if ( $string =~ /^\"([^\\"]*(?:\\.[^\\"]*)*)\"(?:\s+\#.*)?\z/ ) { | |
205 | # Reusing the variable is a little ugly, | |
206 | # but avoids a new variable and a string copy. | |
207 | $string = $1; | |
208 | $string =~ s/\\"/"/g; | |
209 | $string =~ s/\\([never\\fartz]|x([0-9a-fA-F]{2}))/(length($1)>1)?pack("H2",$2):$UNESCAPES{$1}/gex; | |
210 | return $string; | |
211 | } | |
212 | ||
213 | # Special cases | |
214 | if ( $string =~ /^[\'\"!&]/ ) { | |
215 | die \"YAML::Tiny does not support a feature in line '$string'"; | |
216 | } | |
217 | return {} if $string =~ /^{}(?:\s+\#.*)?\z/; | |
218 | return [] if $string =~ /^\[\](?:\s+\#.*)?\z/; | |
219 | ||
220 | # Regular unquoted string | |
221 | if ( $string !~ /^[>|]/ ) { | |
222 | if ( | |
223 | $string =~ /^(?:-(?:\s|$)|[\@\%\`])/ | |
224 | or | |
225 | $string =~ /:(?:\s|$)/ | |
226 | ) { | |
227 | die \"YAML::Tiny found illegal characters in plain scalar: '$string'"; | |
228 | } | |
229 | $string =~ s/\s+#.*\z//; | |
230 | return $string; | |
231 | } | |
232 | ||
233 | # Error | |
234 | die \"YAML::Tiny failed to find multi-line scalar content" unless @$lines; | |
235 | ||
236 | # Check the indent depth | |
237 | $lines->[0] =~ /^(\s*)/; | |
238 | $indent->[-1] = length("$1"); | |
239 | if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) { | |
240 | die \"YAML::Tiny found bad indenting in line '$lines->[0]'"; | |
241 | } | |
242 | ||
243 | # Pull the lines | |
244 | my @multiline = (); | |
245 | while ( @$lines ) { | |
246 | $lines->[0] =~ /^(\s*)/; | |
247 | last unless length($1) >= $indent->[-1]; | |
248 | push @multiline, substr(shift(@$lines), length($1)); | |
249 | } | |
250 | ||
251 | my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n"; | |
252 | my $t = (substr($string, 1, 1) eq '-') ? '' : "\n"; | |
253 | return join( $j, @multiline ) . $t; | |
254 | } | |
255 | ||
256 | # Parse an array | |
257 | sub _read_array { | |
258 | my ($self, $array, $indent, $lines) = @_; | |
259 | ||
260 | while ( @$lines ) { | |
261 | # Check for a new document | |
262 | if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) { | |
263 | while ( @$lines and $lines->[0] !~ /^---/ ) { | |
264 | shift @$lines; | |
265 | } | |
266 | return 1; | |
267 | } | |
268 | ||
269 | # Check the indent level | |
270 | $lines->[0] =~ /^(\s*)/; | |
271 | if ( length($1) < $indent->[-1] ) { | |
272 | return 1; | |
273 | } elsif ( length($1) > $indent->[-1] ) { | |
274 | die \"YAML::Tiny found bad indenting in line '$lines->[0]'"; | |
275 | } | |
276 | ||
277 | if ( $lines->[0] =~ /^(\s*\-\s+)[^\'\"]\S*\s*:(?:\s+|$)/ ) { | |
278 | # Inline nested hash | |
279 | my $indent2 = length("$1"); | |
280 | $lines->[0] =~ s/-/ /; | |
281 | push @$array, { }; | |
282 | $self->_read_hash( $array->[-1], [ @$indent, $indent2 ], $lines ); | |
283 | ||
284 | } elsif ( $lines->[0] =~ /^\s*\-(\s*)(.+?)\s*\z/ ) { | |
285 | # Array entry with a value | |
286 | shift @$lines; | |
287 | push @$array, $self->_read_scalar( "$2", [ @$indent, undef ], $lines ); | |
288 | ||
289 | } elsif ( $lines->[0] =~ /^\s*\-\s*\z/ ) { | |
290 | shift @$lines; | |
291 | unless ( @$lines ) { | |
292 | push @$array, undef; | |
293 | return 1; | |
294 | } | |
295 | if ( $lines->[0] =~ /^(\s*)\-/ ) { | |
296 | my $indent2 = length("$1"); | |
297 | if ( $indent->[-1] == $indent2 ) { | |
298 | # Null array entry | |
299 | push @$array, undef; | |
300 | } else { | |
301 | # Naked indenter | |
302 | push @$array, [ ]; | |
303 | $self->_read_array( $array->[-1], [ @$indent, $indent2 ], $lines ); | |
304 | } | |
305 | ||
306 | } elsif ( $lines->[0] =~ /^(\s*)\S/ ) { | |
307 | push @$array, { }; | |
308 | $self->_read_hash( $array->[-1], [ @$indent, length("$1") ], $lines ); | |
309 | ||
310 | } else { | |
311 | die \"YAML::Tiny failed to classify line '$lines->[0]'"; | |
312 | } | |
313 | ||
314 | } elsif ( defined $indent->[-2] and $indent->[-1] == $indent->[-2] ) { | |
315 | # This is probably a structure like the following... | |
316 | # --- | |
317 | # foo: | |
318 | # - list | |
319 | # bar: value | |
320 | # | |
321 | # ... so lets return and let the hash parser handle it | |
322 | return 1; | |
323 | ||
324 | } else { | |
325 | die \"YAML::Tiny failed to classify line '$lines->[0]'"; | |
326 | } | |
327 | } | |
328 | ||
329 | return 1; | |
330 | } | |
331 | ||
332 | # Parse an array | |
333 | sub _read_hash { | |
334 | my ($self, $hash, $indent, $lines) = @_; | |
335 | ||
336 | while ( @$lines ) { | |
337 | # Check for a new document | |
338 | if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) { | |
339 | while ( @$lines and $lines->[0] !~ /^---/ ) { | |
340 | shift @$lines; | |
341 | } | |
342 | return 1; | |
343 | } | |
344 | ||
345 | # Check the indent level | |
346 | $lines->[0] =~ /^(\s*)/; | |
347 | if ( length($1) < $indent->[-1] ) { | |
348 | return 1; | |
349 | } elsif ( length($1) > $indent->[-1] ) { | |
350 | die \"YAML::Tiny found bad indenting in line '$lines->[0]'"; | |
351 | } | |
352 | ||
353 | # Get the key | |
354 | unless ( $lines->[0] =~ s/^\s*([^\'\" ][^\n]*?)\s*:(\s+(?:\#.*)?|$)// ) { | |
355 | if ( $lines->[0] =~ /^\s*[?\'\"]/ ) { | |
356 | die \"YAML::Tiny does not support a feature in line '$lines->[0]'"; | |
357 | } | |
358 | die \"YAML::Tiny failed to classify line '$lines->[0]'"; | |
359 | } | |
360 | my $key = $1; | |
361 | ||
362 | # Do we have a value? | |
363 | if ( length $lines->[0] ) { | |
364 | # Yes | |
365 | $hash->{$key} = $self->_read_scalar( shift(@$lines), [ @$indent, undef ], $lines ); | |
366 | } else { | |
367 | # An indent | |
368 | shift @$lines; | |
369 | unless ( @$lines ) { | |
370 | $hash->{$key} = undef; | |
371 | return 1; | |
372 | } | |
373 | if ( $lines->[0] =~ /^(\s*)-/ ) { | |
374 | $hash->{$key} = []; | |
375 | $self->_read_array( $hash->{$key}, [ @$indent, length($1) ], $lines ); | |
376 | } elsif ( $lines->[0] =~ /^(\s*)./ ) { | |
377 | my $indent2 = length("$1"); | |
378 | if ( $indent->[-1] >= $indent2 ) { | |
379 | # Null hash entry | |
380 | $hash->{$key} = undef; | |
381 | } else { | |
382 | $hash->{$key} = {}; | |
383 | $self->_read_hash( $hash->{$key}, [ @$indent, length($1) ], $lines ); | |
384 | } | |
385 | } | |
386 | } | |
387 | } | |
388 | ||
389 | return 1; | |
390 | } | |
213 | sub _load_string { | |
214 | my $class = ref $_[0] ? ref shift : shift; | |
215 | my $self = bless [], $class; | |
216 | my $string = $_[0]; | |
217 | eval { | |
218 | unless ( defined $string ) { | |
219 | die \"Did not provide a string to load"; | |
220 | } | |
221 | ||
222 | # Check if Perl has it marked as characters, but it's internally | |
223 | # inconsistent. E.g. maybe latin1 got read on a :utf8 layer | |
224 | if ( utf8::is_utf8($string) && ! utf8::valid($string) ) { | |
225 | die \<<'...'; | |
226 | Read an invalid UTF-8 string (maybe mixed UTF-8 and 8-bit character set). | |
227 | Did you decode with lax ":utf8" instead of strict ":encoding(UTF-8)"? | |
228 | ... | |
229 | } | |
230 | ||
231 | # Ensure Unicode character semantics, even for 0x80-0xff | |
232 | utf8::upgrade($string); | |
233 | ||
234 | # Check for and strip any leading UTF-8 BOM | |
235 | $string =~ s/^\x{FEFF}//; | |
236 | ||
237 | # Check for some special cases | |
238 | return $self unless length $string; | |
239 | ||
240 | # Split the file into lines | |
241 | my @lines = grep { ! /^\s*(?:\#.*)?\z/ } | |
242 | split /(?:\015{1,2}\012|\015|\012)/, $string; | |
243 | ||
244 | # Strip the initial YAML header | |
245 | @lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines; | |
246 | ||
247 | # A nibbling parser | |
248 | my $in_document = 0; | |
249 | while ( @lines ) { | |
250 | # Do we have a document header? | |
251 | if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) { | |
252 | # Handle scalar documents | |
253 | shift @lines; | |
254 | if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) { | |
255 | push @$self, | |
256 | $self->_load_scalar( "$1", [ undef ], \@lines ); | |
257 | next; | |
258 | } | |
259 | $in_document = 1; | |
260 | } | |
261 | ||
262 | if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) { | |
263 | # A naked document | |
264 | push @$self, undef; | |
265 | while ( @lines and $lines[0] !~ /^---/ ) { | |
266 | shift @lines; | |
267 | } | |
268 | $in_document = 0; | |
269 | ||
270 | # XXX The final '-+$' is to look for -- which ends up being an | |
271 | # error later. | |
272 | } elsif ( ! $in_document && @$self ) { | |
273 | # only the first document can be explicit | |
274 | die \"YAML::Tiny failed to classify the line '$lines[0]'"; | |
275 | } elsif ( $lines[0] =~ /^\s*\-(?:\s|$|-+$)/ ) { | |
276 | # An array at the root | |
277 | my $document = [ ]; | |
278 | push @$self, $document; | |
279 | $self->_load_array( $document, [ 0 ], \@lines ); | |
280 | ||
281 | } elsif ( $lines[0] =~ /^(\s*)\S/ ) { | |
282 | # A hash at the root | |
283 | my $document = { }; | |
284 | push @$self, $document; | |
285 | $self->_load_hash( $document, [ length($1) ], \@lines ); | |
286 | ||
287 | } else { | |
288 | # Shouldn't get here. @lines have whitespace-only lines | |
289 | # stripped, and previous match is a line with any | |
290 | # non-whitespace. So this clause should only be reachable via | |
291 | # a perlbug where \s is not symmetric with \S | |
292 | ||
293 | # uncoverable statement | |
294 | die \"YAML::Tiny failed to classify the line '$lines[0]'"; | |
295 | } | |
296 | } | |
297 | }; | |
298 | my $err = $@; | |
299 | if ( ref $err eq 'SCALAR' ) { | |
300 | $self->_error(${$err}); | |
301 | } elsif ( $err ) { | |
302 | $self->_error($err); | |
303 | } | |
304 | ||
305 | return $self; | |
306 | } | |
307 | ||
308 | sub _unquote_single { | |
309 | my ($self, $string) = @_; | |
310 | return '' unless length $string; | |
311 | $string =~ s/\'\'/\'/g; | |
312 | return $string; | |
313 | } | |
314 | ||
315 | sub _unquote_double { | |
316 | my ($self, $string) = @_; | |
317 | return '' unless length $string; | |
318 | $string =~ s/\\"/"/g; | |
319 | $string =~ | |
320 | s{\\([Nnever\\fartz0b]|x([0-9a-fA-F]{2}))} | |
321 | {(length($1)>1)?pack("H2",$2):$UNESCAPES{$1}}gex; | |
322 | return $string; | |
323 | } | |
324 | ||
325 | # Load a YAML scalar string to the actual Perl scalar | |
326 | sub _load_scalar { | |
327 | my ($self, $string, $indent, $lines) = @_; | |
328 | ||
329 | # Trim trailing whitespace | |
330 | $string =~ s/\s*\z//; | |
331 | ||
332 | # Explitic null/undef | |
333 | return undef if $string eq '~'; | |
334 | ||
335 | # Single quote | |
336 | if ( $string =~ /^$re_capture_single_quoted$re_trailing_comment\z/ ) { | |
337 | return $self->_unquote_single($1); | |
338 | } | |
339 | ||
340 | # Double quote. | |
341 | if ( $string =~ /^$re_capture_double_quoted$re_trailing_comment\z/ ) { | |
342 | return $self->_unquote_double($1); | |
343 | } | |
344 | ||
345 | # Special cases | |
346 | if ( $string =~ /^[\'\"!&]/ ) { | |
347 | die \"YAML::Tiny does not support a feature in line '$string'"; | |
348 | } | |
349 | return {} if $string =~ /^{}(?:\s+\#.*)?\z/; | |
350 | return [] if $string =~ /^\[\](?:\s+\#.*)?\z/; | |
351 | ||
352 | # Regular unquoted string | |
353 | if ( $string !~ /^[>|]/ ) { | |
354 | die \"YAML::Tiny found illegal characters in plain scalar: '$string'" | |
355 | if $string =~ /^(?:-(?:\s|$)|[\@\%\`])/ or | |
356 | $string =~ /:(?:\s|$)/; | |
357 | $string =~ s/\s+#.*\z//; | |
358 | return $string; | |
359 | } | |
360 | ||
361 | # Error | |
362 | die \"YAML::Tiny failed to find multi-line scalar content" unless @$lines; | |
363 | ||
364 | # Check the indent depth | |
365 | $lines->[0] =~ /^(\s*)/; | |
366 | $indent->[-1] = length("$1"); | |
367 | if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) { | |
368 | die \"YAML::Tiny found bad indenting in line '$lines->[0]'"; | |
369 | } | |
370 | ||
371 | # Pull the lines | |
372 | my @multiline = (); | |
373 | while ( @$lines ) { | |
374 | $lines->[0] =~ /^(\s*)/; | |
375 | last unless length($1) >= $indent->[-1]; | |
376 | push @multiline, substr(shift(@$lines), $indent->[-1]); | |
377 | } | |
378 | ||
379 | my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n"; | |
380 | my $t = (substr($string, 1, 1) eq '-') ? '' : "\n"; | |
381 | return join( $j, @multiline ) . $t; | |
382 | } | |
383 | ||
384 | # Load an array | |
385 | sub _load_array { | |
386 | my ($self, $array, $indent, $lines) = @_; | |
387 | ||
388 | while ( @$lines ) { | |
389 | # Check for a new document | |
390 | if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) { | |
391 | while ( @$lines and $lines->[0] !~ /^---/ ) { | |
392 | shift @$lines; | |
393 | } | |
394 | return 1; | |
395 | } | |
396 | ||
397 | # Check the indent level | |
398 | $lines->[0] =~ /^(\s*)/; | |
399 | if ( length($1) < $indent->[-1] ) { | |
400 | return 1; | |
401 | } elsif ( length($1) > $indent->[-1] ) { | |
402 | die \"YAML::Tiny found bad indenting in line '$lines->[0]'"; | |
403 | } | |
404 | ||
405 | if ( $lines->[0] =~ /^(\s*\-\s+)[^\'\"]\S*\s*:(?:\s+|$)/ ) { | |
406 | # Inline nested hash | |
407 | my $indent2 = length("$1"); | |
408 | $lines->[0] =~ s/-/ /; | |
409 | push @$array, { }; | |
410 | $self->_load_hash( $array->[-1], [ @$indent, $indent2 ], $lines ); | |
411 | ||
412 | } elsif ( $lines->[0] =~ /^\s*\-\s*\z/ ) { | |
413 | shift @$lines; | |
414 | unless ( @$lines ) { | |
415 | push @$array, undef; | |
416 | return 1; | |
417 | } | |
418 | if ( $lines->[0] =~ /^(\s*)\-/ ) { | |
419 | my $indent2 = length("$1"); | |
420 | if ( $indent->[-1] == $indent2 ) { | |
421 | # Null array entry | |
422 | push @$array, undef; | |
423 | } else { | |
424 | # Naked indenter | |
425 | push @$array, [ ]; | |
426 | $self->_load_array( | |
427 | $array->[-1], [ @$indent, $indent2 ], $lines | |
428 | ); | |
429 | } | |
430 | ||
431 | } elsif ( $lines->[0] =~ /^(\s*)\S/ ) { | |
432 | push @$array, { }; | |
433 | $self->_load_hash( | |
434 | $array->[-1], [ @$indent, length("$1") ], $lines | |
435 | ); | |
436 | ||
437 | } else { | |
438 | die \"YAML::Tiny failed to classify line '$lines->[0]'"; | |
439 | } | |
440 | ||
441 | } elsif ( $lines->[0] =~ /^\s*\-(\s*)(.+?)\s*\z/ ) { | |
442 | # Array entry with a value | |
443 | shift @$lines; | |
444 | push @$array, $self->_load_scalar( | |
445 | "$2", [ @$indent, undef ], $lines | |
446 | ); | |
447 | ||
448 | } elsif ( defined $indent->[-2] and $indent->[-1] == $indent->[-2] ) { | |
449 | # This is probably a structure like the following... | |
450 | # --- | |
451 | # foo: | |
452 | # - list | |
453 | # bar: value | |
454 | # | |
455 | # ... so lets return and let the hash parser handle it | |
456 | return 1; | |
457 | ||
458 | } else { | |
459 | die \"YAML::Tiny failed to classify line '$lines->[0]'"; | |
460 | } | |
461 | } | |
462 | ||
463 | return 1; | |
464 | } | |
465 | ||
466 | # Load a hash | |
467 | sub _load_hash { | |
468 | my ($self, $hash, $indent, $lines) = @_; | |
469 | ||
470 | while ( @$lines ) { | |
471 | # Check for a new document | |
472 | if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) { | |
473 | while ( @$lines and $lines->[0] !~ /^---/ ) { | |
474 | shift @$lines; | |
475 | } | |
476 | return 1; | |
477 | } | |
478 | ||
479 | # Check the indent level | |
480 | $lines->[0] =~ /^(\s*)/; | |
481 | if ( length($1) < $indent->[-1] ) { | |
482 | return 1; | |
483 | } elsif ( length($1) > $indent->[-1] ) { | |
484 | die \"YAML::Tiny found bad indenting in line '$lines->[0]'"; | |
485 | } | |
486 | ||
487 | # Find the key | |
488 | my $key; | |
489 | ||
490 | # Quoted keys | |
491 | if ( $lines->[0] =~ | |
492 | s/^\s*$re_capture_single_quoted$re_key_value_separator// | |
493 | ) { | |
494 | $key = $self->_unquote_single($1); | |
495 | } | |
496 | elsif ( $lines->[0] =~ | |
497 | s/^\s*$re_capture_double_quoted$re_key_value_separator// | |
498 | ) { | |
499 | $key = $self->_unquote_double($1); | |
500 | } | |
501 | elsif ( $lines->[0] =~ | |
502 | s/^\s*$re_capture_unquoted_key$re_key_value_separator// | |
503 | ) { | |
504 | $key = $1; | |
505 | $key =~ s/\s+$//; | |
506 | } | |
507 | elsif ( $lines->[0] =~ /^\s*\?/ ) { | |
508 | die \"YAML::Tiny does not support a feature in line '$lines->[0]'"; | |
509 | } | |
510 | else { | |
511 | die \"YAML::Tiny failed to classify line '$lines->[0]'"; | |
512 | } | |
513 | ||
514 | if ( exists $hash->{$key} ) { | |
515 | warn "YAML::Tiny found a duplicate key '$key' in line '$lines->[0]'"; | |
516 | } | |
517 | ||
518 | # Do we have a value? | |
519 | if ( length $lines->[0] ) { | |
520 | # Yes | |
521 | $hash->{$key} = $self->_load_scalar( | |
522 | shift(@$lines), [ @$indent, undef ], $lines | |
523 | ); | |
524 | } else { | |
525 | # An indent | |
526 | shift @$lines; | |
527 | unless ( @$lines ) { | |
528 | $hash->{$key} = undef; | |
529 | return 1; | |
530 | } | |
531 | if ( $lines->[0] =~ /^(\s*)-/ ) { | |
532 | $hash->{$key} = []; | |
533 | $self->_load_array( | |
534 | $hash->{$key}, [ @$indent, length($1) ], $lines | |
535 | ); | |
536 | } elsif ( $lines->[0] =~ /^(\s*)./ ) { | |
537 | my $indent2 = length("$1"); | |
538 | if ( $indent->[-1] >= $indent2 ) { | |
539 | # Null hash entry | |
540 | $hash->{$key} = undef; | |
541 | } else { | |
542 | $hash->{$key} = {}; | |
543 | $self->_load_hash( | |
544 | $hash->{$key}, [ @$indent, length($1) ], $lines | |
545 | ); | |
546 | } | |
547 | } | |
548 | } | |
549 | } | |
550 | ||
551 | return 1; | |
552 | } | |
553 | ||
554 | ||
555 | ### | |
556 | # Dumper functions: | |
391 | 557 | |
392 | 558 | # Save an object to a file |
393 | sub write { | |
394 | my $self = shift; | |
395 | my $file = shift or return $self->_error('No file name provided'); | |
396 | ||
397 | # Write it to the file | |
398 | open( CFG, '>' . $file ) or return $self->_error( | |
399 | "Failed to open file '$file' for writing: $!" | |
400 | ); | |
401 | print CFG $self->write_string; | |
402 | close CFG; | |
403 | ||
404 | return 1; | |
559 | sub _dump_file { | |
560 | my $self = shift; | |
561 | ||
562 | require Fcntl; | |
563 | ||
564 | # Check the file | |
565 | my $file = shift or $self->_error( 'You did not specify a file name' ); | |
566 | ||
567 | my $fh; | |
568 | # flock if available (or warn if not possible for OS-specific reasons) | |
569 | if ( _can_flock() ) { | |
570 | # Open without truncation (truncate comes after lock) | |
571 | my $flags = Fcntl::O_WRONLY()|Fcntl::O_CREAT(); | |
572 | sysopen( $fh, $file, $flags ) | |
573 | or $self->_error("Failed to open file '$file' for writing: $!"); | |
574 | ||
575 | # Use no translation and strict UTF-8 | |
576 | binmode( $fh, ":raw:encoding(UTF-8)"); | |
577 | ||
578 | flock( $fh, Fcntl::LOCK_EX() ) | |
579 | or warn "Couldn't lock '$file' for reading: $!"; | |
580 | ||
581 | # truncate and spew contents | |
582 | truncate $fh, 0; | |
583 | seek $fh, 0, 0; | |
584 | } | |
585 | else { | |
586 | open $fh, ">:unix:encoding(UTF-8)", $file; | |
587 | } | |
588 | ||
589 | # serialize and spew to the handle | |
590 | print {$fh} $self->_dump_string; | |
591 | ||
592 | # close the file (release the lock) | |
593 | unless ( close $fh ) { | |
594 | $self->_error("Failed to close file '$file': $!"); | |
595 | } | |
596 | ||
597 | return 1; | |
405 | 598 | } |
406 | 599 | |
407 | 600 | # Save an object to a string |
408 | sub write_string { | |
409 | my $self = shift; | |
410 | return '' unless @$self; | |
411 | ||
412 | # Iterate over the documents | |
413 | my $indent = 0; | |
414 | my @lines = (); | |
415 | foreach my $cursor ( @$self ) { | |
416 | push @lines, '---'; | |
417 | ||
418 | # An empty document | |
419 | if ( ! defined $cursor ) { | |
420 | # Do nothing | |
421 | ||
422 | # A scalar document | |
423 | } elsif ( ! ref $cursor ) { | |
424 | $lines[-1] .= ' ' . $self->_write_scalar( $cursor, $indent ); | |
425 | ||
426 | # A list at the root | |
427 | } elsif ( ref $cursor eq 'ARRAY' ) { | |
428 | unless ( @$cursor ) { | |
429 | $lines[-1] .= ' []'; | |
430 | next; | |
431 | } | |
432 | push @lines, $self->_write_array( $cursor, $indent, {} ); | |
433 | ||
434 | # A hash at the root | |
435 | } elsif ( ref $cursor eq 'HASH' ) { | |
436 | unless ( %$cursor ) { | |
437 | $lines[-1] .= ' {}'; | |
438 | next; | |
439 | } | |
440 | push @lines, $self->_write_hash( $cursor, $indent, {} ); | |
441 | ||
442 | } else { | |
443 | Carp::croak("Cannot serialize " . ref($cursor)); | |
444 | } | |
445 | } | |
446 | ||
447 | join '', map { "$_\n" } @lines; | |
448 | } | |
449 | ||
450 | sub _write_scalar { | |
451 | my $string = $_[1]; | |
452 | return '~' unless defined $string; | |
453 | return "''" unless length $string; | |
454 | if ( $string =~ /[\x00-\x08\x0b-\x0d\x0e-\x1f\"\'\n]/ ) { | |
455 | $string =~ s/\\/\\\\/g; | |
456 | $string =~ s/"/\\"/g; | |
457 | $string =~ s/\n/\\n/g; | |
458 | $string =~ s/([\x00-\x1f])/\\$UNPRINTABLE[ord($1)]/g; | |
459 | return qq|"$string"|; | |
460 | } | |
461 | if ( $string =~ /(?:^\W|\s|:\z)/ or $QUOTE{$string} ) { | |
462 | return "'$string'"; | |
463 | } | |
464 | return $string; | |
465 | } | |
466 | ||
467 | sub _write_array { | |
468 | my ($self, $array, $indent, $seen) = @_; | |
469 | if ( $seen->{refaddr($array)}++ ) { | |
470 | die "YAML::Tiny does not support circular references"; | |
471 | } | |
472 | my @lines = (); | |
473 | foreach my $el ( @$array ) { | |
474 | my $line = (' ' x $indent) . '-'; | |
475 | my $type = ref $el; | |
476 | if ( ! $type ) { | |
477 | $line .= ' ' . $self->_write_scalar( $el, $indent + 1 ); | |
478 | push @lines, $line; | |
479 | ||
480 | } elsif ( $type eq 'ARRAY' ) { | |
481 | if ( @$el ) { | |
482 | push @lines, $line; | |
483 | push @lines, $self->_write_array( $el, $indent + 1, $seen ); | |
484 | } else { | |
485 | $line .= ' []'; | |
486 | push @lines, $line; | |
487 | } | |
488 | ||
489 | } elsif ( $type eq 'HASH' ) { | |
490 | if ( keys %$el ) { | |
491 | push @lines, $line; | |
492 | push @lines, $self->_write_hash( $el, $indent + 1, $seen ); | |
493 | } else { | |
494 | $line .= ' {}'; | |
495 | push @lines, $line; | |
496 | } | |
497 | ||
498 | } else { | |
499 | die "YAML::Tiny does not support $type references"; | |
500 | } | |
501 | } | |
502 | ||
503 | @lines; | |
504 | } | |
505 | ||
506 | sub _write_hash { | |
507 | my ($self, $hash, $indent, $seen) = @_; | |
508 | if ( $seen->{refaddr($hash)}++ ) { | |
509 | die "YAML::Tiny does not support circular references"; | |
510 | } | |
511 | my @lines = (); | |
512 | foreach my $name ( sort keys %$hash ) { | |
513 | my $el = $hash->{$name}; | |
514 | my $line = (' ' x $indent) . "$name:"; | |
515 | my $type = ref $el; | |
516 | if ( ! $type ) { | |
517 | $line .= ' ' . $self->_write_scalar( $el, $indent + 1 ); | |
518 | push @lines, $line; | |
519 | ||
520 | } elsif ( $type eq 'ARRAY' ) { | |
521 | if ( @$el ) { | |
522 | push @lines, $line; | |
523 | push @lines, $self->_write_array( $el, $indent + 1, $seen ); | |
524 | } else { | |
525 | $line .= ' []'; | |
526 | push @lines, $line; | |
527 | } | |
528 | ||
529 | } elsif ( $type eq 'HASH' ) { | |
530 | if ( keys %$el ) { | |
531 | push @lines, $line; | |
532 | push @lines, $self->_write_hash( $el, $indent + 1, $seen ); | |
533 | } else { | |
534 | $line .= ' {}'; | |
535 | push @lines, $line; | |
536 | } | |
537 | ||
538 | } else { | |
539 | die "YAML::Tiny does not support $type references"; | |
540 | } | |
541 | } | |
542 | ||
543 | @lines; | |
544 | } | |
601 | sub _dump_string { | |
602 | my $self = shift; | |
603 | return '' unless ref $self && @$self; | |
604 | ||
605 | # Iterate over the documents | |
606 | my $indent = 0; | |
607 | my @lines = (); | |
608 | ||
609 | eval { | |
610 | foreach my $cursor ( @$self ) { | |
611 | push @lines, '---'; | |
612 | ||
613 | # An empty document | |
614 | if ( ! defined $cursor ) { | |
615 | # Do nothing | |
616 | ||
617 | # A scalar document | |
618 | } elsif ( ! ref $cursor ) { | |
619 | $lines[-1] .= ' ' . $self->_dump_scalar( $cursor ); | |
620 | ||
621 | # A list at the root | |
622 | } elsif ( ref $cursor eq 'ARRAY' ) { | |
623 | unless ( @$cursor ) { | |
624 | $lines[-1] .= ' []'; | |
625 | next; | |
626 | } | |
627 | push @lines, $self->_dump_array( $cursor, $indent, {} ); | |
628 | ||
629 | # A hash at the root | |
630 | } elsif ( ref $cursor eq 'HASH' ) { | |
631 | unless ( %$cursor ) { | |
632 | $lines[-1] .= ' {}'; | |
633 | next; | |
634 | } | |
635 | push @lines, $self->_dump_hash( $cursor, $indent, {} ); | |
636 | ||
637 | } else { | |
638 | die \("Cannot serialize " . ref($cursor)); | |
639 | } | |
640 | } | |
641 | }; | |
642 | if ( ref $@ eq 'SCALAR' ) { | |
643 | $self->_error(${$@}); | |
644 | } elsif ( $@ ) { | |
645 | $self->_error($@); | |
646 | } | |
647 | ||
648 | join '', map { "$_\n" } @lines; | |
649 | } | |
650 | ||
651 | sub _has_internal_string_value { | |
652 | my $value = shift; | |
653 | my $b_obj = B::svref_2object(\$value); # for round trip problem | |
654 | return $b_obj->FLAGS & B::SVf_POK(); | |
655 | } | |
656 | ||
657 | sub _dump_scalar { | |
658 | my $string = $_[1]; | |
659 | my $is_key = $_[2]; | |
660 | # Check this before checking length or it winds up looking like a string! | |
661 | my $has_string_flag = _has_internal_string_value($string); | |
662 | return '~' unless defined $string; | |
663 | return "''" unless length $string; | |
664 | if (Scalar::Util::looks_like_number($string)) { | |
665 | # keys and values that have been used as strings get quoted | |
666 | if ( $is_key || $has_string_flag ) { | |
667 | return qq['$string']; | |
668 | } | |
669 | else { | |
670 | return $string; | |
671 | } | |
672 | } | |
673 | if ( $string =~ /[\x00-\x09\x0b-\x0d\x0e-\x1f\x7f-\x9f\'\n]/ ) { | |
674 | $string =~ s/\\/\\\\/g; | |
675 | $string =~ s/"/\\"/g; | |
676 | $string =~ s/\n/\\n/g; | |
677 | $string =~ s/[\x85]/\\N/g; | |
678 | $string =~ s/([\x00-\x1f])/\\$UNPRINTABLE[ord($1)]/g; | |
679 | $string =~ s/([\x7f-\x9f])/'\x' . sprintf("%X",ord($1))/ge; | |
680 | return qq|"$string"|; | |
681 | } | |
682 | if ( $string =~ /(?:^[~!@#%&*|>?:,'"`{}\[\]]|^-+$|\s|:\z)/ or | |
683 | $QUOTE{$string} | |
684 | ) { | |
685 | return "'$string'"; | |
686 | } | |
687 | return $string; | |
688 | } | |
689 | ||
690 | sub _dump_array { | |
691 | my ($self, $array, $indent, $seen) = @_; | |
692 | if ( $seen->{refaddr($array)}++ ) { | |
693 | die \"YAML::Tiny does not support circular references"; | |
694 | } | |
695 | my @lines = (); | |
696 | foreach my $el ( @$array ) { | |
697 | my $line = (' ' x $indent) . '-'; | |
698 | my $type = ref $el; | |
699 | if ( ! $type ) { | |
700 | $line .= ' ' . $self->_dump_scalar( $el ); | |
701 | push @lines, $line; | |
702 | ||
703 | } elsif ( $type eq 'ARRAY' ) { | |
704 | if ( @$el ) { | |
705 | push @lines, $line; | |
706 | push @lines, $self->_dump_array( $el, $indent + 1, $seen ); | |
707 | } else { | |
708 | $line .= ' []'; | |
709 | push @lines, $line; | |
710 | } | |
711 | ||
712 | } elsif ( $type eq 'HASH' ) { | |
713 | if ( keys %$el ) { | |
714 | push @lines, $line; | |
715 | push @lines, $self->_dump_hash( $el, $indent + 1, $seen ); | |
716 | } else { | |
717 | $line .= ' {}'; | |
718 | push @lines, $line; | |
719 | } | |
720 | ||
721 | } else { | |
722 | die \"YAML::Tiny does not support $type references"; | |
723 | } | |
724 | } | |
725 | ||
726 | @lines; | |
727 | } | |
728 | ||
729 | sub _dump_hash { | |
730 | my ($self, $hash, $indent, $seen) = @_; | |
731 | if ( $seen->{refaddr($hash)}++ ) { | |
732 | die \"YAML::Tiny does not support circular references"; | |
733 | } | |
734 | my @lines = (); | |
735 | foreach my $name ( sort keys %$hash ) { | |
736 | my $el = $hash->{$name}; | |
737 | my $line = (' ' x $indent) . $self->_dump_scalar($name, 1) . ":"; | |
738 | my $type = ref $el; | |
739 | if ( ! $type ) { | |
740 | $line .= ' ' . $self->_dump_scalar( $el ); | |
741 | push @lines, $line; | |
742 | ||
743 | } elsif ( $type eq 'ARRAY' ) { | |
744 | if ( @$el ) { | |
745 | push @lines, $line; | |
746 | push @lines, $self->_dump_array( $el, $indent + 1, $seen ); | |
747 | } else { | |
748 | $line .= ' []'; | |
749 | push @lines, $line; | |
750 | } | |
751 | ||
752 | } elsif ( $type eq 'HASH' ) { | |
753 | if ( keys %$el ) { | |
754 | push @lines, $line; | |
755 | push @lines, $self->_dump_hash( $el, $indent + 1, $seen ); | |
756 | } else { | |
757 | $line .= ' {}'; | |
758 | push @lines, $line; | |
759 | } | |
760 | ||
761 | } else { | |
762 | die \"YAML::Tiny does not support $type references"; | |
763 | } | |
764 | } | |
765 | ||
766 | @lines; | |
767 | } | |
768 | ||
769 | ||
770 | ||
771 | ##################################################################### | |
772 | # DEPRECATED API methods: | |
773 | ||
774 | # Error storage (DEPRECATED as of 1.57) | |
775 | our $errstr = ''; | |
545 | 776 | |
546 | 777 | # Set error |
547 | 778 | sub _error { |
548 | $YAML::Tiny::errstr = $_[1]; | |
549 | undef; | |
779 | require Carp; | |
780 | $errstr = $_[1]; | |
781 | $errstr =~ s/ at \S+ line \d+.*//; | |
782 | Carp::croak( $errstr ); | |
550 | 783 | } |
551 | 784 | |
552 | 785 | # Retrieve error |
786 | my $errstr_warned; | |
553 | 787 | sub errstr { |
554 | $YAML::Tiny::errstr; | |
555 | } | |
556 | ||
788 | require Carp; | |
789 | Carp::carp( "YAML::Tiny->errstr and \$YAML::Tiny::errstr is deprecated" ) | |
790 | unless $errstr_warned++; | |
791 | $errstr; | |
792 | } | |
557 | 793 | |
558 | 794 | |
559 | 795 | |
560 | 796 | |
561 | 797 | ##################################################################### |
562 | # YAML Compatibility | |
563 | ||
564 | sub Dump { | |
565 | YAML::Tiny->new(@_)->write_string; | |
566 | } | |
567 | ||
568 | sub Load { | |
569 | my $self = YAML::Tiny->read_string(@_); | |
570 | unless ( $self ) { | |
571 | Carp::croak("Failed to load YAML document from string"); | |
572 | } | |
573 | if ( wantarray ) { | |
574 | return @$self; | |
575 | } else { | |
576 | # To match YAML.pm, return the last document | |
577 | return $self->[-1]; | |
578 | } | |
579 | } | |
580 | ||
581 | BEGIN { | |
582 | *freeze = *Dump; | |
583 | *thaw = *Load; | |
584 | } | |
585 | ||
586 | sub DumpFile { | |
587 | my $file = shift; | |
588 | YAML::Tiny->new(@_)->write($file); | |
589 | } | |
590 | ||
591 | sub LoadFile { | |
592 | my $self = YAML::Tiny->read($_[0]); | |
593 | unless ( $self ) { | |
594 | Carp::croak("Failed to load YAML document from '" . ($_[0] || '') . "'"); | |
595 | } | |
596 | if ( wantarray ) { | |
597 | return @$self; | |
598 | } else { | |
599 | # Return only the last document to match YAML.pm, | |
600 | return $self->[-1]; | |
601 | } | |
602 | } | |
603 | ||
604 | ||
605 | ||
606 | ||
607 | ||
798 | # Helper functions. Possibly not needed. | |
799 | ||
800 | ||
801 | # Use to detect nv or iv | |
802 | use B; | |
803 | ||
804 | # XXX-INGY Is flock YAML::Tiny's responsibility? | |
805 | # Some platforms can't flock :-( | |
806 | # XXX-XDG I think it is. When reading and writing files, we ought | |
807 | # to be locking whenever possible. People (foolishly) use YAML | |
808 | # files for things like session storage, which has race issues. | |
809 | my $HAS_FLOCK; | |
810 | sub _can_flock { | |
811 | if ( defined $HAS_FLOCK ) { | |
812 | return $HAS_FLOCK; | |
813 | } | |
814 | else { | |
815 | require Config; | |
816 | my $c = \%Config::Config; | |
817 | $HAS_FLOCK = grep { $c->{$_} } qw/d_flock d_fcntl_can_lock d_lockf/; | |
818 | require Fcntl if $HAS_FLOCK; | |
819 | return $HAS_FLOCK; | |
820 | } | |
821 | } | |
822 | ||
823 | ||
824 | # XXX-INGY Is this core in 5.8.1? Can we remove this? | |
825 | # XXX-XDG Scalar::Util 1.18 didn't land until 5.8.8, so we need this | |
608 | 826 | ##################################################################### |
609 | 827 | # Use Scalar::Util if possible, otherwise emulate it |
610 | 828 | |
829 | use Scalar::Util (); | |
611 | 830 | BEGIN { |
612 | local $@; | |
613 | eval { | |
614 | require Scalar::Util; | |
615 | }; | |
616 | my $v = eval("$Scalar::Util::VERSION") || 0; | |
617 | if ( $@ or $v < 1.18 ) { | |
618 | eval <<'END_PERL'; | |
831 | local $@; | |
832 | if ( eval { Scalar::Util->VERSION(1.18); } ) { | |
833 | *refaddr = *Scalar::Util::refaddr; | |
834 | } | |
835 | else { | |
836 | eval <<'END_PERL'; | |
619 | 837 | # Scalar::Util failed to load or too old |
620 | 838 | sub refaddr { |
621 | my $pkg = ref($_[0]) or return undef; | |
622 | if ( !! UNIVERSAL::can($_[0], 'can') ) { | |
623 | bless $_[0], 'Scalar::Util::Fake'; | |
624 | } else { | |
625 | $pkg = undef; | |
626 | } | |
627 | "$_[0]" =~ /0x(\w+)/; | |
628 | my $i = do { local $^W; hex $1 }; | |
629 | bless $_[0], $pkg if defined $pkg; | |
630 | $i; | |
839 | my $pkg = ref($_[0]) or return undef; | |
840 | if ( !! UNIVERSAL::can($_[0], 'can') ) { | |
841 | bless $_[0], 'Scalar::Util::Fake'; | |
842 | } else { | |
843 | $pkg = undef; | |
844 | } | |
845 | "$_[0]" =~ /0x(\w+)/; | |
846 | my $i = do { no warnings 'portable'; hex $1 }; | |
847 | bless $_[0], $pkg if defined $pkg; | |
848 | $i; | |
631 | 849 | } |
632 | 850 | END_PERL |
633 | } else { | |
634 | *refaddr = *Scalar::Util::refaddr; | |
635 | } | |
636 | } | |
851 | } | |
852 | } | |
853 | ||
854 | delete $YAML::Tiny::{refaddr}; | |
637 | 855 | |
638 | 856 | 1; |
639 | 857 | |
858 | # XXX-INGY Doc notes I'm putting up here. Changing the doc when it's wrong | |
859 | # but leaving grey area stuff up here. | |
860 | # | |
861 | # I would like to change Read/Write to Load/Dump below without | |
862 | # changing the actual API names. | |
863 | # | |
864 | # It might be better to put Load/Dump API in the SYNOPSIS instead of the | |
865 | # dubious OO API. | |
866 | # | |
867 | # null and bool explanations may be outdated. | |
868 | ||
640 | 869 | __END__ |
641 | 870 | |
642 | #line 1175 | |
871 | #line 1487 |