Convert cloneRepo to promises, and added test

This commit is contained in:
Shahan Nedadahandeh 2023-03-21 00:32:48 -04:00
parent 56b119db1e
commit 026bf38a59
8 changed files with 97 additions and 65 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"editor.formatOnSave": true
}

16
package-lock.json generated
View File

@ -23,13 +23,13 @@
"uuidv4": "^6.2.13"
},
"devDependencies": {
"@types/jest": "^29.2.5",
"@types/jest": "^29.5.0",
"@types/node": "^18.7.16",
"@types/supertest": "^2.0.12",
"better-sqlite3": "^8.0.1",
"concurrently": "^7.4.0",
"cross-env": "^7.0.3",
"jest": "^29.3.1",
"jest": "^29.5.0",
"nodemon": "^2.0.19",
"supertest": "^6.3.3"
}
@ -1432,9 +1432,9 @@
}
},
"node_modules/@types/jest": {
"version": "29.4.0",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.4.0.tgz",
"integrity": "sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==",
"version": "29.5.0",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz",
"integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==",
"dev": true,
"dependencies": {
"expect": "^29.0.0",
@ -8633,9 +8633,9 @@
}
},
"@types/jest": {
"version": "29.4.0",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.4.0.tgz",
"integrity": "sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==",
"version": "29.5.0",
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz",
"integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==",
"dev": true,
"requires": {
"expect": "^29.0.0",

View File

@ -9,7 +9,8 @@
"compile": "rimraf build && tsc",
"server": "node build/server.js",
"server:dev": "nodemon build/server.js",
"ts:watch": "tsc --watch"
"ts:watch": "tsc --watch",
"test": "tsc && jest build/test"
},
"keywords": [],
"author": "",
@ -29,13 +30,13 @@
"uuidv4": "^6.2.13"
},
"devDependencies": {
"@types/jest": "^29.2.5",
"@types/jest": "^29.5.0",
"@types/node": "^18.7.16",
"@types/supertest": "^2.0.12",
"better-sqlite3": "^8.0.1",
"concurrently": "^7.4.0",
"cross-env": "^7.0.3",
"jest": "^29.3.1",
"jest": "^29.5.0",
"nodemon": "^2.0.19",
"supertest": "^6.3.3"
}

View File

@ -1,59 +1,78 @@
import { mkdtemp } from "fs";
import { execSync } from "child_process";
import { promises as fs } from "fs";
import { tmpdir } from "os";
import { join } from "path";
import util from "util";
const exec = util.promisify(require("child_process").exec);
const { exec } = require("child_process");
const {uuid} = require("uuidv4")
import { uuid } from "uuidv4";
function checkError(error){
if (error) {
console.log(`error: ${error.message}`);
return;
function throwIfError(error) {
if (error != undefined) {
console.error(`error: ${error.message}`);
}
}
export function cloneRepo(httpAddr, callback){
mkdtemp(join(tmpdir(), 'dt-'), (err, folder) => {
if (err) throw err;
var fString = folder;
exec("git clone " + httpAddr + " " + fString, (error, stdout, stderr) => {
checkError(error)
console.log(`stdout: ${stderr}`);
createAndPublishNewBranch(fString);
callback(fString);
return fString;
})
})
export async function cloneRepo(httpAddr: string) {
const tmpFolderPath = await fs.mkdtemp(join(tmpdir(), "dt-"));
console.log(`Cloning repo to directory: ${tmpFolderPath}`);
try {
const stdOut = execSync(
`git clone ${httpAddr} ${tmpFolderPath}`
).toString();
console.log(`Clone output is: ${stdOut}`);
} catch (error) {
console.error(
`Failed to clone repo: ${error.status} ${
error.message
} ${error.stderr.toString()} ${error.stdout.toString()}`
);
throw error.message;
}
return tmpFolderPath;
}
export function pushRepo(repoPath){
export function pushRepo(repoPath) {
exec("git -C " + repoPath + " push", (error, stdout, stderr) => {
checkError(error)
throwIfError(error);
console.log(`stdout: ${stderr}`);
})
});
}
export function commitRepo(repoPath){
export function commitRepo(repoPath) {
exec("git -C " + repoPath + " add .", (error, stdout, stderr) => {
checkError(error)
exec("git -C " + repoPath + " commit -m \"generic commit message\"", (error, stdout, stderr) => {
checkError(error)
console.log(`stdout: ${stderr}`);
})
})
throwIfError(error);
exec(
"git -C " + repoPath + ' commit -m "generic commit message"',
(error, stdout, stderr) => {
throwIfError(error);
console.log(`stdout: ${stderr}`);
}
);
});
}
function createAndPublishNewBranch(repoPath){
function createAndPublishNewBranch(repoPath) {
var id = uuid();
exec("git -C " + repoPath + " checkout -b " + id + " && git -C " + repoPath + " push -u origin "+ id, (error, stdout, stderr) => {
checkError(error)
console.log(`stdout: ${stderr}`);
return id;
}
)
exec(
"git -C " +
repoPath +
" checkout -b " +
id +
" && git -C " +
repoPath +
" push -u origin " +
id,
(error, stdout, stderr) => {
throwIfError(error);
console.log(`stdout: ${stderr}`);
return id;
}
);
}
export function removeRepo(repoPath){
exec("rm -r "+repoPath);
export function removeRepo(repoPath) {
exec("rm -r " + repoPath);
}

View File

@ -43,7 +43,7 @@ const storage = multer.diskStorage({
const fileFilter = (
_,
file: Express.Multer.File,
file: express.Multer.File,
callback: FileFilterCallback
) => {
let mimeType = file.mimetype.toLowerCase();

View File

@ -0,0 +1,22 @@
import { cloneRepo, commitRepo, pushRepo, removeRepo } from "../gitClient";
import { existsSync, readdirSync } from "fs";
test("successfully clones repo", async () => {
const folderPath = await cloneRepo("https://github.com/octocat/Spoon-Knife");
expect(existsSync(folderPath)).toBe(true);
const directoryContents = readdirSync(folderPath);
expect(directoryContents).toContain("index.html");
expect(directoryContents).toContain("README.md");
});
test("throws error if can't clone repo", async () => {
let thrownError = undefined;
try {
await cloneRepo("kdskdfj");
} catch (error) {
thrownError = error;
}
expect(thrownError).not.toBeUndefined();
});

View File

@ -1,13 +0,0 @@
import { exec } from 'child_process';
import { SimpleConsoleLogger } from 'typeorm'
import {cloneRepo, commitRepo, pushRepo, removeRepo} from './gitClient'
//Sample usage
cloneRepo('https://git.csclub.uwaterloo.ca/www/library.git', (temporaryDir) => {
//temporaryDir is the temp directory name
// exec("touch "+ temporaryDir + "/thing.js"); (add a new file to the directory)
commitRepo(temporaryDir); // commit to the directory
pushRepo(temporaryDir); // push to the directory
removeRepo(temporaryDir); // remove the directory
});

View File

@ -8,7 +8,7 @@
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"outDir": "build",
"resolveJsonModule": true,
"resolveJsonModule": true
},
"include": ["src"]
}