Skip to content
This repository has been archived by the owner on Jan 16, 2023. It is now read-only.

Commit

Permalink
refactored port selection in netstat function to select from behind, …
Browse files Browse the repository at this point in the history
…added -a flag to netstat
  • Loading branch information
ArloGui committed May 9, 2020
1 parent ea90767 commit 410e067
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 172 deletions.
2 changes: 1 addition & 1 deletion src/processes/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const netStatCommandLibrary = {
},
darwin: {
cmd: 'netstat',
args: ['-v', '-n', '-p', 'tcp'],
args: ['-a', '-v', '-n', '-p', 'tcp'],
},
win32: {
cmd: 'netstat.exe',
Expand Down
338 changes: 167 additions & 171 deletions src/processes/process.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,196 +7,192 @@ import logger from "../utils/logger";
const { netstatCommand, searchCommand, platform } = commands;

class ProcessService {
public port: number;
private rootDir: string;
private fileName: string;
private vscode;
private statusText;
private aesopEmitter;
constructor({ rootDir, vscode, statusText, aesopEmitter }) {
this.rootDir = rootDir;
this.vscode = vscode;
this.statusText = statusText;
this.aesopEmitter = aesopEmitter;
this.fileName = "@process.service.ts";
this.startStorybook = this.startStorybook.bind(this);
this.findLocation = this.findLocation.bind(this);
this.locationViaNetStat = this.locationViaNetStat.bind(this);
}

//make location checks private methods that are referred to in a findLocation check

public findLocation(pid) {
logger.write(
"Attempting to find Storybook Location",
this.fileName,
"findLocation"
);
const processPid = parseInt(pid).toString();
this.locationViaNetStat(processPid);
}

//test
private locationViaNetStat(processPid) {
logger.write(
"Attempting to locate via Netstat",
this.fileName,
"locationViaNetstat"
);

const netStatProcess = child_process.spawnSync(
netstatCommand.cmd,
netstatCommand.args
);
const grepProcess = child_process.spawnSync(
searchCommand.cmd,
[processPid],
{ input: netStatProcess.stdout, encoding: "utf-8" }
);

const data = grepProcess.stdout;

const parts = data.split(/\s/).filter(String);
logger.write(
`Getting data from grep process ${parts}`,
this.fileName,
"locationViaNetstat/grepProcess"
);
//@TODO: refactor for platform specific or grab port dynamically
//Might be useful to use table-parser. idk if that works w/ windows tho

const partIndex = platform === "win32" ? 1 : 3;
// this.port = parseInt(parts[partIndex].replace(/[^0-9]/g, ""));
if (platform === "darwin") {
const localAddress = parts[partIndex].split(".");
this.port = parseInt(localAddress[1]);
} else {
// const partIndex = platform === "win32" ? 1 : 3;
this.port = parseInt(parts[partIndex].replace(/[^0-9]/g, ""));
public port: number;
private rootDir: string;
private fileName: string;
private vscode;
private statusText;
private aesopEmitter;
constructor({ rootDir, vscode, statusText, aesopEmitter }) {
this.rootDir = rootDir;
this.vscode = vscode;
this.statusText = statusText;
this.aesopEmitter = aesopEmitter;
this.fileName = "@process.service.ts";
this.startStorybook = this.startStorybook.bind(this);
this.findLocation = this.findLocation.bind(this);
this.locationViaNetStat = this.locationViaNetStat.bind(this);
}

this.aesopEmitter.emit("create_webview", this.port);
logger.write(
`Found Storybook location via Netstat`,
this.fileName,
"locationViaNetstat/grepProcess"
);
}

//MAYBE separate this function?
//possibly break it down as well into:
//grab json script
//start storybook

startStorybook() {
let data: Buffer;
logger.write(
"Starting Storybook for you!",
this.fileName,
"startStorybook"
);

try {
data = fs.readFileSync(path.join(this.rootDir, "package.json"));
logger.write(
"Obtained data from package.json",
this.fileName,
"startStorybook"
);
} catch (err) {
this.vscode.window.showErrorMessage(
`Aesop is attempting to read ${this.rootDir}. Is there a package.json file here?`
);
this.statusText.dispose();
return false;
//make location checks private methods that are referred to in a findLocation check

public findLocation(pid) {
logger.write(
"Attempting to find Storybook Location",
this.fileName,
"findLocation"
);
const processPid = parseInt(pid).toString();
this.locationViaNetStat(processPid);
}

this.statusText.text = `Checking package.json...`;
//test
private locationViaNetStat(processPid) {
logger.write(
"Attempting to locate via Netstat",
this.fileName,
"locationViaNetstat"
);

const netStatProcess = child_process.spawnSync(
netstatCommand.cmd,
netstatCommand.args
);
const grepProcess = child_process.spawnSync(
searchCommand.cmd,
[processPid],
{ input: netStatProcess.stdout, encoding: "utf-8" }
);

const data = grepProcess.stdout;

const parts = data.split(/\s/).filter(String);

const partIndex = (platform === 'win32') ? 1 : 3;
const localAddress = parts[partIndex]

let portStr = ''
const nanRegex = new RegExp('[^0-9]')

for (let i = localAddress.length - 1; i >= 0; i--) {
if (nanRegex.test(localAddress[i])) break;
portStr = localAddress[i] + portStr;
}

this.port = parseInt(portStr);
this.aesopEmitter.emit('create_webview', this.port);

//check if the user has custom configurations for starting storybook
logger.write(
`Found Storybook location via Netstat`,
this.fileName,
"locationViaNetstat/grepProcess"
);
}

let packageJSON = JSON.parse(data.toString());
let storybookScript = packageJSON.scripts.storybook;
let retrievedScriptArray = storybookScript.split(" ");
//MAYBE separate this function?
//possibly break it down as well into:
//grab json script
//start storybook

startStorybook() {
let data: Buffer;
logger.write(
"Starting Storybook for you!",
this.fileName,
"startStorybook"
);

try {
data = fs.readFileSync(path.join(this.rootDir, "package.json"));
logger.write(
"Obtained data from package.json",
this.fileName,
"startStorybook"
);
} catch (err) {
this.vscode.window.showErrorMessage(
`Aesop is attempting to read ${this.rootDir}. Is there a package.json file here?`
);
this.statusText.dispose();
return false;
}

//older Windows systems support here: check platform, change process command accordingly
this.statusText.text = `Checking package.json...`;

const sbCLI = "./node_modules/.bin/start-storybook";
const sbStartIndex = retrievedScriptArray.indexOf("start-storybook");
retrievedScriptArray[sbStartIndex] = sbCLI;
retrievedScriptArray.push("--ci");
//check if the user has custom configurations for starting storybook

//launch storybook using a child process
const childProcessArguments =
platform === "win32" ? ["run", "storybook"] : retrievedScriptArray;
const childProcessCommand = platform === "win32" ? "npm.cmd" : "node";
let packageJSON = JSON.parse(data.toString());
let storybookScript = packageJSON.scripts.storybook;
let retrievedScriptArray = storybookScript.split(" ");

const runSb = child_process.spawn(
childProcessCommand,
childProcessArguments,
{
cwd: this.rootDir,
env: process.env,
windowsHide: false,
windowsVerbatimArguments: true,
}
);
//older Windows systems support here: check platform, change process command accordingly

this.statusText.text = `Done looking. Aesop will now launch Storybook in the background.`;
const sbCLI = "./node_modules/.bin/start-storybook";
const sbStartIndex = retrievedScriptArray.indexOf("start-storybook");
retrievedScriptArray[sbStartIndex] = sbCLI;
retrievedScriptArray.push("--ci");

runSb.stdout.setEncoding("utf8");
//launch storybook using a child process
const childProcessArguments =
platform === "win32" ? ["run", "storybook"] : retrievedScriptArray;
const childProcessCommand = platform === "win32" ? "npm.cmd" : "node";

let counter = 0;
const runSb = child_process.spawn(
childProcessCommand,
childProcessArguments,
{
cwd: this.rootDir,
env: process.env,
windowsHide: false,
windowsVerbatimArguments: true,
}
);

//Storybook outputs three messages to the terminal as it spins up
//grab the port from the last message to listen in on the process
this.statusText.text = `Done looking. Aesop will now launch Storybook in the background.`;

let callback = (data) => {
let str = data.toString().split(" ");
counter += 1;
logger.write(
`This is data: ${data.toString()}`,
this.fileName,
"startStorybook/runSb"
);
runSb.stdout.setEncoding("utf8");

if (counter >= 2) {
for (let i = 165; i < str.length; i += 1) {
if (str[i].includes("localhost")) {
const path = str[i];
const regExp = /[^0-9]/g;
this.port = path.replace(regExp, "");
let counter = 0;

//Storybook outputs three messages to the terminal as it spins up
//grab the port from the last message to listen in on the process

let callback = (data) => {
let str = data.toString().split(" ");
counter += 1;
logger.write(
"Found instance in stdout that includes localhost",
this.fileName,
"startStorybook/runSb"
`This is data: ${data.toString()}`,
this.fileName,
"startStorybook/runSb"
);
this.aesopEmitter.emit("create_webview", this.port);
return true;
}
}
}
};
callback = callback.bind(this);

runSb.stdout.on("data", callback);

runSb.stderr.on("data", (data) => {
console.error(`stderr: ${data}`);
logger.write(
`This is stderr: ${data.toString()}`,
this.fileName,
"startStorybook/runSb"
);
// process.exit(1);
});

//make sure the child process is terminated on process exit
runSb.on("close", (code) => {
console.log(`child process exited with code ${code}`);
});
}

if (counter >= 2) {
for (let i = 165; i < str.length; i += 1) {
if (str[i].includes("localhost")) {
const path = str[i];
const regExp = /[^0-9]/g;
this.port = path.replace(regExp, "");

logger.write(
"Found instance in stdout that includes localhost",
this.fileName,
"startStorybook/runSb"
);
this.aesopEmitter.emit("create_webview", this.port);
return true;
}
}
}
};
callback = callback.bind(this);

runSb.stdout.on("data", callback);

runSb.stderr.on("data", (data) => {
console.error(`stderr: ${data}`);
logger.write(
`This is stderr: ${data.toString()}`,
this.fileName,
"startStorybook/runSb"
);
// process.exit(1);
});

//make sure the child process is terminated on process exit
runSb.on("close", (code) => {
console.log(`child process exited with code ${code}`);
});
}
}

export default ProcessService;

0 comments on commit 410e067

Please sign in to comment.