Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds initial ARC site #1

Merged
merged 3 commits into from
Feb 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: CI
on:
pull_request:
push:
branches:
- main

jobs:
check:
name: CI
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-website-${{ hashFiles('**/Cargo.lock') }}

- name: Install and Build
run: |
cd parser
yarn install
yarn ci
34 changes: 34 additions & 0 deletions .github/workflows/site.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Site
on:
push:
branches:
- main

jobs:
deploy:
name: Site
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-website-${{ hashFiles('**/Cargo.lock') }}

- name: Install and Build
run: |
cd site
yarn install
yarn build
- name: Deploy
uses: JamesIves/[email protected]
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH: gh-pages
FOLDER: site/build
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ARCs
# Aleo Request for Comments (ARCs)

🚨 This repository is under active development. 🚨

Expand Down
10 changes: 10 additions & 0 deletions arc-0000/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
---
arc: 0
title: Template
authors: The Aleo Team <[email protected]>
topic: Meta
status: Living
reviewers: Howard Wu <[email protected]>
created: 2020-02-07
---

## Overview

This file serves as the suggested template for new ARC proposals.
Expand Down
10 changes: 10 additions & 0 deletions arc-0001/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
---
arc: 1
title: ARC Proposal Guidelines
authors: The Aleo Team <[email protected]>
topic: Meta
status: Living
reviewers: Howard Wu <[email protected]>
created: 2020-02-07
---

## Overview

Aleo Request for Comments (ARCs) are protocol-level, network-level, and application-level standards for the Aleo ecosystem.
Expand Down
26 changes: 26 additions & 0 deletions parser/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

**/arcs.json
yarn.lock
25 changes: 25 additions & 0 deletions parser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# parser

## Development

The parser expects each `arc-xxxx/README.md` file to adhere to the following format:
```
---
title: This is a test
description: Once upon a time...
---
# Title
Lorem ipsum...
```

The parser will then parse it into:
```json
{
metadata: {
title: "This is a test",
description: "Once upon a time..."
},
content: "# Title\nLorem ipsum..."
}
```
240 changes: 240 additions & 0 deletions parser/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
const fs = require('fs');
const glob = require("glob");
const parseMD = require('parse-md').default;

/**
* arc: 1
* title: Template
* authors: The Aleo Team <[email protected]>
* topic: Meta
* status: Living
* reviewers: Howard Wu <[email protected]>
* created: 2020-02-07
*/
const requiredMetadata = ['arc', 'title', 'authors', 'topic', 'status', 'reviewers', 'created'];

const topics = ['Meta', 'Protocol', 'Network', 'Application'];

const statuses = ['Idea', 'Draft', 'Active', 'Withdrawn', 'Accepted', 'Rejected', 'Final', 'Deprecated', 'Living'];

// Executes sanity checks for CI.
const ci = () => {
getArcDirectories('..', async (err, list) => {
if (err) {
console.log('Error', err);
process.exit(1);
} else {
for (let i = 0; i < list.length; i++) {
const arcDirectory = list[i];

/**************************** ****************************/
/***************** ADD NEW CI CHECKS HERE ****************/
/**************************** ****************************/

await checkArcReadmeExists(arcDirectory);
await checkArcReadmeContent(arcDirectory);

/**************************** ****************************/
/**************************** ****************************/
/**************************** ****************************/

if (i === list.length - 1) {
console.log("\nAll ARCs are up to standard!\n");
}
}
}
})
}

// Builds pages for site.
const site = () => {
getArcDirectories('..', async (err, list) => {
if (err) {
console.log('Error', err);
process.exit(1);
} else {

let arcs = {};

for (let i = 0; i < list.length; i++) {
const arcDirectory = list[i];

/**************************** ****************************/
/**************** ADD NEW SITE LOGIC HERE ****************/
/**************************** ****************************/

await checkArcReadmeExists(arcDirectory);
await checkArcReadmeContent(arcDirectory);

const { id, metadata, content } = parseArcReadme(arcDirectory);
// Skip adding arc-0000 template.
if (id !== 0) {
arcs[id] = { metadata, content };
}

/**************************** ****************************/
/**************************** ****************************/
/**************************** ****************************/

if (i === list.length - 1) {
console.log("\nSuccessfully built all ARCs!");

// Write the processed ARCs to the `site` directory.
const path = "../site/src/arcs.json";
fs.writeFileSync(path, JSON.stringify(arcs, null, 4));

console.log(`\nSuccessfully wrote all ARCs to ${path}!\n`);
}
}
}
})
}

