Skip to content

Commit

Permalink
feat: Add version check (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
ffflorian authored Apr 29, 2019
1 parent 7af79f1 commit df03823
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 86 deletions.
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
# schemastore-updater [![Build Status](https://api.travis-ci.org/ffflorian/schemastore-updater.svg?branch=master)](https://travis-ci.org/ffflorian/schemastore-updater/) [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=ffflorian/schemastore-updater)](https://dependabot.com)
# schemastore-updater [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=ffflorian/schemastore-updater)](https://dependabot.com)

A tool to load schema files from [@SchemaStore/schemastore](https://github.com/SchemaStore/schemastore) and publish them as TypeScript definitions [on npm](https://www.npmjs.com/search?q=schemastore).
A tool to load schema files from [@SchemaStore/schemastore](https://github.com/SchemaStore/schemastore) and publish them as TypeScript definitions [on npm](https://www.npmjs.com/search?q=@schemastore/).

## Usage

```
Usage: schemastore-updater [options] [command]
Options:
-V, --version output the version number
-s, --settings <file> Specify a settings file
-h, --help output usage information
Commands:
update [options]
version-check
```

```
Usage: update [options]
Options:
-f, --force Force re-generating all schemas
-h, --help output usage information
```
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"lint:other": "yarn prettier --list-different",
"lint:ts": "tslint --project tsconfig.json",
"prettier": "prettier --ignore-path .gitignore \"*.{json,md}\"",
"start": "cross-env NODE_DEBUG='schemastore-updater/*' ts-node src/cli.ts",
"start": "rimraf temp && cross-env NODE_DEBUG='schemastore-updater/*' ts-node src/cli.ts",
"test": "exit 0"
},
"version": "1.1.0"
Expand Down
16 changes: 8 additions & 8 deletions schemas/json-schemas.lock
Original file line number Diff line number Diff line change
Expand Up @@ -445,30 +445,30 @@
},
"appsscript.json": {
"hash": "379d95dc88cc7f9423397861fae2979d5bb2e7fb3a5381d7b865c3df38c862b8",
"version": "0.0.1"
"version": "1.0.1"
},
"bozr.json": {
"hash": "1df26248def39755c4bd1665ef5a0fe89861ec7f74c0f890d081801c1c7d0e90",
"version": "0.0.1"
"version": "1.0.1"
},
"bukkit-plugin.json": {
"hash": "5ef6e55e702d20431df4e88059bc3ba5edeb6902881174417c11fa16e501a3f0",
"version": "0.0.1"
"version": "1.0.1"
},
"bungee-plugin.json": {
"hash": "782ee73bfded5335de76d2e77cd0a6e8b0477467b3a19cf7ff458e292062c363",
"version": "0.0.1"
"version": "1.0.1"
},
"clasp.json": {
"hash": "e54d46c347f1a6e2150e8a07806e02feb88d34a634a26a48fa7a481eaa85e111",
"version": "0.0.1"
"version": "1.0.1"
},
"gitlab-ci.json": {
"hash": "00ffc235209fdac3fc80edeb03c0de02171b3050a2f060226213b762d1e3a83b",
"version": "0.0.1"
"version": "1.0.1"
},
"nlu.json": {
"hash": "4085ae872de074f028a24e0c57e097a129f55ec4ae09852096b9a001c99480ab",
"version": "0.0.1"
"version": "1.0.2"
}
}
}
5 changes: 5 additions & 0 deletions settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"ansible-stable-2.3.json",
"ansible-stable-2.4.json",
"ansible-stable-2.5.json",
"ansible-stable-2.6.json",
"ansible-stable-2.7.json",
"babelrc.json",
"bootstraprc.json",
"chrome-manifest.json",
Expand All @@ -18,7 +20,10 @@
"host.json",
"htmlhint.json",
"jscsrc.json",
"lsdlschema-1.0.json",
"lsdlschema.json",
"modernizrrc.json",
"pocketmine-plugin.json",
"project-1.0.0-beta4.json",
"project-1.0.0-beta8.json",
"project-1.0.0-rc1.json",
Expand Down
106 changes: 70 additions & 36 deletions src/SchemaGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,37 @@ import * as logdown from 'logdown';
import * as path from 'path';
import * as semver from 'semver';
import * as simpleGit from 'simple-git/promise';
import {BuildResult, SchemaData, SchemaHashes} from './interfaces';
import {BuildResult, FileSettings, SchemaData, SchemaHashes} from './interfaces';

