Upgrade tooling

This commit is contained in:
Johannes Loher 2021-05-23 02:46:03 +02:00
parent f6e9aab543
commit 1985f4a2b6
8 changed files with 177 additions and 173 deletions

View file

@ -17,4 +17,13 @@ module.exports = {
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
// e.g. "@typescript-eslint/explicit-function-return-type": "off",
},
overrides: [
{
files: ['./*.js'],
rules: {
'@typescript-eslint/no-var-requires': 'off',
},
},
],
};

View file

@ -46,9 +46,9 @@ build:
cache:
<<: *global_cache
script: |
yarn updateManifest -- --update=${RELEASE_TYPE}
yarn bump-version --release=${RELEASE_TYPE}
RELEASE_VERSION=$(jq -r '.version' < package.json)
git add package.json package-lock.json src/module.json
git add package.json src/module.json
git --no-pager diff
git commit -m "release version ${RELEASE_VERSION}"
git tag -f latest

View file

@ -3,7 +3,6 @@
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"gruntfuggly.todo-tree",
"eg2.vscode-npm-script",
"msjsdiag.debugger-for-chrome",
"arcanis.vscode-zipfs"
]

View file

@ -68,7 +68,7 @@ the following content:
```
{
"dataPath": "<path to your home directory>/.local/share/FoundryVTT"
"dataPath": "<path to your home directory>/.local/share/FoundryVTT/Data"
}
```

View file

