Compare commits

...

12 Commits

Author SHA1 Message Date
chirag-singhal
3d1ec88717 removed yarn deploy in publish 2020-07-16 22:10:50 +05:30
chirag-singhal
6b1407303e update foam publish command 2020-07-16 20:27:11 +05:30
Ankit Tiwari
528213a0f8 Merge remote-tracking branch 'origin/cli/basic-publish' into cli/demo 2020-07-16 17:38:35 +05:30
Ankit Tiwari
ff89948a70 Merge remote-tracking branch 'origin/cli/fake-init' into cli/demo 2020-07-16 17:38:26 +05:30
Ankit Tiwari
734982996a Merge branch 'cli/lint' into cli/demo 2020-07-16 17:37:25 +05:30
Jani Eväkallio
265ab19e31 Prototype basic publish command (just pushes all changes to git) 2020-07-16 11:57:47 +01:00
Jani Eväkallio
80a799dff9 Prototype the foam init command 2020-07-16 11:11:27 +01:00
Ankit Tiwari
3ef95628f5 Remove posttest command 2020-07-16 13:33:18 +05:30
Ankit Tiwari
626f64aec0 Propagate the error from writeFileToDisk method 2020-07-16 13:32:30 +05:30
Ankit Tiwari
e36c285764 Refactor renameFile to use path module 2020-07-16 13:30:26 +05:30
Ankit Tiwari
20ca92f451 Make fs tests no blocking by using promises 2020-07-16 12:12:50 +05:30
Ankit Tiwari
4557150378 Use Promise.resolve(null) 2020-07-16 11:50:41 +05:30
10 changed files with 271 additions and 18 deletions

View File

@@ -12,7 +12,9 @@
"@oclif/config": "^1",
"@oclif/plugin-help": "^3",
"chalk": "^4.1.0",
"@types/inquirer": "^6.5.0",
"foam-core": "^0.2.0",
"inquirer": "^7.3.2",
"ora": "^4.0.4",
"tslib": "^1"
},
@@ -63,7 +65,6 @@
"scripts": {
"cli": "./bin/run",
"postpack": "rm -f oclif.manifest.json",
"posttest": "eslint . --ext .ts --config .eslintrc",
"prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme",
"test": "jest",
"version": "oclif-dev readme && git add README.md"

View File

@@ -0,0 +1,168 @@
/*eslint-disable no-unused-vars*/
import { Command, flags } from '@oclif/command';
import * as inquirer from 'inquirer';
import * as ora from 'ora';
// @todo implement this class, currently it does nothing but collect inputs
export default class Init extends Command {
static description = 'Initialize a new Foam workspace from template';
// @todo better examples
static examples = [`$ foam init`];
// @todo validate inputs
static flags = {
help: flags.help({ char: 'h' }),
name: flags.string({
char: 'n',
description: 'workspace name',
}),
scm: flags.string({
char: 's',
description: 'source control (github, git, local)'
}),
template: flags.string({
char: 't',
description: 'template'
}),
gitHubUser: flags.string({
char: 'u',
description: 'github username'
}),
gitHubPassword: flags.string({
description: 'github password'
}),
// @todo make flag
githubPages: flags.string({
char: 'p',
description: 'enable github pages'
}),
repoOwner: flags.string({
char: 'p',
description: 'github repo owner'
}),
visibility: flags.string({
char: 'v',
description: 'github repo visibility (public/private)'
}),
};
async run() {
const { flags } = this.parse(Init);
const name =
flags.name ||
(await inquirer.prompt({
name: 'name',
message: 'Give your workspace a name',
type: 'input',
default: 'foam',
})).name;
const template =
flags.template ||
(await inquirer.prompt({
name: 'template',
message: 'Choose from one of the available templates',
type: 'list',
choices: [
{ name: 'Default (foam-template)' },
{ name: 'Gatsby + GitHub Actions (foam-template-gatsby)' },
{ name: '11ty + Netlify (foam-template-eleventy)' },
{ name: 'MLH Fellowship Workspace (foam-template-mlh)' },
],
})).template;
const scm = (await inquirer.prompt([
{
name: 'scm',
message: 'How do you want to store your workspace?',
type: 'list',
default: 'GitHub',
choices: [
{ name: 'GitHub' },
{ name: 'Local git repository' },
{ name: 'Local directory (no source control)' },
],
},
])).scm;
if (scm === 'GitHub') {
const userName =
flags.gitHubUser ||
(await inquirer.prompt({
name: 'username',
message: 'GitHub username',
type: 'input'
})).username;
const password =
flags.gitHubPassword ||
(await inquirer.prompt({
name: 'password',
message: 'GitHub password',
type: 'password'
})).password;
const owner =
flags.repoOwner ||
(await inquirer.prompt({
name: 'owner',
message: 'GitHub repository owner',
type: 'input',
default: userName
})).owner;
const visibility =
flags.visibility ||
(await inquirer.prompt({
name: 'visibility',
message: 'Should the repository be public or private?',
type: 'list',
choices: [
{ name: 'Public' },
{ name: 'Private' }
],
})).visibility.toLowerCase();
const pages =
flags.githubPages ||
((await inquirer.prompt({
name: 'pages',
message: 'Publish automatically to GitHub pages?',
type: 'list',
choices: [
{ name: 'Yes' },
{ name: 'No' }
],
})).pages === 'Yes');
const sure = (await inquirer.prompt({
name: 'sure',
type: 'confirm',
message: `Create a new ${visibility} Foam in https://github.com/${owner}/${name}?`
})).sure;
if (sure) {
const spinner = ora().start();
await new Promise(resolve => {
setTimeout(() => resolve(), 1000);
});
spinner.succeed();
spinner.succeed('Foam workspace created!');
spinner.succeed('Run "code foam" to open your new workspace');
}
} else {
console.log(`Created a private Foam workspace in ./${name}`);
}
}
}

View File

@@ -59,7 +59,7 @@ Successfully generated link references and heading!
return writeFileToDisk(note.path, file);
}
return null;
return Promise.resolve(null);
})
await Promise.all(fileWritePromises);