interface SchemaGeneratorOptions extends Partial<FileSettings> {
force?: boolean;
}

const defaultOptions: Required<SchemaGeneratorOptions> = {
disabledSchemas: [],
force: false,
lockFile: 'schemas/json-schemas.lock',
schemaStoreRepo: 'https://github.com/SchemaStore/schemastore',
};

class SchemaGenerator {
private readonly git: simpleGit.SimpleGit;
private readonly jsonSchemasDir: string;
private readonly logger: logdown.Logger;
private readonly schemaStoreDirResolved: string;
private readonly options: Required<SchemaGeneratorOptions>;
private readonly lockFile: string;

constructor(
private readonly disabledSchemas: string[],
private readonly schemaStoreRepo: string,
private readonly lockFile = 'schemas/json-schemas.lock',
private readonly force = false
) {
constructor(options?: SchemaGeneratorOptions) {
this.options = {
...defaultOptions,
...options,
};
this.git = simpleGit('.');
this.schemaStoreDirResolved = path.join('temp', 'schemastore');
this.jsonSchemasDir = path.join(this.schemaStoreDirResolved, 'src', 'schemas', 'json');
this.lockFile = path.resolve(this.lockFile);
this.logger = logdown('schemastore-updater/index', {
this.schemaStoreDirResolved = path.join('temp/schemastore');
this.jsonSchemasDir = path.join(this.schemaStoreDirResolved, 'src/schemas/json');
this.lockFile = path.resolve(this.options.lockFile);
this.logger = logdown('schemastore-updater/SchemaGenerator', {
logger: console,
markdown: false,
});
Expand All @@ -36,7 +48,7 @@ class SchemaGenerator {

this.logger.info(`Using lockfile "${this.lockFile}".`);

if (this.force) {
if (this.options.force) {
this.logger.info(`Force is set. Will re-generate all schemas.`);
}
}
Expand All @@ -51,9 +63,7 @@ class SchemaGenerator {
}

private async generateLockFile(fileName: string, data: SchemaHashes): Promise<void> {
await fs.writeFile(path.resolve(fileName), JSON.stringify(data, null, 2), {
encoding: 'utf8',
});
await fs.writeJson(path.resolve(fileName), data, {spaces: 2});
}

private async generateSchemas(jsonData: SchemaHashes): Promise<BuildResult> {
Expand All @@ -64,6 +74,7 @@ class SchemaGenerator {
const schemaName = fileName.replace('.json', '');
const fileNameResolved = path.resolve(this.jsonSchemasDir, fileName);
this.logger.info(`Processing "${schemaName}" ...`);

let newSchema = '';

try {
Expand All @@ -73,19 +84,21 @@ class SchemaGenerator {
disabledSchemas.push(fileName);
continue;
}

const schemaDirResolved = path.resolve('schemas', schemaName);

await fs.ensureDir(schemaDirResolved);
await fs.writeFile(path.resolve(schemaDirResolved, 'index.d.ts'), newSchema, {encoding: 'utf8'});
await fs.writeFile(path.join(schemaDirResolved, 'index.d.ts'), newSchema, 'utf8');

const packageJson = this.generatePackageJson(schemaName, jsonData[fileName]);
await fs.writeFile(path.resolve(schemaDirResolved, 'package.json'), packageJson, {encoding: 'utf8'});
const readMe = this.generateReadme(schemaName, jsonData[fileName].version);
await fs.writeFile(path.resolve(schemaDirResolved, 'README.md'), readMe, {
encoding: 'utf8',
});
await fs.writeFile(path.join(schemaDirResolved, 'package.json'), packageJson, 'utf8');

const readMe = this.generateReadme(schemaName);
await fs.writeFile(path.join(schemaDirResolved, 'README.md'), readMe, 'utf8');

const license = this.generateLicense();
await fs.writeFile(path.resolve(schemaDirResolved, 'LICENSE'), license, {
encoding: 'utf8',
});
await fs.writeFile(path.join(schemaDirResolved, 'LICENSE'), license, 'utf8');

generatedSchemas.push(schemaName);
}

Expand Down Expand Up @@ -126,7 +139,7 @@ SOFTWARE
"dependencies": {},
"description": "TypeScript definitions for ${schemaName}.",
"license": "MIT",
"main": "",
"main": "index.d.ts",
"name": "@schemastore/${schemaName}",
"repository": "https://github.com/ffflorian/schemastore-updater/tree/master/schemas/${schemaName}",
"scripts": {},
Expand All @@ -138,7 +151,7 @@ SOFTWARE
`;
}

private generateReadme(schemaName: string, schemaVersion: string) {
private generateReadme(schemaName: string): string {
const timeStamp = new Date().toLocaleDateString('en-US', {
day: '2-digit',
hour: '2-digit',
Expand Down Expand Up @@ -167,33 +180,51 @@ Files were exported from https://github.com/ffflorian/schemastore-updater/tree/m

private async removeAndClone(): Promise<void> {
await fs.remove(this.schemaStoreDirResolved);
this.logger.info(`Cloning "${this.schemaStoreRepo}" to "${this.schemaStoreDirResolved}" ...`);
await this.git.clone(this.schemaStoreRepo, this.schemaStoreDirResolved, ['--depth=1']);
this.logger.info(`Cloning "${this.options.schemaStoreRepo}" to "${this.schemaStoreDirResolved}" ...`);
await this.git.clone(this.options.schemaStoreRepo, this.schemaStoreDirResolved, ['--depth=1']);
}

public async checkVersions(): Promise<void> {
const lockFileData: SchemaHashes = await fs.readJSON(this.lockFile);
const invalidEntries = [];

for (const entry of Object.keys(lockFileData)) {
const name = entry.replace('.json', '');
const packageJson = fs.readJsonSync(`./schemas/${name}/package.json`);
const lockFileVersion = lockFileData[entry].version;
if (lockFileVersion !== packageJson.version) {
invalidEntries.push(entry);
}
}

if (invalidEntries.length) {
throw new Error(`Invalid version entries: "${invalidEntries.join('", "')}".`);
}
}

public async start(): Promise<BuildResult> {
public async generate(): Promise<BuildResult> {
const lockFileData: SchemaHashes = await fs.readJSON(this.lockFile);

await this.removeAndClone();
const allFiles = await fs.readdir(this.jsonSchemasDir);

const jsonFiles = allFiles.filter(fileName => {
const schemaIsDisabled = this.disabledSchemas.includes(fileName);
const schemaIsDisabled = this.options.disabledSchemas.includes(fileName);
return fileName.endsWith('.json') && !schemaIsDisabled;
});

this.logger.info(`Loaded ${jsonFiles.length} enabled schemas and ${this.disabledSchemas.length} disabled schemas.`);
this.logger.info(
`Loaded ${jsonFiles.length} enabled schemas and ${this.options.disabledSchemas.length} disabled schemas.`
);

const fileHashes: {[fileName: string]: string} = {};
const fileHashes: Record<string, string> = {};

for (const fileName of jsonFiles) {
const fileNameResolved = path.resolve(this.jsonSchemasDir, fileName);
const fileIsReadable = await this.fileIsReadable(fileNameResolved);

if (fileIsReadable) {
const fileContent = await fs.readFile(fileNameResolved, {
encoding: 'utf8',
});
const fileContent = await fs.readFile(fileNameResolved, 'utf8');
const sha256 = crypto
.createHash('sha256')
.update(fileContent)
Expand All @@ -215,7 +246,10 @@ Files were exported from https://github.com/ffflorian/schemastore-updater/tree/m
version: '0.0.1',
};
updatedHashes[fileName] = lockFileData[fileName];
} else if (lockFileData[fileName] && (fileHashes[fileName] !== lockFileData[fileName].hash || this.force)) {
} else if (
lockFileData[fileName] &&
(fileHashes[fileName] !== lockFileData[fileName].hash || this.options.force)
) {
this.logger.info(`Hash from "${fileName}" is outdated. Updating.`);

const newVersion = semver.inc(lockFileData[fileName].version, 'patch');
Expand Down
Loading

0 comments on commit df03823

Please sign in to comment.