@ -1,41 +1,32 @@
const gulp = require('gulp');
const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const stringify = require('json-stringify-pretty-compact');
const argv = require('yargs').argv;
const { rollup } = require('rollup');
const argv = require('yargs').argv;
const chalk = require('chalk');
const fs = require('fs-extra');
const gulp = require('gulp');
const path = require('path');
const rollupConfig = require('./rollup.config');
function getManifest() {
const json = {};
if (fs.existsSync('src')) {
json.root = 'src';
} else {
json.root = 'dist';
}
const modulePath = path.join(json.root, 'module.json');
if (fs.existsSync(modulePath)) {
json.file = fs.readJSONSync(modulePath);
json.name = 'module.json';
} else {
return;
}
return json;
}
const semver = require('semver');
/********************/
/* BUILD */
/* CONFIGURATION */
/********************/
const name = path.basename(path.resolve('.'));
const sourceDirectory = './src';
const distDirectory = './dist';
const sourceFileExtension = '.ts';
const staticFiles = ['module.json'];
const getDownloadURL = (version) =>
`https://git.f3l.de/ghost/risk-dice-modifier/-/jobs/artifacts/${version}/download?job=build`;
/********************/
/* BUILD */
/********************/
/**
* Build TypeScript
* Build the distributable JavaScript code
*/
async function buildTS() {
async function buildCode() {
const build = await rollup({ input: rollupConfig.input, plugins: rollupConfig.plugins });
return build.write(rollupConfig.output);
}
@ -44,16 +35,10 @@ async function buildTS() {
* Copy static files
*/
async function copyFiles() {
const statics = ['module.json'];
try {
for (const file of statics) {
if (fs.existsSync(path.join('src', file))) {
await fs.copy(path.join('src', file), path.join('dist', file));
}
for (const file of staticFiles) {
if (fs.existsSync(path.join(sourceDirectory, file))) {
await fs.copy(path.join(sourceDirectory, file), path.join(distDirectory, file));
}
return Promise.resolve();
} catch (err) {
Promise.reject(err);
}
}
@ -61,158 +46,146 @@ async function copyFiles() {
* Watch for changes for each build step
*/
function buildWatch() {
gulp.watch('src/**/*.ts', { ignoreInitial: false }, buildTS);
gulp.watch(['src/*.json'], { ignoreInitial: false }, copyFiles);
gulp.watch(
path.join(sourceDirectory, '**', `*${sourceFileExtension}`).replace(/\\/g, '/'),
{ ignoreInitial: false },
buildCode,
);
gulp.watch(
staticFiles.map((file) => path.join(sourceDirectory, file).replace(/\\/g, '/')),
{ ignoreInitial: false },
copyFiles,
);
}
/********************/
/* CLEAN */
/* CLEAN */
/********************/
/**
* Remove built files from `dist` folder
* while ignoring source files
* Remove built files from `dist` folder while ignoring source files
*/
async function clean() {
const name = path.basename(path.resolve('.'));
const files = [];
// If the project uses TypeScript
if (fs.existsSync(path.join('src', 'module', `${name}.ts`))) {
files.push('module', `${name}.js`, 'module.json');
}
const files = [...staticFiles, 'module'];
console.log(' ', chalk.yellow('Files to clean:'));
console.log(' ', chalk.blueBright(files.join('\n ')));
// Attempt to remove the files
try {
for (const filePath of files) {
await fs.remove(path.join('dist', filePath));
}
return Promise.resolve();
} catch (err) {
Promise.reject(err);
for (const filePath of files) {
await fs.remove(path.join(distDirectory, filePath));
}
}
/********************/
/* LINK */
/* LINK */
/********************/
/**
* Get the data path of Foundry VTT based on what is configured in `foundryconfig.json`
*/
function getDataPath() {
const config = fs.readJSONSync('foundryconfig.json');
if (config?.dataPath) {
if (!fs.existsSync(path.resolve(config.dataPath))) {
throw new Error('User Data path invalid, no Data directory found');
}
return path.resolve(config.dataPath);
} else {
throw new Error('No User Data path defined in foundryconfig.json');
}
}
/**
* Link build to User Data folder
*/
async function linkUserData() {
const name = path.basename(path.resolve('.'));
const config = fs.readJSONSync('foundryconfig.json');
let destinationDirectory;
if (fs.existsSync(path.resolve('.', sourceDirectory, 'module.json'))) {
destinationDirectory = 'modules';
} else {
throw new Error(`Could not find ${chalk.blueBright('module.json')}`);
}
let destDir;
try {
if (
fs.existsSync(path.resolve('.', 'dist', 'module.json')) ||
fs.existsSync(path.resolve('.', 'src', 'module.json'))
) {
destDir = 'modules';
} else {
throw Error(`Could not find ${chalk.blueBright('module.json')}`);
}
const linkDirectory = path.resolve(getDataPath(), destinationDirectory, name);
let linkDir;
if (config.dataPath) {
if (!fs.existsSync(path.join(config.dataPath, 'Data')))
throw Error('User Data path invalid, no Data directory found');
if (argv.clean || argv.c) {
console.log(chalk.yellow(`Removing build in ${chalk.blueBright(linkDirectory)}.`));
linkDir = path.join(config.dataPath, 'Data', destDir, name);
} else {
throw Error('No User Data path defined in foundryconfig.json');
}
if (argv.clean || argv.c) {
console.log(chalk.yellow(`Removing build in ${chalk.blueBright(linkDir)}`));
await fs.remove(linkDir);
} else if (!fs.existsSync(linkDir)) {
console.log(chalk.green(`Copying build to ${chalk.blueBright(linkDir)}`));
await fs.symlink(path.resolve('./dist'), linkDir);
}
return Promise.resolve();
} catch (err) {
Promise.reject(err);
await fs.remove(linkDirectory);
} else if (!fs.existsSync(linkDirectory)) {
console.log(chalk.green(`Copying build to ${chalk.blueBright(linkDirectory)}.`));
await fs.ensureDir(path.resolve(linkDirectory, '..'));
await fs.symlink(path.resolve('.', distDirectory), linkDirectory);
}
}
/*********************/
/* PACKAGE */
/*********************/
/********************/
/* VERSIONING */
/********************/
/**
* Update version and URLs in the manifest JSON
* Get the contents of the manifest file as object.
*/
function updateManifest(cb) {
function getManifest() {
const manifestPath = path.join(sourceDirectory, 'module.json');
if (fs.existsSync(manifestPath)) {
return {
file: fs.readJSONSync(manifestPath),
name: 'module.json',
};
}
}
/**
* Get the target version based on on the current version and the argument passed as release.
*/
function getTargetVersion(currentVersion, release) {
if (['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].includes(release)) {
return semver.inc(currentVersion, release);
} else {
return semver.valid(release);
}
}
/**
* Update version and download URL.
*/
function bumpVersion(cb) {
const packageJson = fs.readJSONSync('package.json');
const packageLockJson = fs.readJSONSync('package-lock.json');
const manifest = getManifest();
if (!manifest) cb(Error(chalk.red('Manifest JSON not found')));
try {
const version = argv.update || argv.u;
const release = argv.release || argv.r;
/* Update version */
const currentVersion = packageJson.version;
const versionMatch = /^(\d{1,}).(\d{1,}).(\d{1,})$/;
const currentVersion = manifest.file.version;
let targetVersion = '';
if (!version) {
cb(Error('Missing version number'));
if (!release) {
return cb(Error('Missing release type'));
}
if (versionMatch.test(version)) {
targetVersion = version;
} else {
targetVersion = currentVersion.replace(versionMatch, (substring, major, minor, patch) => {
console.log(substring, Number(major) + 1, Number(minor) + 1, Number(patch) + 1);
if (version === 'major') {
return `${Number(major) + 1}.0.0`;
} else if (version === 'minor') {
return `${major}.${Number(minor) + 1}.0`;
} else if (version === 'patch') {
return `${major}.${minor}.${Number(patch) + 1}`;
} else {
return '';
}
});
}
const targetVersion = getTargetVersion(currentVersion, release);
if (targetVersion === '') {
return cb(Error(chalk.red('Error: Incorrect version arguments.')));
if (!targetVersion) {
return cb(new Error(chalk.red('Error: Incorrect version arguments')));
}
if (targetVersion === currentVersion) {
return cb(Error(chalk.red('Error: Target version is identical to current version.')));
return cb(new Error(chalk.red('Error: Target version is identical to current version')));
}
console.log(`Updating version number to '${targetVersion}'`);
packageJson.version = targetVersion;
packageLockJson.version = targetVersion;
manifest.file.version = targetVersion;
/* Update URL */
const result = `https://git.f3l.de/ghost/${packageJson.name}/-/jobs/artifacts/${targetVersion}/download?job=build`;
manifest.file.download = result;
const prettyProjectJson =
stringify(manifest.file, {
maxLength: 40,
indent: 4,
}) + '\n';
fs.writeJSONSync('package.json', packageJson, { spaces: 4 });
fs.writeJSONSync('package-lock.json', packageLockJson, { spaces: 4 });
fs.writeFileSync(path.join(manifest.root, manifest.name), prettyProjectJson, 'utf8');
manifest.file.version = targetVersion;
manifest.file.download = getDownloadURL(targetVersion);
fs.writeJSONSync(path.join(sourceDirectory, manifest.name), manifest.file, { spaces: 4 });
return cb();
} catch (err) {
@ -220,10 +193,10 @@ function updateManifest(cb) {
}
}
const execBuild = gulp.parallel(buildTS, copyFiles);
const execBuild = gulp.parallel(buildCode, copyFiles);
exports.build = gulp.series(clean, execBuild);
exports.watch = buildWatch;
exports.clean = clean;
exports.link = linkUserData;
exports.updateManifest = updateManifest;
exports.bumpVersion = bumpVersion;

View file

@ -21,16 +21,17 @@
"scripts": {
"build": "gulp build",
"build:watch": "gulp watch",
"link": "gulp link",
"clean": "gulp clean && gulp link --clean",
"update": "yarn add --dev foundry-vtt-types@github:League-of-Foundry-Developers/foundry-vtt-types#foundry-0.7.9",
"updateManifest": "gulp updateManifest",
"lint": "eslint 'src/**/*.ts' --cache",
"lint:fix": "eslint 'src/**/*.ts' --cache --fix",
"format": "prettier --write 'src/**/*.(ts|json)'",
"link-project": "gulp link",
"clean": "gulp clean",
"clean:link": "gulp link --clean",
"bump-version": "gulp bumpVersion",
"lint": "eslint --ext .ts,.js .",
"lint:fix": "eslint --ext .ts,.js --fix .",
"format": "prettier --write \"./**/*.(ts|js|json)\"",
"postinstall": "husky install"
},
"devDependencies": {
"@league-of-foundry-developers/foundry-vtt-types": "^0.7.9-6",
"@rollup/plugin-node-resolve": "^13.0.0",
"@types/fs-extra": "^9.0.11",
"@typescript-eslint/eslint-plugin": "^4.24.0",
@ -39,7 +40,6 @@
"eslint": "^7.27.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"foundry-vtt-types": "github:League-of-Foundry-Developers/foundry-vtt-types#foundry-0.7.9",
"fs-extra": "^10.0.0",
"gulp": "^4.0.2",
"husky": "^6.0.0",
@ -48,12 +48,13 @@
"prettier": "^2.3.0",
"rollup": "^2.48.0",
"rollup-plugin-typescript2": "^0.30.0",
"semver": "^7.3.5",
"tslib": "^2.2.0",
"typescript": "^4.2.4",
"yargs": "^17.0.1"
},
"lint-staged": {
"*.ts": "eslint --cache --fix",
"*.(ts|js)": "eslint --fix",
"*.json": "prettier --write"
}
}

View file

@ -2,7 +2,7 @@
"compilerOptions": {
"target": "ES2020",
"lib": ["DOM", "ES2020"],
"types": ["foundry-vtt-types"],
"types": ["@league-of-foundry-developers/foundry-vtt-types"],
"esModuleInterop": true,
"moduleResolution": "node",
"forceConsistentCasingInFileNames": true,

View file

@ -58,6 +58,22 @@ __metadata:
languageName: node
linkType: hard
"@league-of-foundry-developers/foundry-vtt-types@npm:^0.7.9-6":
version: 0.7.9-6
resolution: "@league-of-foundry-developers/foundry-vtt-types@npm:0.7.9-6"
dependencies:
"@types/howler": 2.2.1
"@types/jquery": 3.5.1
"@types/socket.io-client": ^1.4.33
handlebars: 4.7.6
pixi-particles: ^4.3.0
pixi.js: 5.3.4
tinymce: 5.6.2
typescript: ^4.1.4
checksum: ea8783a4da939db6d51e12a6cb343e53cb6df747ccf8d823063066322c707c98c0fffd2559efc0e0e8fec47b08528f5920be3ac9cd4708c673d947f0e8898e6e
languageName: node
linkType: hard
"@nodelib/fs.scandir@npm:2.1.4":
version: 2.1.4
resolution: "@nodelib/fs.scandir@npm:2.1.4"
@ -2429,21 +2445,6 @@ __metadata:
languageName: node
linkType: hard
"foundry-vtt-types@github:League-of-Foundry-Developers/foundry-vtt-types#foundry-0.7.9":
version: 0.1.0
resolution: "foundry-vtt-types@https://github.com/League-of-Foundry-Developers/foundry-vtt-types.git#commit=de66d24eb891c97923db47eb1a819eec2a298f02"
dependencies:
"@types/howler": 2.2.1
"@types/jquery": 3.5.1
"@types/socket.io-client": ^1.4.33
handlebars: 4.7.6
pixi.js: 5.3.4
tinymce: 5.6.2
typescript: ^4.1.4
checksum: fb6065ce7ed2c969ee421abd3d259f264ed707fabfce01f27d59707338a9ca6854233c0cb8b91ef2310af22a7f7ee95b3e5080d0d2c6662e9b31ed3a5d10ba17
languageName: node
linkType: hard
"fragment-cache@npm:^0.2.1":
version: 0.2.1
resolution: "fragment-cache@npm:0.2.1"
@ -4437,6 +4438,15 @@ fsevents@~2.3.1:
languageName: node
linkType: hard
"pixi-particles@npm:^4.3.0":
version: 4.3.0
resolution: "pixi-particles@npm:4.3.0"
peerDependencies:
pixi.js: ">=4.0.0"
checksum: 66da332ae33a236afb5a5b2ebeea0308314423bab1017851be860a0904aed91cb5f345ea488c75a6efdfa6e42096ba7762472f8573590b924b93cae293b8b6d9
languageName: node
linkType: hard
"pixi.js@npm:5.3.4":
version: 5.3.4
resolution: "pixi.js@npm:5.3.4"
@ -4897,6 +4907,7 @@ fsevents@~2.3.1:
version: 0.0.0-use.local
resolution: "risk-dice-modifier@workspace:."
dependencies:
"@league-of-foundry-developers/foundry-vtt-types": ^0.7.9-6
"@rollup/plugin-node-resolve": ^13.0.0
"@types/fs-extra": ^9.0.11
"@typescript-eslint/eslint-plugin": ^4.24.0
@ -4905,7 +4916,6 @@ fsevents@~2.3.1:
eslint: ^7.27.0
eslint-config-prettier: ^8.3.0
eslint-plugin-prettier: ^3.4.0
foundry-vtt-types: "github:League-of-Foundry-Developers/foundry-vtt-types#foundry-0.7.9"
fs-extra: ^10.0.0
gulp: ^4.0.2
husky: ^6.0.0
@ -4914,6 +4924,7 @@ fsevents@~2.3.1:
prettier: ^2.3.0
rollup: ^2.48.0
rollup-plugin-typescript2: ^0.30.0
semver: ^7.3.5
tslib: ^2.2.0
typescript: ^4.2.4
yargs: ^17.0.1
@ -5043,6 +5054,17 @@ fsevents@~2.3.1:
languageName: node
linkType: hard
"semver@npm:^7.3.5":
version: 7.3.5
resolution: "semver@npm:7.3.5"
dependencies:
lru-cache: ^6.0.0
bin:
semver: bin/semver.js
checksum: c53624ddf4b9779bcbf55a1eb8b37074cc44bfeca416f3cc263429408202a8a3c59b00eef8c647d697303bc39b95c022a5c61959221d3814bfb1270ff7c14986
languageName: node
linkType: hard
"set-blocking@npm:^2.0.0, set-blocking@npm:~2.0.0":
version: 2.0.0
resolution: "set-blocking@npm:2.0.0"