Skip to content
Open
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
6 changes: 3 additions & 3 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ authors:
orcid: https://orcid.org/0009-0001-1641-9397
identifiers:
- type: url
value: https://github.com/caffeine-addictt/template/releases/tag/v1.12.3
description: The GitHub release URL of tag v1.12.3.
value: https://github.com/caffeine-addictt/template/releases/tag/v1.13.2
description: The GitHub release URL of tag v1.13.2.
cff-version: 1.2.0
date-released: 2024-05-12
keywords:
Expand All @@ -19,4 +19,4 @@ message: If you use this software, please cite it using these metadata.
repository-code: https://github.com/caffeine-addictt/template
title: template
type: software
version: 1.12.3
version: 1.13.2
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,6 @@ Alex - [contact@ngjx.org](mailto:contact@ngjx.org)
[stars-shield]: https://img.shields.io/github/stars/caffeine-addictt/template.svg?style=for-the-badge&color=yellow
[stars-url]: https://github.com/caffeine-addictt/template/stargazers
[license-shield]: https://img.shields.io/github/license/caffeine-addictt/template.svg?style=for-the-badge
[license-url]: https://github.com/caffeine-addictt/template/blob/master/LICENSE.txt
[license-url]: https://github.com/caffeine-addictt/template/blob/main/LICENSE
[use-shield]: https://img.shields.io/badge/Use%20template-FFFFFF?style=for-the-badge
[use-url]: https://github.com/new?template_name=template&template_owner=caffeine-addictt
2 changes: 1 addition & 1 deletion dist/io-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const replaceInFile = (filePath, _tempDir, data) => new Promise((resolve) => {
// Revert to legacy
let fileContent = fs_1.default.readFileSync(filePath, 'utf8');
fileContent = fileContent
.replace(/{{REPOSITORY}}/g, data.repository)
.replace(/{{REPOSITORY}}/g, `${data.username}/${data.repository}`)
.replace(/{{PROJECT_NAME}}/g, data.proj_name)
.replace(/{{PROJECT_SHORT_DESCRIPTION}}/g, data.proj_short_desc)
.replace(/{{PROJECT_LONG_DESCRIPTION}}/g, data.proj_long_desc)
Expand Down
16 changes: 16 additions & 0 deletions dist/parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractRepoInfo = void 0;
/** Extract username/org and repo from url */
const extractRepoInfo = (url) => {
const originUrl = url.trim();
const match = /^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/.exec(originUrl);
if (!match || !match[1] || !match[2])
throw new AggregateError(`Could not extract user and repo from git remote: ${originUrl}`);
return {
url: originUrl,
org: match[1],
repo: match[2],
};
};
exports.extractRepoInfo = extractRepoInfo;
35 changes: 35 additions & 0 deletions dist/resolver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"use strict";
/**
* This file will hold the configuration options to make the setup script not so annoying
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveUserInfo = exports.resolveRepoInfo = void 0;
const parser_1 = require("./parser");
const term_1 = require("./term");
const resolveRepoInfo = () => (0, term_1.execute)('git', ['remote', 'get-url', 'origin'])
.then((_originUrl) => (0, parser_1.extractRepoInfo)(_originUrl.toString()))
.catch(() => ({}));
exports.resolveRepoInfo = resolveRepoInfo;
const resolveUserInfo = async () => {
const promises = await Promise.all([
(0, term_1.execute)('git', ['config', '--global', 'user.name'])
.then((r) => r.toString().trim())
.catch(() => undefined),
(0, term_1.execute)('git', ['config', '--global', 'user.email'])
.then((r) => r.toString().trim())
.catch(() => undefined),
]);
return {
name: promises[0],
email: promises[1],
};
};
exports.resolveUserInfo = resolveUserInfo;
const resolveGitInfo = async () => {
const promises = await Promise.all([(0, exports.resolveRepoInfo)(), (0, exports.resolveUserInfo)()]);
return {
...promises[0],
...promises[1],
};
};
exports.default = resolveGitInfo;
34 changes: 24 additions & 10 deletions dist/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const readline_1 = __importDefault(require("readline"));
const io_util_1 = require("./io-util");
const resolver_1 = __importDefault(require("./resolver"));
/**
* For interacting with stdin/stdout
*/
Expand All @@ -28,15 +29,25 @@ const question = (query, validator = [], trimWhitespace = true) => new Promise((
}));
/** Ask for project information */
const fetchInfo = async (cleanup) => {
const name = await question('Name? (This will go on the LICENSE)\n=> ');
const email = await question('Email?\n=> ', [
const resolved = await (0, resolver_1.default)();
// Ask user
const name = await question(`Name? (This will go on the LICENSE)${resolved.name ? ` [Resolved: ${resolved.name}]` : ''}\n=> `)
.then((val) => val.trim())
.then((val) => (val.length ? val : resolved.name ?? ''));
const email = await question(`Email?${resolved.email ? ` [Resolved: ${resolved.email}]` : ''}\n=> `, [
{
validate: (s) => /.+@.+\..+/.test(s),
validate: (s) => !!resolved.email || /.+@.+\..+/.test(s),
onError: () => console.log('Invalid email!'),
},
]);
const username = await question('Username? (https://github.com/<username>)\n=> ');
const repository = await question('Repository? ((https://github.com/$username/<repo>\n=> ');
])
.then((val) => val.trim())
.then((val) => (val.length ? val : resolved.email ?? ''));
const username = await question(`Username? (https://github.com/<username>)${resolved.org ? ` [Resolved: ${resolved.org}]` : ''}\n=> `)
.then((val) => val.trim())
.then((val) => (val.length ? val : resolved.org ?? ''));
const repository = await question(`Repository? (https://github.com/${username}/<repo>)${resolved.repo ? ` [Resolved: ${resolved.repo}]` : ''}\n=> `)
.then((val) => val.trim())
.then((val) => (val.length ? val : resolved.repo ?? ''));
const proj_name = await question('Project name?\n=> ');
const proj_short_desc = await question('Short description?\n=> ');
const proj_long_desc = await question('Long description?\n=> ');
Expand Down Expand Up @@ -90,14 +101,14 @@ const { func: main } = (0, io_util_1.withTempDir)('caffeine-addictt-template-',
recursive: true,
});
// Use async
await Promise.all(filesToUpdate.map((filename) => async () => {
await Promise.all(filesToUpdate.map((filename) => (async () => {
const filePath = path_1.default.join('./template', filename);
const fileInfo = fs_1.default.statSync(filePath);
if (fileInfo.isDirectory()) {
return;
}
await (0, io_util_1.replaceInFile)(filePath, tempDir, data);
}));
})()));
// Write CODEOWNERS
fs_1.default.appendFileSync('./template/.github/CODEOWNERS', `* @${data.username}`);
// ########################################## //
Expand All @@ -122,6 +133,9 @@ const { func: main } = (0, io_util_1.withTempDir)('caffeine-addictt-template-',
// ################# //
// Stage 3: Clean up //
// ################# //
// Only add `force: true` for files or directories that
// will only exist if some development task was carried out
// like eslintcache
console.log('Cleaning up...');
// Js
fs_1.default.unlinkSync('package.json');
Expand All @@ -133,16 +147,16 @@ const { func: main } = (0, io_util_1.withTempDir)('caffeine-addictt-template-',
fs_1.default.unlinkSync('babel.config.cjs');
fs_1.default.rmSync('tests', { recursive: true });
// Linting
fs_1.default.unlinkSync('.eslintcache');
fs_1.default.unlinkSync('.eslintignore');
fs_1.default.unlinkSync('.prettierignore');
fs_1.default.unlinkSync('eslint.config.mjs');
fs_1.default.rmSync('.eslintcache', { force: true });
// Syncing
fs_1.default.unlinkSync('.templatesyncignore');
// Git
fs_1.default.unlinkSync('.gitignore');
// Node
fs_1.default.rmSync('node_modules', { recursive: true });
fs_1.default.rmSync('node_modules', { recursive: true, force: true });
// Clean up dist
fs_1.default.unlinkSync(__filename);
fs_1.default.rmSync('dist', { recursive: true });
Expand Down
10 changes: 10 additions & 0 deletions dist/term.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.execute = void 0;
const child_process_1 = require("child_process");
const execute = (command, args, spawnOptions) => new Promise((resolve, reject) => {
const cmd = (0, child_process_1.spawn)(command, args, spawnOptions);
cmd.stdout.on('data', resolve);
cmd.stderr.on('data', reject);
});
exports.execute = execute;
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/io-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const replaceInFile = (

let fileContent = fs.readFileSync(filePath, 'utf8');
fileContent = fileContent
.replace(/{{REPOSITORY}}/g, data.repository)
.replace(/{{REPOSITORY}}/g, `${data.username}/${data.repository}`)
.replace(/{{PROJECT_NAME}}/g, data.proj_name)
.replace(/{{PROJECT_SHORT_DESCRIPTION}}/g, data.proj_short_desc)
.replace(/{{PROJECT_LONG_DESCRIPTION}}/g, data.proj_long_desc)
Expand Down
20 changes: 20 additions & 0 deletions src/parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { RepoInfo } from './types';

/** Extract username/org and repo from url */
export const extractRepoInfo = (url: string): RepoInfo => {
const originUrl = url.trim();
const match = /^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/.exec(
originUrl,
);

if (!match || !match[1] || !match[2])
throw new AggregateError(
`Could not extract user and repo from git remote: ${originUrl}`,
);

return {
url: originUrl,
org: match[1],
repo: match[2],
} satisfies RepoInfo;
};
37 changes: 37 additions & 0 deletions src/resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* This file will hold the configuration options to make the setup script not so annoying
*/

import { extractRepoInfo } from './parser';
import { execute } from './term';
import type { GitInfo, RepoInfo, UserInfo } from './types';

export const resolveRepoInfo = (): Promise<RepoInfo> =>
execute('git', ['remote', 'get-url', 'origin'])
.then((_originUrl) => extractRepoInfo(_originUrl.toString()))
.catch(() => ({}));

export const resolveUserInfo = async (): Promise<UserInfo> => {
const promises = await Promise.all([
execute('git', ['config', '--global', 'user.name'])
.then((r) => r.toString().trim())
.catch(() => undefined),
execute('git', ['config', '--global', 'user.email'])
.then((r) => r.toString().trim())
.catch(() => undefined),
]);

return {
name: promises[0],
email: promises[1],
} satisfies UserInfo;
};

const resolveGitInfo = async (): Promise<GitInfo> => {
const promises = await Promise.all([resolveRepoInfo(), resolveUserInfo()]);
return {
...promises[0],
...promises[1],
} as GitInfo;
};
export default resolveGitInfo;
Loading