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

improve output and performance of bit watch and add tests #1846

Merged
merged 5 commits into from
Jul 23, 2019
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [unreleased]

- build only the component of the modified/added/removed file upon `bit watch`
- [#1634](https://github.com/teambit/bit/issues/1634) improve the output of `bit watch`
- [#1668](https://github.com/teambit/bit/issues/1668) bug fix - `bit watch` doesn't update files
- improve `bit watch` to watch directories instead of only files to support addition / deletion

Expand Down
79 changes: 79 additions & 0 deletions e2e/commands/watch.e2e.2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import chai, { expect } from 'chai';
import path from 'path';
import Helper from '../e2e-helper';
import * as fixtures from '../fixtures/fixtures';

chai.use(require('chai-fs'));

describe('bit watch command', function () {
this.timeout(0);
const helper = new Helper();
after(() => {
helper.destroyEnv();
});
describe('watch', () => {
let scopeAfterBuild;
before(() => {
helper.setNewLocalAndRemoteScopes();
helper.populateWorkspaceWithComponents();
helper.importDummyCompiler();
helper.build();
scopeAfterBuild = helper.cloneLocalScope();
});
describe('as author', () => {
let watchProcess;
before(async () => {
watchProcess = await helper.watch();
});
after(() => {
watchProcess.kill();
});
describe('changing a file', () => {
before(() => {
helper.createFile('utils', 'is-string.js', fixtures.isStringV2);
});
it('should update the dist', async () => {
await helper.waitForWatchToRebuildComponent(watchProcess);
const distContent = helper.readFile('dist/utils/is-string.js');
expect(distContent).to.equal(fixtures.isStringV2);
});
describe('changing it again', () => {
before(() => {
helper.createFile('utils', 'is-string.js', fixtures.isStringV3);
});
it('should update the dist again', async () => {
await helper.waitForWatchToRebuildComponent(watchProcess);
const distContent = helper.readFile('dist/utils/is-string.js');
expect(distContent).to.equal(fixtures.isStringV3);
});
});
});
});
describe('as imported', () => {
let watchProcess;
before(async () => {
helper.getClonedLocalScope(scopeAfterBuild);
helper.tagAllComponents();
helper.exportAllComponents();
helper.reInitLocalScope();
helper.addRemoteScope();
helper.addRemoteEnvironment();
helper.importManyComponents(['bar/foo', 'utils/is-string', 'utils/is-type']);
watchProcess = await helper.watch();
});
after(() => {
watchProcess.kill();
});
describe('adding a file to a tracked directory', () => {
before(() => {
helper.outputFile('components/utils/is-string/new-file.js', 'console.log();');
});
it('should create a dist file for that new file', async () => {
await helper.waitForWatchToRebuildComponent(watchProcess);
const expectedFile = path.join(helper.localScopePath, 'components/utils/is-string/dist/new-file.js');
expect(expectedFile).to.be.a.file();
});
});
});
});
});
36 changes: 34 additions & 2 deletions e2e/e2e-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import chalk from 'chalk';
import glob from 'glob';
import os from 'os';
import path from 'path';
import childProcess from 'child_process';
import childProcess, { ChildProcess } from 'child_process';
import fs from 'fs-extra';
import json from 'comment-json';
import { expect } from 'chai';
Expand All @@ -16,6 +16,7 @@ import * as fixtures from './fixtures/fixtures';
import { NOTHING_TO_TAG_MSG } from '../src/cli/commands/public-cmds/tag-cmd';
import { removeChalkCharacters } from '../src/utils';
import { FileStatus } from '../src/consumer/versions-ops/merge-version';
import { STARTED_WATCHING_MSG, WATCHER_COMPLETE_BUILD_MSG } from '../src/consumer/component-ops/watch-components';

const generateRandomStr = (size: number = 8): string => {
return Math.random()
Expand Down Expand Up @@ -53,7 +54,7 @@ export default class Helper {
}

// #region General
runCmd(cmd: string, cwd: string = this.localScopePath) {
runCmd(cmd: string, cwd: string = this.localScopePath): string {
if (this.debugMode) console.log(rightpad(chalk.green('cwd: '), 20, ' '), cwd); // eslint-disable-line
if (cmd.startsWith('bit ')) cmd = cmd.replace('bit', this.bitBin);
if (this.debugMode) console.log(rightpad(chalk.green('command: '), 20, ' '), cmd); // eslint-disable-line
Expand All @@ -62,6 +63,37 @@ export default class Helper {
return cmdOutput.toString();
}

watch(): Promise<ChildProcess> {
const cmd = `${this.bitBin} watch --verbose`;
if (this.debugMode) console.log(rightpad(chalk.green('command: '), 20, ' '), cmd); // eslint-disable-line
return new Promise((resolve, reject) => {
const watchProcess = childProcess.exec(cmd, { cwd: this.localScopePath, detached: true });
watchProcess.stdout.on('data', (data) => {
if (this.debugMode) console.log(`stdout: ${data}`);
if (data.includes(STARTED_WATCHING_MSG)) {
if (this.debugMode) console.log('bit watch is up and running');
resolve(watchProcess);
}
});
watchProcess.stderr.on('data', (data) => {
if (this.debugMode) console.log(`stderr: ${data}`);
reject(data);
});
watchProcess.on('close', (code) => {
if (this.debugMode) console.log(`child process exited with code ${code}`);
});
});
}
async waitForWatchToRebuildComponent(watchProcess: ChildProcess) {
return new Promise((resolve) => {
watchProcess.stdout.on('data', (data) => {
if (data.includes(WATCHER_COMPLETE_BUILD_MSG)) {
resolve(data);
}
});
});
}

parseOptions(options: Object): string {
const value = Object.keys(options)
.map((key) => {
Expand Down
2 changes: 2 additions & 0 deletions e2e/fixtures/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export const isString =
"const isType = require('./is-type.js'); module.exports = function isString() { return isType() + ' and got is-string'; };";
export const isStringV2 =
"const isType = require('./is-type.js'); module.exports = function isString() { return isType() + ' and got is-string v2'; };";
export const isStringV3 =
"const isType = require('./is-type.js'); module.exports = function isString() { return isType() + ' and got is-string v3'; };";
export const isStringSpec = testShouldPass => `const expect = require('chai').expect;
const isString = require('./is-string.js');

Expand Down
Loading