Skip to content

Commit

Permalink
qip-0001: QIP process
Browse files Browse the repository at this point in the history
  • Loading branch information
wizeguyy committed Sep 11, 2023
0 parents commit c24f76f
Show file tree
Hide file tree
Showing 9 changed files with 698 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.mediawiki linguist-detectable
19 changes: 19 additions & 0 deletions .github/workflows/github-action-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: GitHub Actions Check
run-name: ${{ github.actor }} Checks 🚀
on: [push, pull_request]
jobs:
Link-Format-Checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: scripts/link-format-chk.sh
Build-Table-Checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: scripts/buildtable.pl >/tmp/table.mediawiki || exit 1
Diff-Checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: scripts/diffcheck.sh
25 changes: 25 additions & 0 deletions README.mediawiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
People wishing to submit QIPs, first should propose their idea to the [https://forum.qu.ai Quai forum] (do <em>not</em> assign a number - read <a href="qip-0001.mediawiki">QIP 1</a> for the full process). After discussion, please open a PR. After copy-editing and acceptance, it will be published here.

We are fairly liberal with approving QIPs, and try not to be too involved in decision making on behalf of the community. The exception is in very rare cases of dispute resolution when a decision is contentious and cannot be agreed upon. In those cases, the conservative option will always be preferred.

Having a QIP here does not make it a formally accepted standard until its status becomes Final or Active.

Those proposing changes should consider that ultimately consent may rest with the consensus of the Quai users.

{| class="wikitable sortable" style="width: auto; text-align: center; font-size: smaller; table-layout: fixed;"
!Number
!Layer
!Title
!Owner
!Type
!Status
|- style="background-color: #cfffcf"
| [[qip-0001.mediawiki|1]]
|
| QIP process
| wizeguyy
| Process
| Active
|}

<!-- IMPORTANT! See the instructions at the top of this page, do NOT JUST add QIPs here! -->
359 changes: 359 additions & 0 deletions qip-0001.mediawiki

Large diffs are not rendered by default.

Binary file added qip-0001/process.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 53 additions & 0 deletions qip-0001/process.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
205 changes: 205 additions & 0 deletions scripts/buildtable.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
#!/usr/bin/perl
use strict;
use warnings;

my $topqip = 9999;
my $include_layer = 1;

my %RequiredFields = (
QIP => undef,
Title => undef,
Author => undef,
'Comments-URI' => undef,
Status => undef,
Type => undef,
Created => undef,
# License => undef, (has exceptions)
);
my %MayHaveMulti = (
Author => undef,
'Comments-URI' => undef,
License => undef,
'License-Code' => undef,
'Post-History' => undef,
);
my %DateField = (
Created => undef,
);
my %EmailField = (
Author => undef,
Editor => undef,
);
my %MiscField = (
'Comments-Summary' => undef,
'Discussions-To' => undef,
'Post-History' => undef,
'Replaces' => undef,
'Requires' => undef,
'Superseded-By' => undef,
);

my %ValidLayer = (
'Consensus (soft fork)' => undef,
'Consensus (hard fork)' => undef,
'Peer Services' => undef,
'API/RPC' => undef,
'Applications' => undef,
);
my %ValidStatus = (
Draft => undef,
Deferred => undef,
Proposed => "background-color: #ffffcf",
Rejected => "background-color: #ffcfcf",
Withdrawn => "background-color: #ffcfcf",
Final => "background-color: #cfffcf",
Active => "background-color: #cfffcf",
Replaced => "background-color: #ffcfcf",
Obsolete => "background-color: #ffcfcf",
);
my %ValidType = (
'Standards Track' => 'Standard',
'Informational' => undef,
'Process' => undef,
);
my %RecommendedLicenses = (
'BSD-2-Clause' => undef,
'BSD-3-Clause' => undef,
'CC0-1.0' => undef,
'GNU-All-Permissive' => undef,
);
my %AcceptableLicenses = (
%RecommendedLicenses,
'Apache-2.0' => undef,
'BSL-1.0' => undef,
'CC-BY-4.0' => undef,
'CC-BY-SA-4.0' => undef,
'MIT' => undef,
'AGPL-3.0' => undef,
'AGPL-3.0+' => undef,
'FDL-1.3' => undef,
'GPL-2.0' => undef,
'GPL-2.0+' => undef,
'LGPL-2.1' => undef,
'LGPL-2.1+' => undef,
);
my %DefinedLicenses = (
%AcceptableLicenses,
'OPL' => undef,
'PD' => undef,
);
my %GrandfatheredPD = map { $_ => undef } qw(9 36 37 38 42 49 50 60 65 67 69 74 80 81 83 90 99 105 107 109 111 112 113 114 122 124 125 126 130 131 132 133 140 141 142 143 144 146 147 150 151 152);
my %TolerateMissingLicense = map { $_ => undef } qw(1 10 11 12 13 14 15 16 21 31 33 34 35 39 43 44 45 47 61 64 68 70 71 72 73 101 102 106 120 121);
my %TolerateTitleTooLong = map { $_ => undef } qw(39 44 45 47 49 60 67 68 69 73 74 75 80 81 99 105 106 109 113 122 126 131 143 145 147 173 327);

my %emails;

my $qipnum = 0;
while (++$qipnum <= $topqip) {
my $fn = sprintf "qip-%04d.mediawiki", $qipnum;
-e $fn || next;
open my $F, "<$fn";
while (<$F> !~ m[^(?:\xef\xbb\xbf)?<pre>$]) {
die "No <pre> in $fn" if eof $F;
}
my %found;
my ($title, $author, $status, $type, $layer);
my ($field, $val);
while (<$F>) {
m[^</pre>$] && last;
if (m[^ ([\w-]+)\: (.*\S)$]) {
$field = $1;
$val = $2;
die "Duplicate $field field in $fn" if exists $found{$field};
die "Too many spaces in $fn" if $val =~ /^\s/;
} elsif (m[^ ( +)(.*\S)$]) {
die "Continuation of non-field in $fn" unless defined $field;
die "Too many spaces in $fn" if length $1 != 2 + length $field;
die "Not allowed for multi-value in $fn" unless exists $MayHaveMulti{$field};
$val = $2;
} else {
die "Bad line in $fn preamble";
}
die "Extra spaces in $fn" if $val =~ /^\s/;
if ($field eq 'QIP') {
die "$fn claims to be QIP $val" if $val ne $qipnum;
} elsif ($field eq 'Title') {
$title = $val;
my $title_len = length($title);
die "$fn has too-long Title ($title_len > 44 char max)" if $title_len > 44 and not exists $TolerateTitleTooLong{$qipnum};
} elsif ($field eq 'Author') {
$val =~ m/^(\S[^<@>]*\S) \<([^@>]*\@[\w.-]+\.\w+)\>$/ or die "Malformed Author line in $fn";
my ($authorname, $authoremail) = ($1, $2);
$authoremail =~ s/(?<=\D)$qipnum(?=\D)/<QIPNUM>/g;
$emails{$authorname}->{$authoremail} = undef;
if (defined $author) {
$author .= ", $authorname";
} else {
$author = $authorname;
}
} elsif ($field eq 'Status') {
if ($qipnum == 38) { # HACK
$val =~ s/\s+\(.*\)$//;
}
die "Invalid status in $fn" unless exists $ValidStatus{$val};
$status = $val;
} elsif ($field eq 'Type') {
die "Invalid type in $fn" unless exists $ValidType{$val};
if (defined $ValidType{$val}) {
$type = $ValidType{$val};
} else {
$type = $val;
}
} elsif ($field eq 'Layer') { # QIP 123
die "Invalid layer $val in $fn" unless exists $ValidLayer{$val};
$layer = $val;
} elsif ($field =~ /^License(?:\-Code)?$/) {
die "Undefined license $val in $fn" unless exists $DefinedLicenses{$val};
if (not $found{$field}) {
die "Unacceptable license $val in $fn" unless exists $AcceptableLicenses{$val} or ($val eq 'PD' and exists $GrandfatheredPD{$qipnum});
}
} elsif ($field eq 'Comments-URI') {
if (not $found{'Comments-URI'}) {
my $first_comments_uri = sprintf('https://github.com/quainetwork/qips/wiki/Comments:QIP-%04d', $qipnum);
die "First Comments-URI must be exactly \"$first_comments_uri\" in $fn" unless $val eq $first_comments_uri;
}
} elsif (exists $DateField{$field}) {
die "Invalid date format in $fn" unless $val =~ /^20\d{2}\-(?:0\d|1[012])\-(?:[012]\d|30|31)$/;
} elsif (exists $EmailField{$field}) {
$val =~ m/^(\S[^<@>]*\S) \<[^@>]*\@[\w.]+\.\w+\>$/ or die "Malformed $field line in $fn";
} elsif (not exists $MiscField{$field}) {
die "Unknown field $field in $fn";
}
++$found{$field};
}
if (not $found{License}) {
die "Missing License in $fn" unless exists $TolerateMissingLicense{$qipnum};
}
for my $field (keys %RequiredFields) {
die "Missing $field in $fn" unless $found{$field};
}
print "|-";
if (defined $ValidStatus{$status}) {
print " style=\"" . $ValidStatus{$status} . "\"";
}
print "\n";
print "| [[${fn}|${qipnum}]]\n";
if ($include_layer) {
if (defined $layer) {
print "| ${layer}\n";
} else {
print "|\n";
}
}
print "| ${title}\n";
print "| ${author}\n";
print "| ${type}\n";
print "| ${status}\n";
close $F;
}
for my $author (sort keys %emails) {
my @emails = sort keys %{$emails{$author}};
my $email_count = @emails;
next unless $email_count > 1;
warn "NOTE: $author has $email_count email addresses: @emails\n";
}
13 changes: 13 additions & 0 deletions scripts/diffcheck.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/after.diff || true
if git checkout HEAD^ && scripts/buildtable.pl >/tmp/table.mediawiki 2>/dev/null; then
diff README.mediawiki /tmp/table.mediawiki | grep '^[<>] |' >/tmp/before.diff || true
newdiff=$(diff -s /tmp/before.diff /tmp/after.diff -u | grep '^+')
if [ -n "$newdiff" ]; then
echo "$newdiff"
exit 1
fi
else
echo 'Cannot build previous commit table for comparison'
fi
23 changes: 23 additions & 0 deletions scripts/link-format-chk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
#
# Copyright (c) 2019 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
# Check wrong mediawiki link format

ECODE=0
FILES=""
for fname in $(git diff --name-only HEAD $(git merge-base HEAD master)); do
if [[ $fname == *.mediawiki ]]; then
GRES=$(grep -n '](http' $fname)
if [ "$GRES" != "" ]; then
if [ $ECODE -eq 0 ]; then
>&2 echo "Github Mediawiki format writes link as [URL text], not as [text](url):"
fi
ECODE=1
echo "- $fname:$GRES"
fi
fi
done
exit $ECODE

0 comments on commit c24f76f

Please sign in to comment.