/***************************************************** ****************************************************************/
/***************************************************** ****************************************************************/
/***************************************************** ****************************************************************/
/*************************************** HELPER METHODS ONLY BELOW ****************************************************/
/***************************************************** ****************************************************************/
/***************************************************** ****************************************************************/
/***************************************************** ****************************************************************/

// Returns a list of CLI arguments.
const cliArguments = process.argv.slice(2);

// Returns a list of relative paths to every ARC directory.
const getArcDirectories = (relativePathToRoot, callback) => {
glob(relativePathToRoot + '/arc-*', callback);
};

// Checks that a README.md file exists in a given 'arc-xxxx' directory.
const checkArcReadmeExists = async (arcDirectory) => {
const arcReadmeFile = arcDirectory + '/README.md';
try {
if (!fs.existsSync(arcReadmeFile)) {
console.error('Could not find', arcReadmeFile);
process.exit(1);
}
} catch(err) {
console.error('Could not find', arcReadmeFile);
process.exit(1);
}
}

// Checks that a README.md file has the required content for a given 'arc-xxxx' directory.
const checkArcReadmeContent = async (arcDirectory) => {
const arcReadmeFile = arcDirectory + '/README.md';
const fileContents = fs.readFileSync(arcReadmeFile, 'utf8');
const { metadata, content } = parseMD(fileContents);

/**
* arc: 1
* title: Template
* authors: The Aleo Team <[email protected]>
* topic: Meta
* status: Living
* reviewers: Howard Wu <[email protected]>
* created: 2020-02-07
*/

// Check that the metadata is fully filled in.
for (let i = 0; i < requiredMetadata.length; i++) {
const metatopic = requiredMetadata[i];
if (!metadata.hasOwnProperty(metatopic)) {
console.error('\n', arcReadmeFile, 'is missing \'', metatopic, '\'.\n');
process.exit(1);
}

// Check that the ARC # matches the directory #.
if (metatopic === 'arc') {
try {
const directoryNumber = parseInt(arcDirectory.split('-')[1]);
const metadataNumber = parseInt(metadata.arc);
if (directoryNumber !== metadataNumber) {
console.error('\nARC directory ID (', arcDirectory, ') does not match the ARC ID in the README (', metadataNumber, ').\n');
process.exit(1);
}
} catch (err) {
console.error("\nFailed to check that", arcDirectory, "has a matching ARC number.\n");
process.exit(1)
}
}

// Check that the ARC title is nonempty.
if (metatopic === 'title') {
const title = metadata['title'];
if (title === null || title === undefined || title === "") {
console.error('\nARC title cannot be empty.\n');
process.exit(1);
}
}

// Check that the ARC authors is nonempty.
if (metatopic === 'authors') {
const authors = metadata['authors'];
if (authors === null || authors === undefined || authors === "") {
console.error('\nARC authors cannot be empty.\n');
process.exit(1);
}
}

// Check that the ARC topic matches a valid topic.
if (metatopic === 'topic') {
if (!topics.includes(metadata['topic'])) {
console.error('\nARC topic (', metadata['topic'], ') is not an accepted topic.\n');
process.exit(1);
}
}

// Check that the ARC status matches a valid status.
if (metatopic === 'status') {
if (!statuses.includes(metadata['status'])) {
console.error('\nARC status (', metadata['status'], ') is not an accepted status.\n');
process.exit(1);
}
}

// Check that the ARC created is nonempty.
if (metatopic === 'created') {
const created = metadata['created'];
if (created === null || created === undefined || created === "") {
console.error('\nARC created cannot be empty.\n');
process.exit(1);
}
}
}

// Check that the main body is not empty.
if (content === null || content === undefined || content === "") {
console.error('\n', arcReadmeFile, 'is empty.\n');
process.exit(1);
}
}

// Returns the metadata and content of the README file for a given ARC.
const parseArcReadme = (arcDirectory) => {
const arcReadmeFile = arcDirectory + '/README.md';
const fileContents = fs.readFileSync(arcReadmeFile, 'utf8');
const { metadata, content } = parseMD(fileContents);
const id = metadata.arc;
return { id, metadata, content }
}

// The main program.
const main = () => {
if (cliArguments.length === 0) {
console.error('\nPlease provide one CLI argument: \'ci\', \'site\'\n');
} else {
switch (cliArguments[0].toLowerCase()) {
case 'ci':
ci();
break;
case 'site':
site();
break;
default:
console.error('\nInvalid command. Please provide a valid CLI argument: \'ci\', \'site\'\n');
}
}
}

main()
Loading