diff --git a/Changes b/Changes index 9f19820..456245d 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,8 @@ Revision history for Perl extension PGXN::Manager 0.32.1 + - Updated `doc/spec.txt` to v1.0.1, from it new home in + https://github.com/pgxn/pgxn-meta-spec. 0.32.0 2024-02-17T17:25:24Z - Combined the pgxn_consumer PID number and file location into one diff --git a/doc/spec.txt b/doc/spec.txt index 65ee982..6e1f70c 100644 --- a/doc/spec.txt +++ b/doc/spec.txt @@ -1,93 +1,92 @@ -Name -==== +PGXN Meta Spec +============== -PGXN Meta Spec - The PGXN distribution metadata specification +The PGXN distribution metadata specification Version -======= +------- -1.0.0 +1.0.1 Synopsis -======== - - { - "name": "pgTAP", - "abstract": "Unit testing for PostgreSQL", - "description": "pgTAP is a suite of database functions that make it easy to write TAP-emitting unit tests in psql scripts or xUnit-style test functions.", - "version": "0.2.5", - "maintainer": [ - "David E. Wheeler ", - "pgTAP List " - ], - "license": { - "PostgreSQL": "https://www.postgresql.org/about/licence" - }, - "prereqs": { - "runtime": { - "requires": { - "plpgsql": 0, - "PostgreSQL": "8.0.0" - }, - "recommends": { - "PostgreSQL": "8.4.0" - } - } - }, - "provides": { - "pgtap": { - "file": "sql/pgtap.sql", - "docfile": "doc/pgtap.mmd", - "version": "0.2.4", - "abstract": "Unit testing assertions for PostgreSQL" - }, - "schematap": { - "file": "sql/schematap.sql", - "docfile": "doc/schematap.mmd", - "version": "0.2.4", - "abstract": "Schema testing assertions for PostgreSQL" - } - }, - "resources": { - "homepage": "https://pgtap.org/", - "bugtracker": { - "web": "https://github.com/theory/pgtap/issues" - }, - "repository": { - "url": "https://github.com/theory/pgtap.git", - "web": "https://github.com/theory/pgtap", - "type": "git" - } - }, - "generated_by": "David E. Wheeler", - "meta-spec": { - "version": "1.0.0", - "url": "https://pgxn.org/meta/spec.txt" - }, - "tags": [ - "testing", - "unit testing", - "tap", - "tddd", - "test driven database development" - ] +-------- + +``` json +{ + "name": "pgTAP", + "abstract": "Unit testing for PostgreSQL", + "description": "pgTAP is a suite of database functions that make it easy to write TAP-emitting unit tests in psql scripts or xUnit-style test functions.", + "version": "0.2.5", + "maintainer": [ + "David E. Wheeler ", + "pgTAP List " + ], + "license": { + "PostgreSQL": "https://www.postgresql.org/about/licence" + }, + "prereqs": { + "runtime": { + "requires": { + "plpgsql": 0, + "PostgreSQL": "8.0.0" + }, + "recommends": { + "PostgreSQL": "8.4.0" + } + } + }, + "provides": { + "pgtap": { + "file": "sql/pgtap.sql", + "docfile": "doc/pgtap.mmd", + "version": "0.2.4", + "abstract": "Unit testing assertions for PostgreSQL" + }, + "schematap": { + "file": "sql/schematap.sql", + "docfile": "doc/schematap.mmd", + "version": "0.2.4", + "abstract": "Schema testing assertions for PostgreSQL" } + }, + "resources": { + "homepage": "https://pgtap.org/", + "bugtracker": { + "web": "https://github.com/theory/pgtap/issues" + }, + "repository": { + "url": "https://github.com/theory/pgtap.git", + "web": "https://github.com/theory/pgtap", + "type": "git" + } + }, + "generated_by": "David E. Wheeler", + "meta-spec": { + "version": "1.0.0", + "url": "https://pgxn.org/meta/spec.txt" + }, + "tags": [ + "testing", + "unit testing", + "tap", + "tddd", + "test driven database development" + ] +} +``` Description -=========== +----------- This document describes version 1.0.0 of the PGXN distribution metadata -specification, also known as the “PGXN Meta Spec.” It is formatted using the -[MultiMarkdown](https://fletcherpenney.net/multimarkdown/) variant of -[Markdown](https://daringfireball.net/projects/markdown/), and the canonical -copy may always be found at -[master.pgxn.org/meta/spec.txt](https://master.pgxn.org/meta/spec.txt). A -generated HTML-formatted copy found at [pgxn.org/spec/](https://pgxn.org/spec/) -may also be considered canonical. +specification, also known as the "PGXN Meta Spec." It is formatted using the +[Github Flavored Markdown] variant of [Markdown], and the canonical copy may +always be found at [master.pgxn.org/meta/spec.txt]. A generated HTML-formatted +copy found at [pgxn.org/spec/] may also be considered canonical. This document is stable. Any revisions to this specification for typo -corrections and prose clarifications may be issued as “PGXN Meta Spec -1.0.*x*”. These revisions will never change semantics or add or remove +corrections and prose clarifications may be issued as "PGXN Meta Spec +1.0.*x*". These revisions will never change semantics or add or remove specified behavior. Distribution metadata describe important properties of PGXN distributions. @@ -96,40 +95,40 @@ with this specification and include it with the distribution for use by automated tools that index, examine, package, or install PGXN distributions. Terminology -=========== - -distribution -: The primary object described by the metadata. In the context of this - document it usually refers to a collection of extensions, source code, - utilities, tests, and/or documents that are distributed together for other - developers to use. Examples of distributions are - [`semver`](https://pgxn.org/dist/semver/), - [`pair`](https://pgxn.org/dist/pair/), and - [`pgTAP`](https://pgxn.org/dist/pgTAP/). - -extension -: A reusable library of code contained in a single file or within files - referenced by the [`CREATE EXTENSION` - statement](https://www.postgresql.org/docs/current/static/sql-createextension.html). - Extensions usually contain one or more PostgreSQL objects — such as data - types, functions, and operators — and are often referred to by the name of - a primary object that can be mapped to the file name. For example, one - might refer to `pgTAP` instead of `sql/pgtap.sql`. - -consumer -: Code that reads a metadata file, deserializes it into a data structure in - memory, or interprets a data structure of metadata elements. - -producer -: Code that constructs a metadata data structure, serializes into a - bytestream and/or writes it to disk. - -must, should, may, etc. -: These terms are interpreted as described in [IETF RFC - 2119](https://www.ietf.org/rfc/rfc2119.txt). +----------- + +### distribution + +The primary object described by the metadata. In the context of this document +it usually refers to a collection of extensions, source code, utilities, +tests, and/or documents that are distributed together for other developers to +use. Examples of distributions are [`semver`], [`pair`], and [`pgTAP`]. + +### extension + +A reusable library of code contained in a single file or within files +referenced by the [`CREATE EXTENSION` statement]. Extensions usually contain +one or more PostgreSQL objects --- such as data types, functions, and +operators --- and are often referred to by the name of a primary object that +can be mapped to the file name. For example, one might refer to `pgTAP` +instead of `sql/pgtap.sql`. + +### consumer + +Code that reads a metadata file, deserializes it into a data structure in +memory, or interprets a data structure of metadata elements. + +### producer + +Code that constructs a metadata data structure, serializes into a byte stream +and/or writes it to disk. + +### must, should, may, etc. + +These terms are interpreted as described in [IETF RFC 2119]. Data Types -========== +---------- Fields in the [Structure](#Structure) section describe data elements, each of which has an associated data type as described herein. There are four @@ -137,20 +136,17 @@ primitive types: *Boolean*, *String*, *List*, and *Map*. Other types are subtypes of primitives and define compound data structures or define constraints on the values of a data element. -Boolean -------- +### Boolean A *Boolean* is used to provide a true or false value. It **must** be represented as a defined (not `null`) value. -String ------- +### String A *String* is data element containing a non-zero length sequence of Unicode characters. -List ----- +### List A *List* is an ordered collection of zero or more data elements. Elements of a List may be of mixed types. @@ -162,66 +158,58 @@ JavaScript array. Consumers expecting a List **must** consider a [String](#String) as equivalent to a List of length 1. -Map ---- +### Map -A *Map* is an unordered collection of zero or more data elements (“values”), -indexed by associated [String](#String) elements (“keys”). The Map’s value +A *Map* is an unordered collection of zero or more data elements ("values"), +indexed by associated [String](#String) elements ("keys"). The Map’s value elements may be of mixed types. -License String --------------- +### License String A *License String* is a subtype of [String](#String) with a restricted set of values. Valid values are described in detail in the description of the [license field](#license). -Term ----- +### Term A *Term* is a subtype of [String](#String) that **must** be at least two characters long contain no slash (`/`), backslash (`\`), control, or space characters. -Tag ---- +### Tag A *Tag* is a subtype of [String](#String) that **must** be fewer than 256 characters long contain no slash (`/`), backslash (`\`), control, or space characters. -URI ---- +### URI *URI* is a subtype of [String](#String) containing a Uniform Resource Identifier or Locator. -Version -------- +### Version A *Version* is a subtype of [String](#String) containing a value that describes the version number of extensions or distributions. Restrictions on format are described in detail in the [Version Format](#Version.Format) section. -Version Range -------------- +### Version Range The *Version Range* type is a subtype of [String](#String). It describes a range of Versions that may be present or installed to fulfill prerequisites. It is specified in detail in the [Version Ranges](#Version.Ranges) section. -Structure -========= +### Structure The metadata structure is a data element of type [Map](#Map). This section describes valid keys within the [Map](#Map). Any keys not described in this specification document (whether top-level or within compound data structures described herein) are considered *custom keys* -and **must** begin with an “x” or “X” and be followed by an underscore; i.e. +and **must** begin with an "x" or "X" and be followed by an underscore; i.e.l, they must match the pattern: `/\Ax_/i`. If a custom key refers to a compound -data structure, subkeys within it do not need an “x_” or “X_” prefix. +data structure, subkeys within it do not need an "x_" or "X_" prefix. Consumers of metadata may ignore any or all custom keys. All other keys not described herein are invalid and should be ignored by consumers. Producers @@ -234,7 +222,7 @@ which the definition was modified, whether the key is *required* or are in parentheses, brackets, and braces, respectively. If a data type is a [Map](#Map) or [Map](#Map) subtype, valid subkeys will be -described as well. All examples are represented as [JSON](https://json.org/). +described as well. All examples are represented as [JSON]. - -configure -: The configure phase occurs before any dynamic configuration has been - attempted. Extensions required by the configure phase **must** be +* **configure**: The configure phase occurs before any dynamic configuration + has been attempted. Extensions required by the configure phase **must** be available for use before the distribution building tool has been executed. -build -: The build phase is when the distribution’s source code is compiled (if - necessary) and otherwise made ready for installation. +* **build**: The build phase is when the distribution’s source code is + compiled (if necessary) and otherwise made ready for installation. -test -: The test phase is when the distribution’s automated test suite is run. Any - extension needed only for testing and not for subsequent use should be - listed here. +* **test**: The test phase is when the distribution’s automated test suite + is run. Any extension needed only for testing and not for subsequent use + should be listed here. -runtime -: The runtime phase refers not only to when the distribution’s contents are - installed, but also to its continued use. Any extension that is a - prerequisite for regular use of this distribution should be indicated +* **runtime**: The runtime phase refers not only to when the distribution’s + contents are installed, but also to its continued use. Any extension that + is a prerequisite for regular use of this distribution should be indicated here. -develop -: The develop phase’s prereqs are extensions needed to work on the - distribution’s source code as its maintainer does. These tools might be - needed to build a release tarball, to run maintainer-only tests, or to +* **develop**: The develop phase’s prereqs are extensions needed to work on + the distribution’s source code as its maintainer does. These tools might + be needed to build a release tarball, to run maintainer-only tests, or to perform other tasks related to developing new versions of the distribution. -### Relationships ### - -requires -: These dependencies **must** be installed for proper completion of the - phase. +#### Relationships #### -recommends -: Recommended dependencies are *strongly* encouraged and should be satisfied - except in resource constrained environments. +* **requires**: These dependencies **must** be installed for proper + completion of the phase. -suggests -: These dependencies are optional, but are suggested for enhanced operation - of the described distribution. +* **recommends**: Recommended dependencies are *strongly* encouraged and + should be satisfied except in resource constrained environments. -conflicts +* **suggests**: These dependencies are optional, but are suggested for + enhanced operation of the described distribution. -: These dependencies cannot be installed when the phase is in operation. - This is a very rare situation, and the conflicts relationship should be - used with great caution, or not at all. +* **conflicts**: These dependencies cannot be installed when the phase is in + operation. This is a very rare situation, and the conflicts relationship + should be used with great caution, or not at all. -Merging and Resolving Prerequisites ------------------------------------ +### Merging and Resolving Prerequisites ### Whenever metadata consumers merge prerequisites, they should be merged in a way that preserves the intended semantics of the prerequisite structure. @@ -797,58 +793,72 @@ mappings: Extension | Version | Distribution ------------|---------|------------------ - pgtap | 0.25.0 | pgTAP-0.25.0.zip - schematap | 0.25.0 | pgTAP-0.25.0.zip - functap | 0.18.1 | pgTAP-0.18.1.zip + pgtap | 0.25.0 | pgtap-0.25.0.zip + schematap | 0.25.0 | pgtap-0.25.0.zip + functap | 0.18.1 | pgtap-0.18.1.zip -Note that functap was removed from the pgTAP distribution sometime after -0.18.1. Consider the case where pgTAP 0.25.0 is installed. If a distribution -specified “functap” as a prerequisite, it could result in -`pgTAP-0.18.1.tar.gz` being installed, overwriting any files from -`pgTAP-0.25.0.zip`. +Note that functap was removed from the pgtap distribution sometime after +0.18.1. Consider the case where pgtap 0.25.0 is installed. If a distribution +specified "functap" as a prerequisite, it could result in +`pgtap-0.18.1.tar.gz` being installed, overwriting any files from +`pgtap-0.25.0.zip`. Consumers of metadata **should** test whether prerequisites would result in -installed module files being “downgraded” to an older version and **may** warn +installed module files being "downgraded" to an older version and **may** warn users or ignore the prerequisite that would cause such a result. Serialization -============= +------------- Distribution metadata should be serialized as JSON-encoded data and packaged with distributions as the file `META.json`. Notes For Implementors -====================== - -Comparing Version Numbers -------------------------- - -Following the [Semantic Versioning Spec](https://semver.org/), version numbers -**must** be strictly compared by splitting the [Version](#Version) -string on full stop characters (i.e. “dots”, “periods” or “decimal points”) -and comparing each of the three parts as integers. If an ASCII string has been -appended to the third number, it will be extracted and compared in -ASCII-betical order, and in any event will be considered to be less than an -un-encumbered third integer of the same value. Some examples: - - 0.12.1 < 0.12.2 - 1.42.0 > 1.41.99 - 2.0.0 > 1.999.999 - 2.0.0alpha3 < 2.0.0beta1 - 2.0.0beta < 2.0.0 +---------------------- + +### Comparing Version Numbers ### + +Following the [Semantic Versioning 2.0.0 Spec][semver], version numbers +**must** be strictly compared by splitting the [Version](#Version) string on +full stop characters (i.e. "dots", "periods" or "decimal points") and +comparing each of the three parts as integers. If a dash and prerelease ASCII +string has been appended to the third number, it will be extracted and +compared in ASCII-betical order, and in any event will be considered to be +less than an un-encumbered third integer of the same value. Some examples: + +``` +0.12.1 < 0.12.2 +1.42.0 > 1.41.99 +2.0.0 > 1.999.999 +2.0.0alpha3 < 2.0.0beta1 +2.0.0beta < 2.0.0 +``` See Also -======== +-------- -* [CPAN Meta Spec](https://metacpan.org/pod/CPAN::Meta::Spec) -* [PGXN](https://www.pgxn.org/) -* [JSON](https://json.org/) -* [Semantic Versioning](https://semver.org/) +* [CPAN Meta Spec] +* [PGXN] +* [JSON] +* [Semantic Versioning 2.0.0][semver] Contributors ============ -The PGXN Meta Spec borrows heavily from the [CPAN Meta -Spec](https://metacpan.org/pod/CPAN::Meta::Spec), which was originally -written by Ken Williams in 2003 and has since been updated by Randy Sims, -David Golden, and Ricardo Signes. Ported to PGXN by David E. Wheeler. +The PGXN Meta Spec borrows heavily from the [CPAN Meta Spec], which was +originally written by Ken Williams in 2003 and has since been updated by Randy +Sims, David Golden, and Ricardo Signes. Ported to PGXN by David E. Wheeler. + + [Github Flavored Markdown]: https://github.github.com/gfm/ + [Markdown]: https://daringfireball.net/projects/markdown/ + [master.pgxn.org/meta/spec.txt]: https://master.pgxn.org/meta/spec.txt + [pgxn.org/spec/]: https://pgxn.org/spec/ + [`semver`]: https://pgxn.org/dist/semver/ + [`pair`]: https://pgxn.org/dist/pair/ + [`pgTAP`]: https://pgxn.org/dist/pgtap/ + [`CREATE EXTENSION` statement]: https://www.postgresql.org/docs/current/static/sql-createextension.html + [IETF RFC 2119]: https://www.ietf.org/rfc/rfc2119.txt + [JSON]: https://json.org/ + [semver]: https://semver.org/ + [CPAN Meta Spec]: https://metacpan.org/pod/CPAN::Meta::Spec + [PGXN]: https://pgxn.org/ diff --git a/t/base.t b/t/base.t index 72fd06e..597d191 100644 --- a/t/base.t +++ b/t/base.t @@ -78,7 +78,7 @@ file_contents_is $index, JSON::XS->new->indent->space_after->canonical->encode( # Make sure that spec.txt contains what it ought to. file_contents_like $spec, - qr{PGXN Meta Spec - The PGXN distribution metadata specification}, + qr{The PGXN distribution metadata specification}, "...And $spec should look like the meta spec"; # Make sure they don't get overwritten by subsequent calls to init_root(). @@ -88,7 +88,7 @@ copy 'README.md', $spec; ok $pgxn->init_root, 'Init the root again'; file_exists_ok $index, "$index should still exist"; file_contents_unlike $spec, - qr{PGXN Meta Spec - The PGXN distribution metadata specification}, + qr{The PGXN distribution metadata specification}, "...And $spec should not have been replaced"; # Make sure a newer spec.txt updates the mirror. @@ -96,7 +96,7 @@ my $time = (stat File::Spec->catfile(qw(doc spec.txt)))[9]; utime $time, $time - 5, $spec; ok $pgxn->init_root, 'Init the root once more'; file_contents_like $spec, - qr{PGXN Meta Spec - The PGXN distribution metadata specification}, + qr{The PGXN distribution metadata specification}, "Now $spec should be updated"; ##############################################################################