View File

@@ -49,7 +49,7 @@ Successfully generated link references and heading!
if (kebabCasedFileName) {
return renameFile(note.path, kebabCasedFileName);
}
return null;
return Promise.resolve(null);
})
await Promise.all(fileRename);
@@ -80,7 +80,7 @@ Successfully generated link references and heading!
return writeFileToDisk(note.path, file);
}
return null;
return Promise.resolve(null);
}))
await Promise.all(fileWritePromises);

View File

@@ -0,0 +1,63 @@
import {Command, flags} from '@oclif/command'
import { execSync } from 'child_process';
import * as ora from 'ora';
export default class Publish extends Command {
static description = 'Push all changes to git repository';
static examples = [
`$ foam publish -m "Optional log message"`,
]
static flags = {
message: flags.string({
char: 'm',
description: "optional message"
}),
remote: flags.string({
char: 'r',
description: "remote"
}),
branch: flags.string({
char: 'b',
description: "branch"
})
}
async execWithSpinner(command: string, message: string) {
const spinner = ora(message).start();
// @todo handle errors
const response = execSync(command).toString();
spinner.succeed(`${message} Done!`);
return response;
}
async printPublishInfo(remote: string) {
// @todo actually get this data from GH API
const [, remotePath] = execSync(`git remote get-url ${remote}`).toString().trim().split(':');
const [repo, org] = remotePath.split('/').reverse();
console.log('');
console.log(`🎉 Your changes will be available shortly at https://${org}.github.io/${repo.replace('.git', '')}`);
console.log('');
}
async run() {
const {flags} = this.parse(Publish);
// @todo improve
const message = flags.message || 'foam publish';
const remote = flags.remote || 'origin';
const branch = flags.branch || 'master';
await this.execWithSpinner(`git add -A`, 'Staging changes...');
await this.execWithSpinner(`git commit -m "${message}"`, 'Creating a commit...');
await this.execWithSpinner(`git push ${remote} ${branch}`, "Publishing...");
await this.printPublishInfo(remote);
}
}

