├── .github └── workflows │ └── main.yml ├── .gitignore ├── .layout ├── Changes ├── LICENCE ├── META6.json ├── README.md ├── lib └── Test │ └── META.rakumod └── t ├── 010-use.t ├── 020-internals.t ├── 030-my-meta.t └── data └── META.info.meta6 /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | test: 11 | strategy: 12 | matrix: 13 | os: 14 | - ubuntu-latest 15 | - macOS-latest 16 | - windows-latest 17 | runs-on: ${{ matrix.os }} 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - uses: Raku/setup-raku@v1 22 | 23 | - name: Raku version 24 | run: raku -v 25 | 26 | - name: Install dependencies 27 | run: zef install --deps-only --/test --test-depends . 28 | 29 | - name: Run tests 30 | run: zef test -v --debug . 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /blib/ 2 | /.build/ 3 | _build/ 4 | cover_db/ 5 | inc/ 6 | Build 7 | !Build/ 8 | Build.bat 9 | .last_cover_stats 10 | /Makefile 11 | /Makefile.old 12 | /MANIFEST.bak 13 | /META.yml 14 | /META.json 15 | /MYMETA.* 16 | nytprof.out 17 | /pm_to_blib 18 | *.o 19 | *.bs 20 | /_eumm/ 21 | .precomp 22 | *.rev-deps 23 | -------------------------------------------------------------------------------- /.layout: -------------------------------------------------------------------------------- 1 | { 2 | "type": "layout", 3 | "children": [ 4 | { 5 | "purpose": null, 6 | "name": "t", 7 | "type": "directory", 8 | "children": [ 9 | { 10 | "purpose": null, 11 | "name": "data", 12 | "children": [ 13 | { 14 | "name": "META.info.meta6", 15 | "type": "file" 16 | } 17 | ], 18 | "type": "directory" 19 | }, 20 | { 21 | "type": "file", 22 | "name": "030-my-meta.t" 23 | }, 24 | { 25 | "name": "020-internals.t", 26 | "type": "file" 27 | }, 28 | { 29 | "type": "file", 30 | "name": "010-use.t" 31 | } 32 | ] 33 | }, 34 | { 35 | "name": "README.md", 36 | "type": "file" 37 | }, 38 | { 39 | "name": "lib", 40 | "type": "directory", 41 | "children": [ 42 | { 43 | "purpose": null, 44 | "name": "Test", 45 | "type": "directory", 46 | "children": [ 47 | { 48 | "name": "META.rakumod", 49 | "type": "file" 50 | } 51 | ] 52 | } 53 | ], 54 | "purpose": null 55 | }, 56 | { 57 | "type": "file", 58 | "name": "META6.json" 59 | }, 60 | { 61 | "type": "file", 62 | "name": "Changes" 63 | }, 64 | { 65 | "name": "LICENCE", 66 | "type": "file" 67 | } 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | v0.0.20 Tue 4 Jul 07:59:32 BST 2023 2 | * Rename library files 3 | v0.0.19 Sun 7 Aug 10:08:15 BST 2022 4 | * Update layout 5 | v0.0.18 Sun 7 Aug 09:48:01 BST 2022 6 | * Upload to zef repository 7 | v0.0.17 Sat 3 Apr 12:46:00 BST 2021 8 | * Spring clean and switch to GH actions 9 | v0.0.16 Mon 4 Mar 20:04:59 GMT 2019 10 | * Remove :api adverb to appease older Rakudi 11 | v0.0.15 Wed 20 Feb 15:56:26 GMT 2019 12 | * Use License::SPDX rather than built in list 13 | * Spring clean and upload to CPAN 14 | v0.0.14 Mon 30 Apr 14:17:31 BST 2018 15 | * Use .add rather than .child on paths 16 | v0.0.13 Wed Aug 30 21:06:10 2017 +0100 17 | * Test the source 18 | v0.0.12 Wed Aug 30 15:28:09 2017 +0100 19 | * Add test for no wildcard version 20 | v0.0.11 Thu Aug 17 10:35:35 2017 +0100 21 | * Support either meta6 or meta-version 22 | v0.0.10 Sat Jul 22 12:48:36 2017 +0100 23 | * Fix version matcher in use 24 | v0.0.9 Thu May 4 20:56:47 2017 +0100 25 | * Test licence 26 | v0.0.8 Tue Dec 20 07:09:48 2016 +0000 27 | * Fixes for lexical use 28 | v0.0.7 Thu Aug 4 21:23:39 2016 +0100 29 | * Up version 30 | v0.0.6 Sun May 1 22:10:55 2016 +0100 31 | * Adjust to new version of META6 32 | v0.0.5 Tue Apr 26 09:56:28 2016 +0100 33 | * Test on Travis OS/x and Appveyor windows 34 | v0.0.4 Thu Mar 24 15:16:45 2016 +0000 35 | * Remove reference to "ufo" in README 36 | v0.0.3 Sun Jan 3 12:56:52 2016 +0000 37 | * Test for no hypen in name Test no v prefix in version literals if meta6 > 0 38 | v0.0.2 Sat Jan 2 19:23:14 2016 +0000 39 | * Test for absolute paths in provides Test for "author" rather than "authors" 40 | 41 | * Add travis 42 | 43 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | The Artistic License 2.0 2 | 3 | Copyright (c) 2015 Jonathan Stowe 4 | 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | This license establishes the terms under which a given free software 11 | Package may be copied, modified, distributed, and/or redistributed. 12 | The intent is that the Copyright Holder maintains some artistic 13 | control over the development of that Package while still keeping the 14 | Package available as open source and free software. 15 | 16 | You are always permitted to make arrangements wholly outside of this 17 | license directly with the Copyright Holder of a given Package. If the 18 | terms of this license do not permit the full use that you propose to 19 | make of the Package, you should contact the Copyright Holder and seek 20 | a different licensing arrangement. 21 | 22 | Definitions 23 | 24 | "Copyright Holder" means the individual(s) or organization(s) 25 | named in the copyright notice for the entire Package. 26 | 27 | "Contributor" means any party that has contributed code or other 28 | material to the Package, in accordance with the Copyright Holder's 29 | procedures. 30 | 31 | "You" and "your" means any person who would like to copy, 32 | distribute, or modify the Package. 33 | 34 | "Package" means the collection of files distributed by the 35 | Copyright Holder, and derivatives of that collection and/or of 36 | those files. A given Package may consist of either the Standard 37 | Version, or a Modified Version. 38 | 39 | "Distribute" means providing a copy of the Package or making it 40 | accessible to anyone else, or in the case of a company or 41 | organization, to others outside of your company or organization. 42 | 43 | "Distributor Fee" means any fee that you charge for Distributing 44 | this Package or providing support for this Package to another 45 | party. It does not mean licensing fees. 46 | 47 | "Standard Version" refers to the Package if it has not been 48 | modified, or has been modified only in ways explicitly requested 49 | by the Copyright Holder. 50 | 51 | "Modified Version" means the Package, if it has been changed, and 52 | such changes were not explicitly requested by the Copyright 53 | Holder. 54 | 55 | "Original License" means this Artistic License as Distributed with 56 | the Standard Version of the Package, in its current version or as 57 | it may be modified by The Perl Foundation in the future. 58 | 59 | "Source" form means the source code, documentation source, and 60 | configuration files for the Package. 61 | 62 | "Compiled" form means the compiled bytecode, object code, binary, 63 | or any other form resulting from mechanical transformation or 64 | translation of the Source form. 65 | 66 | 67 | Permission for Use and Modification Without Distribution 68 | 69 | (1) You are permitted to use the Standard Version and create and use 70 | Modified Versions for any purpose without restriction, provided that 71 | you do not Distribute the Modified Version. 72 | 73 | 74 | Permissions for Redistribution of the Standard Version 75 | 76 | (2) You may Distribute verbatim copies of the Source form of the 77 | Standard Version of this Package in any medium without restriction, 78 | either gratis or for a Distributor Fee, provided that you duplicate 79 | all of the original copyright notices and associated disclaimers. At 80 | your discretion, such verbatim copies may or may not include a 81 | Compiled form of the Package. 82 | 83 | (3) You may apply any bug fixes, portability changes, and other 84 | modifications made available from the Copyright Holder. The resulting 85 | Package will still be considered the Standard Version, and as such 86 | will be subject to the Original License. 87 | 88 | 89 | Distribution of Modified Versions of the Package as Source 90 | 91 | (4) You may Distribute your Modified Version as Source (either gratis 92 | or for a Distributor Fee, and with or without a Compiled form of the 93 | Modified Version) provided that you clearly document how it differs 94 | from the Standard Version, including, but not limited to, documenting 95 | any non-standard features, executables, or modules, and provided that 96 | you do at least ONE of the following: 97 | 98 | (a) make the Modified Version available to the Copyright Holder 99 | of the Standard Version, under the Original License, so that the 100 | Copyright Holder may include your modifications in the Standard 101 | Version. 102 | 103 | (b) ensure that installation of your Modified Version does not 104 | prevent the user installing or running the Standard Version. In 105 | addition, the Modified Version must bear a name that is different 106 | from the name of the Standard Version. 107 | 108 | (c) allow anyone who receives a copy of the Modified Version to 109 | make the Source form of the Modified Version available to others 110 | under 111 | 112 | (i) the Original License or 113 | 114 | (ii) a license that permits the licensee to freely copy, 115 | modify and redistribute the Modified Version using the same 116 | licensing terms that apply to the copy that the licensee 117 | received, and requires that the Source form of the Modified 118 | Version, and of any works derived from it, be made freely 119 | available in that license fees are prohibited but Distributor 120 | Fees are allowed. 121 | 122 | 123 | Distribution of Compiled Forms of the Standard Version 124 | or Modified Versions without the Source 125 | 126 | (5) You may Distribute Compiled forms of the Standard Version without 127 | the Source, provided that you include complete instructions on how to 128 | get the Source of the Standard Version. Such instructions must be 129 | valid at the time of your distribution. If these instructions, at any 130 | time while you are carrying out such distribution, become invalid, you 131 | must provide new instructions on demand or cease further distribution. 132 | If you provide valid instructions or cease distribution within thirty 133 | days after you become aware that the instructions are invalid, then 134 | you do not forfeit any of your rights under this license. 135 | 136 | (6) You may Distribute a Modified Version in Compiled form without 137 | the Source, provided that you comply with Section 4 with respect to 138 | the Source of the Modified Version. 139 | 140 | 141 | Aggregating or Linking the Package 142 | 143 | (7) You may aggregate the Package (either the Standard Version or 144 | Modified Version) with other packages and Distribute the resulting 145 | aggregation provided that you do not charge a licensing fee for the 146 | Package. Distributor Fees are permitted, and licensing fees for other 147 | components in the aggregation are permitted. The terms of this license 148 | apply to the use and Distribution of the Standard or Modified Versions 149 | as included in the aggregation. 150 | 151 | (8) You are permitted to link Modified and Standard Versions with 152 | other works, to embed the Package in a larger work of your own, or to 153 | build stand-alone binary or bytecode versions of applications that 154 | include the Package, and Distribute the result without restriction, 155 | provided the result does not expose a direct interface to the Package. 156 | 157 | 158 | Items That are Not Considered Part of a Modified Version 159 | 160 | (9) Works (including, but not limited to, modules and scripts) that 161 | merely extend or make use of the Package, do not, by themselves, cause 162 | the Package to be a Modified Version. In addition, such works are not 163 | considered parts of the Package itself, and are not subject to the 164 | terms of this license. 165 | 166 | 167 | General Provisions 168 | 169 | (10) Any use, modification, and distribution of the Standard or 170 | Modified Versions is governed by this Artistic License. By using, 171 | modifying or distributing the Package, you accept this license. Do not 172 | use, modify, or distribute the Package, if you do not accept this 173 | license. 174 | 175 | (11) If your Modified Version has been derived from a Modified 176 | Version made by someone other than you, you are nevertheless required 177 | to ensure that your Modified Version complies with the requirements of 178 | this license. 179 | 180 | (12) This license does not grant you the right to use any trademark, 181 | service mark, tradename, or logo of the Copyright Holder. 182 | 183 | (13) This license includes the non-exclusive, worldwide, 184 | free-of-charge patent license to make, have made, use, offer to sell, 185 | sell, import and otherwise transfer the Package with respect to any 186 | patent claims licensable by the Copyright Holder that are necessarily 187 | infringed by the Package. If you institute patent litigation 188 | (including a cross-claim or counterclaim) against any party alleging 189 | that the Package constitutes direct or contributory patent 190 | infringement, then this Artistic License to you shall terminate on the 191 | date that such litigation is filed. 192 | 193 | (14) Disclaimer of Warranty: 194 | THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS 195 | IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED 196 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 197 | NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL 198 | LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL 199 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 200 | DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF 201 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 202 | 203 | -------------------------------------------------------------------------------- /META6.json: -------------------------------------------------------------------------------- 1 | { 2 | "test-depends": [ 3 | "Test" 4 | ], 5 | "build-depends": [ 6 | ], 7 | "meta-version": "1", 8 | "name": "Test::META", 9 | "description": "Test a distributions META file", 10 | "source-url": "https://github.com/jonathanstowe/Test-META.git", 11 | "version": "0.0.20", 12 | "raku": "6.*", 13 | "resources": [ 14 | ], 15 | "tags": [ 16 | "devel", 17 | "meta", 18 | "utils", 19 | "testing" 20 | ], 21 | "provides": { 22 | "Test::META": "lib/Test/META.rakumod" 23 | }, 24 | "support": { 25 | "source": "https://github.com/jonathanstowe/Test-META.git", 26 | "email": "jns+git@gellyfish.co.uk", 27 | "bugtracker": "http://github.com/jonathanstowe/Test-META/issues" 28 | }, 29 | "depends": [ 30 | "Test", 31 | "META6:ver<0.0.24+>", 32 | "URI", 33 | "License::SPDX" 34 | ], 35 | "auth": "zef:jonathanstowe", 36 | "license": "Artistic-2.0", 37 | "api": "1.0", 38 | "authors": [ 39 | "Jonathan Stowe " 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Test::META 2 | 3 | Test that a Raku project has a good and proper META file. 4 | 5 | [![CI](https://github.com/jonathanstowe/Test-META/actions/workflows/main.yml/badge.svg)](https://github.com/jonathanstowe/Test-META/actions/workflows/main.yml) 6 | 7 | ## Synopsis 8 | 9 | This is the actual `t/030-my-meta.t` from this distribution 10 | 11 | ```Perl6 12 | #!raku 13 | 14 | use v6; 15 | use lib 'lib'; 16 | 17 | use Test; 18 | use Test::META; 19 | 20 | plan 1; 21 | 22 | # That's it 23 | meta-ok(); 24 | 25 | 26 | done-testing; 27 | ``` 28 | 29 | 30 | However, you may want to make this test conditional, only run by the 31 | author (e.g. by checking the `AUTHOR_TESTING` environment variable). Also, 32 | regular users of your module will not need Test::META on their system): 33 | 34 | ```Perl6 35 | use v6; 36 | use lib 'lib'; 37 | use Test; 38 | plan 1; 39 | 40 | constant AUTHOR = ?%*ENV; 41 | 42 | if AUTHOR { 43 | require Test::META <&meta-ok>; 44 | meta-ok; 45 | done-testing; 46 | } 47 | else { 48 | skip-rest "Skipping author test"; 49 | exit; 50 | } 51 | ``` 52 | 53 | If you are running under Travis CI you can set the right environment 54 | variable in the YAML. One way to do this is like this: 55 | 56 | ``` 57 | script: 58 | - AUTHOR_TESTING=1 prove -v -e "raku -Ilib" 59 | ``` 60 | 61 | Other continuous integration systems will have a similar facility. 62 | 63 | ## Description 64 | 65 | This provides a simple mechanism for module authors to have some 66 | confidence that they have a working distribution META description 67 | file (as described in [S22](http://design.raku.org/S22.html#META6.json)). 68 | 69 | It exports one subroutine `meta-ok` that runs a single sub-test that 70 | checks that: 71 | 72 | * The META file (either META6.json or META.info) exists 73 | * That the META file can be parsed as valid JSON 74 | * That the attributes marked as "mandatory" are present 75 | * That the files mentioned in the "provides" section are present. 76 | 77 | There are mechanisms that are used internally for testing to override the 78 | location or name of the META file. These can be seen in the test suite 79 | though they are not typically needed. 80 | 81 | ## Installation 82 | 83 | You can install directly with "zef": 84 | 85 | ``` 86 | # Remote installation 87 | $ zef install Test::META 88 | 89 | # From the source directory 90 | $ zef install . 91 | ``` 92 | 93 | ## Support 94 | 95 | Suggestions/patches are welcomed via github at: 96 | 97 | https://github.com/jonathanstowe/Test-META 98 | 99 | If you can think of further tests that could be made, please send a 100 | patch. Bear in mind that the tests for the structure of the META file 101 | and particularly the required fields rely on the implementation of the 102 | module [META6](https://github.com/jonathanstowe/META6) and you may want 103 | to consider changing that instead. 104 | 105 | ## Licence 106 | 107 | This is free software. 108 | 109 | Please see the [LICENCE](LICENCE) for the details. 110 | 111 | © Jonathan Stowe 2015 - 2021 112 | -------------------------------------------------------------------------------- /lib/Test/META.rakumod: -------------------------------------------------------------------------------- 1 | use v6; 2 | 3 | =begin pod 4 | 5 | =head1 NAME 6 | 7 | Test::META - Test that a Raku project has a good and proper META file 8 | 9 | =head1 SYNOPSIS 10 | 11 | This is the actual *t/030-my-meta.t* from this distribution 12 | 13 | =begin code 14 | #!raku 15 | 16 | use v6.c; 17 | 18 | use Test; 19 | use Test::META; 20 | 21 | plan 1; 22 | 23 | # That's it 24 | meta-ok(); 25 | 26 | 27 | done-testing; 28 | =end code 29 | 30 | =head1 DESCRIPTION 31 | 32 | This provides a simple mechanism for module authors to have some 33 | confidence that they have a working distribution META description 34 | file (as described in L.) 35 | 36 | It exports one subroutine *meta-ok* that runs a single sub-test that 37 | checks that: 38 | 39 | =item The META file (either META6.json or META.info) exists 40 | 41 | =item The META file can be parsed as valid JSON 42 | 43 | =item The attributes marked as "mandatory" are present 44 | 45 | =item The files mention in the "provides" section are present. 46 | 47 | =item The authors field is used instead of author 48 | 49 | =item The name attribute doesn't have a hyphen rather than '::' 50 | 51 | =item The version exists and it isn't '*' 52 | 53 | =item If the META6 file specifies a meta-version version greater than 0 that the version strings do not contain a 'v' prefix 54 | 55 | The C takes one optional adverb C<:relaxed-name> that can stop 56 | the name check being a fail if it is intended to be like that. 57 | 58 | There are mechanisms (used internally for testing) to over-ride the 59 | location or name of the META file and these can be seen in the test-suite, 60 | though they won't typically be needed. 61 | 62 | =end pod 63 | 64 | 65 | module Test::META:ver<0.0.17>:auth { 66 | 67 | use Test; 68 | use META6:ver(v0.0.24+); 69 | use License::SPDX; 70 | use URI; 71 | our $TESTING = False; 72 | 73 | sub my-diag(Str() $mess) { 74 | diag $mess unless $TESTING; 75 | } 76 | 77 | sub meta-ok(:$relaxed-name) is export(:DEFAULT) { 78 | subtest { 79 | 80 | my $meta-file = get-meta(); 81 | 82 | if $meta-file.defined and $meta-file.e { 83 | pass "have a META file"; 84 | my $meta; 85 | my Int $seen-vee = 0; 86 | lives-ok { 87 | CONTROL { 88 | when CX::Warn { 89 | if $_.message ~~ /'prefix "v" seen in version string'/ { 90 | $seen-vee++; 91 | $_.resume; 92 | } 93 | } 94 | }; 95 | $meta = META6.new(file => $meta-file); 96 | }, "META parses okay"; 97 | if $meta.defined { 98 | ok check-mandatory($meta), "have all required entries"; 99 | ok check-provides($meta), "'provides' looks sane"; 100 | ok check-authors($meta), "Optional 'authors' and not 'author'"; 101 | ok check-license($meta), "License is correct"; 102 | ok check-name($meta, :$relaxed-name), "name has a '::' rather than a hyphen (if this is intentional please pass :relaxed-name to meta-ok)"; 103 | # this is transitional as the method changed in META6 104 | ok ($meta.?meta6 | $meta.?meta-version ) ~~ Version.new(0) ?? True !! $seen-vee == 0, "no 'v' in version strings (meta-version greater than 0)"; 105 | ok check-version($meta), "version is present and doesn't have an asterisk"; 106 | ok check-sources($meta), "have usable source"; 107 | } 108 | } 109 | else { 110 | flunk "don't have META file"; 111 | } 112 | 113 | }, "Project META file is good"; 114 | } 115 | 116 | our sub get-meta() { 117 | $*META-FILE // do { 118 | my $meta; 119 | for meta-candidates().map({ dist-dir.add($_) }) -> $m { 120 | if $m.e { 121 | $meta = $m; 122 | last; 123 | } 124 | } 125 | $meta; 126 | } 127 | } 128 | 129 | our sub check-mandatory(META6:D $meta --> Bool) { 130 | my Bool $rc = True; 131 | 132 | for $meta.^attributes -> $attr { 133 | if $attr.does(META6::MetaAttribute) { 134 | if $attr.optionality ~~ META6::Mandatory { 135 | if not $attr.get_value($meta).defined { 136 | my $name = $attr.name.substr(2); 137 | $rc = False; 138 | my-diag "required attribute '$name' is not defined"; 139 | } 140 | } 141 | } 142 | } 143 | $rc; 144 | } 145 | 146 | our sub check-provides(META6:D $meta --> Bool) { 147 | my Bool $rc = True; 148 | 149 | for $meta.provides.kv -> $name, $path { 150 | if not dist-dir().add($path).e { 151 | $rc = False; 152 | my-diag "file for '$name' '$path' does not exist"; 153 | } 154 | elsif $path.IO.is-absolute { 155 | $rc = False; 156 | my-diag "file for '$name' '$path' is absolute, it should be relative to the dist directory"; 157 | } 158 | } 159 | 160 | $rc; 161 | } 162 | 163 | our sub check-authors(META6:D $meta --> Bool) { 164 | my Bool $rc = True; 165 | 166 | if $meta.author.defined { 167 | if $meta.authors.elems == 0 { 168 | $rc = False; 169 | my-diag "there is an 'author' field rather than the specified 'authors'"; 170 | } 171 | } 172 | 173 | $rc; 174 | } 175 | 176 | our sub check-license(META6:D $meta --> Bool) { 177 | my Bool $rc = True; 178 | if $meta.license.defined { 179 | my $licence-list = License::SPDX.new; 180 | my $licence = $licence-list.get-license($meta.license ); 181 | if !$licence.defined { 182 | if $meta.license eq any('NOASSERTION', 'NONE') { 183 | my-diag "NOTICE! License is $meta.license(). This is valid, but licenses are prefered."; 184 | $rc = True; 185 | } 186 | elsif $meta.support.license { 187 | my-diag "notice license is “$meta.support.license()’, which isn't a SPDX standardized identifier, but license URL was supplied"; 188 | $rc = True; 189 | } 190 | else { 191 | my-diag qq:to/END/; 192 | license ‘$meta.license()’ is not one of the standardized SPDX license identifiers. 193 | please use use one of the identifiers from https://spdx.org/licenses/ 194 | for the license field or if your license is not on the list, 195 | include a URL to the license text as one of the 'support' keys 196 | in addition to listing its name. 197 | END 198 | $rc = False; 199 | } 200 | } 201 | elsif $licence.is-deprecated-license { 202 | my-diag qq:to/END/; 203 | the licence ‘$meta.license()’ is valid but deprecated, you may want to use another license. 204 | END 205 | } 206 | } 207 | $rc; 208 | } 209 | 210 | our sub check-name(META6:D $meta, :$relaxed-name --> Bool) { 211 | my Bool $rc = True; 212 | 213 | if $meta.name.defined { 214 | if not $relaxed-name { 215 | my Str $name = $meta.name; 216 | if so $name ~~ /\-/ && $name !~~ /\:\:/ { 217 | $rc = False; 218 | } 219 | } 220 | else { 221 | $rc = True; 222 | } 223 | } 224 | else { 225 | $rc = False; 226 | } 227 | 228 | $rc; 229 | } 230 | 231 | our sub check-version(META6:D $meta --> Bool ) { 232 | $meta.version.defined && not any($meta.version.parts) eq "*" 233 | } 234 | 235 | our sub check-sources(META6:D $meta --> Bool ) { 236 | my $src-count = 0; 237 | 238 | for ( $meta.source-url, $meta.support.source ).grep(*.defined) -> $source { 239 | if try URI.new($source) -> $uri { 240 | if $uri.host eq 'github.com' { 241 | if $uri.path ~~ /\.git$/ | /'/archive/' .+? [ '.tar.gz' | '.zip' ] $/ { 242 | $src-count++; 243 | } 244 | else { 245 | my-diag "github source $source needs to end in .git or be a proper release."; 246 | } 247 | } 248 | else { 249 | $src-count++; 250 | } 251 | } 252 | else { 253 | my-diag "source $source is not a valid URI"; 254 | } 255 | } 256 | ?$src-count; 257 | } 258 | 259 | sub meta-candidates() { 260 | @*META-CANDIDATES // ; 261 | } 262 | 263 | sub dist-dir() { 264 | $*DIST-DIR // test-dir().parent; 265 | } 266 | 267 | sub test-dir() { 268 | $*TEST-DIR // $*PROGRAM.parent; 269 | } 270 | } 271 | 272 | # vim: expandtab shiftwidth=4 ft=raku 273 | -------------------------------------------------------------------------------- /t/010-use.t: -------------------------------------------------------------------------------- 1 | #!raku 2 | 3 | use v6; 4 | 5 | use Test; 6 | 7 | use-ok('Test::META', 'Can load "Test::META" ok'); 8 | 9 | done-testing; 10 | # vim: expandtab shiftwidth=4 ft=raku 11 | -------------------------------------------------------------------------------- /t/020-internals.t: -------------------------------------------------------------------------------- 1 | #!raku 2 | 3 | use v6; 4 | 5 | use Test; 6 | 7 | use META6; 8 | use Test::META; 9 | 10 | diag "the following may make some diagnostics from the module itself"; 11 | 12 | $Test::META::TESTING = True; 13 | 14 | lives-ok { Test::META::get-meta() }, "get-meta"; 15 | 16 | { 17 | # non-existent but specified implicitly; 18 | my $*META-FILE = "flurblsleb"; 19 | is Test::META::get-meta(), $*META-FILE, 'gen-meta respects $*META-FILE'; 20 | } 21 | { 22 | my @*META-CANDIDATES = / 23 | ok !Test::META::get-meta().defined, 'get-meta() uses @*META-CANDIDATES'; 24 | 25 | } 26 | { 27 | my $*DIST-DIR = $*PROGRAM.parent.child('data'); 28 | my @*META-CANDIDATES = ; 29 | 30 | ok my $meta = Test::META::get-meta(), "get-meta() with existing file"; 31 | ok $meta.e, "file returned exists"; 32 | is $meta.basename, 'META.info.meta6', "and the file we expected"; 33 | 34 | } 35 | 36 | { 37 | nok Test::META::check-mandatory(META6.new()), "check-mandatory on empty META"; 38 | my $good = META6.new(perl-version => Version.new("6"), version => Version.new("0.0.1"), description => "Test thing", name => "Test::META"); 39 | 40 | ok Test::META::check-mandatory($good), "check-mandatory with all defined"; 41 | } 42 | 43 | { 44 | ok Test::META::check-provides(META6.new()), "check-provides on empty META"; 45 | nok Test::META::check-provides(META6.new(provides => ( 'HH::GG' => 'lib/Boodle',))), "check-provides with bogus provides"; 46 | nok Test::META::check-provides(META6.new(provides => ('Test::META' => '/lib/Test/META.rakumod',))), "check-provides with my own files but absolute path"; 47 | ok Test::META::check-provides(META6.new(provides => ('Test::META' => 'lib/Test/META.rakumod',))), "check-provides with my own files"; 48 | ok Test::META::check-authors(META6.new()), "check-authors no authors"; 49 | ok Test::META::check-authors(META6.new(authors => ["A.U. Thor"])), "check-authors with 'authors'"; 50 | ok Test::META::check-authors(META6.new(authors => ["A.U. Thor"], author => "A.U. Thor")), "check-authors with 'authors' and 'author'"; 51 | nok Test::META::check-authors(META6.new(author => "A.U. Thor")), "check-authors with 'author' only"; 52 | ok Test::META::check-name(META6.new(name => "Test::META")), "check-name with good name"; 53 | nok Test::META::check-name(META6.new(name => "Test-META")), "check-name with bad name"; 54 | ok Test::META::check-name(META6.new(name => "Test-META"), :relaxed-name), "check-name with bad name but :relaxed-name"; 55 | ok Test::META::check-license(META6.new(license => "Artistic-2.0")), "check-license with good license name"; 56 | nok Test::META::check-license(META6.new(license => "Artistic")), "check-license with bad license name"; 57 | ok Test::META::check-license(META6.new( 58 | license => "My Super Cool License", support => META6::Support.new(:license('https://mycoollicense.com/license')) 59 | ) 60 | 61 | ), "check-license with bad license name - but a URL was supplied"; 62 | } 63 | 64 | subtest { 65 | nok Test::META::check-version(META6.new()), "check-version with no version"; 66 | nok Test::META::check-version(META6.new(version => Version.new("*"))), "check-version with plain '*'"; 67 | nok Test::META::check-version(META6.new(version => Version.new("1.1.*"))), "check-version with embedded '*'"; 68 | ok Test::META::check-version(META6.new(version => Version.new('0.0.1'))), "check-version with a good version"; 69 | 70 | }, "check-version"; 71 | 72 | subtest { 73 | nok Test::META::check-sources(META6.new(source-url => 'git@github.com:jonathanstowe/Test-META.git')), "not a valid URI"; 74 | nok Test::META::check-sources(META6.new(source-url => 'git://github.com/jonathanstowe/Test-META')), "git URI must end in git"; 75 | ok Test::META::check-sources(META6.new(source-url => 'http://xeamplw.com/jonathanstowe/Test-META')), "non-git URI needn't must end in git"; 76 | 77 | }, "check-sources"; 78 | 79 | 80 | done-testing; 81 | # vim: expandtab shiftwidth=4 ft=raku 82 | -------------------------------------------------------------------------------- /t/030-my-meta.t: -------------------------------------------------------------------------------- 1 | #!raku 2 | 3 | use v6; 4 | 5 | use Test; 6 | use Test::META; 7 | 8 | plan 1; 9 | 10 | # That's it 11 | meta-ok(); 12 | 13 | 14 | done-testing; 15 | # vim: expandtab shiftwidth=4 ft=raku 16 | -------------------------------------------------------------------------------- /t/data/META.info.meta6: -------------------------------------------------------------------------------- 1 | { 2 | "tags" : [ 3 | "devel", 4 | "meta", 5 | "utils" 6 | ], 7 | "provides" : { 8 | "META6" : "lib/META6.pm" 9 | }, 10 | "test-depends" : [ 11 | "Test" 12 | ], 13 | "emulates" : {}, 14 | "support" : { 15 | "phone" : null, 16 | "source" : "git://github.com/jonathanstowe/META6.git", 17 | "mailinglist" : null, 18 | "email" : null, 19 | "irc" : null, 20 | "bugtracker" : null 21 | }, 22 | "perl" : "6", 23 | "build-depends" : [], 24 | "auth" : "github:jonathanstowe", 25 | "source-url" : "git://github.com/jonathanstowe/META6.git", 26 | "depends" : [ 27 | "JSON::Class" 28 | ], 29 | "production" : false, 30 | "name" : "META6", 31 | "authors" : [ 32 | "Jonathan Stowe " 33 | ], 34 | "version" : "0.0.1", 35 | "license" : "Artistic-2.0", 36 | "resource" : {}, 37 | "superseded-by" : {}, 38 | "description" : "Work with Perl 6 META files", 39 | "excludes" : {}, 40 | "supersedes" : {} 41 | } 42 | --------------------------------------------------------------------------------