View File

@@ -1,9 +1,15 @@
import * as fs from 'fs'
import * as fs from 'fs';
import * as path from 'path';
/**
*
* @param fileUri absolute path for the file that needs to renamed
* @param newFileName "new file name" without the extension
*/
export const renameFile = async (fileUri: string, newFileName: string) => {
const fileName = fileUri.split('/').pop();
const extension = fileName?.split('.').pop();
const newFileUri = fileUri.replace(`${fileName}`, `${newFileName}.${extension}`);
const dirName = path.dirname(fileUri);
const extension = path.extname(fileUri);
const newFileUri = path.join(dirName, `${newFileName}${extension}`);
return fs.promises.rename(fileUri, newFileUri);
}

View File

@@ -1,8 +1,5 @@
import * as fs from 'fs';
export const writeFileToDisk = async (fileUri: string, data: string): Promise<Boolean> => {
return fs.promises.writeFile(fileUri, data).then(() => true).catch(err => {
console.log('error while writing to file: ', err)
return false;
})
export const writeFileToDisk = async (fileUri: string, data: string) => {
return fs.promises.writeFile(fileUri, data);
}

View File

@@ -3,6 +3,8 @@ import { renameFile } from '../src/utils/rename-file'
import * as fs from 'fs';
import mockFS from 'mock-fs';
const doesFileExist = (path) => fs.promises.access(path).then(() => true).catch(() => false);
describe('renameFile', () => {
const fileUri = './test/oldFileName.md';
@@ -16,10 +18,11 @@ describe('renameFile', () => {
});
it('should rename existing file', async () => {
expect(fs.existsSync(fileUri)).toBe(true);
expect(await doesFileExist(fileUri)).toBe(true);
renameFile(fileUri, 'new-file-name');
expect(fs.existsSync(fileUri)).toBe(false);
expect(fs.existsSync('./test/new-file-name.md')).toBe(true);
expect(await doesFileExist(fileUri)).toBe(false);
expect(await doesFileExist('./test/new-file-name.md')).toBe(true);
});
});

View File

@@ -18,7 +18,7 @@ describe('writeFileToDisk', () => {
it('should overrwrite existing file in the disk with the new data', async () => {
const expected = `content in the new file`;
await writeFileToDisk(fileUri, expected);
const actual = fs.readFileSync(fileUri, { encoding: 'utf8' });
const actual = await fs.promises.readFile(fileUri, { encoding: 'utf8' });
expect(actual).toBe(expected);
});
})

View File

@@ -2350,6 +2350,14 @@
resolved "https://registry.yarnpkg.com/@types/graphlib/-/graphlib-2.1.6.tgz#5c7b515bfadc08d737f2e84fadbd151117c73207"
integrity sha512-os2Xj+pV/iwLkLX17LWuXdPooA4Jf4xg8WSdKPUi0tCSseP95oikcA1irOgVl3K2QYnoXrjJT3qVZeQ1uskB7g==
"@types/inquirer@^6.5.0":
version "6.5.0"
resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-6.5.0.tgz#b83b0bf30b88b8be7246d40e51d32fe9d10e09be"
integrity sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw==
dependencies:
"@types/through" "*"
rxjs "^6.4.0"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
@@ -2444,6 +2452,13 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
"@types/through@*":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895"
integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==
dependencies:
"@types/node" "*"
"@types/unist@^2.0.0", "@types/unist@^2.0.2":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
@@ -5937,7 +5952,7 @@ inquirer@^6.2.0, inquirer@^6.2.2:
strip-ansi "^5.1.0"
through "^2.3.6"
inquirer@^7.0.0, inquirer@^7.0.4:
inquirer@^7.0.0, inquirer@^7.0.4, inquirer@^7.3.2:
version "7.3.2"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.2.tgz#25245d2e32dc9f33dbe26eeaada231daa66e9c7c"
integrity sha512-DF4osh1FM6l0RJc5YWYhSDB6TawiBRlbV9Cox8MWlidU218Tb7fm3lQTULyUJDfJ0tjbzl0W4q651mrCCEM55w==