Skip to content

Commit

Permalink
Merge pull request #5 from nomo-app/extractAndCheckFiles
Browse files Browse the repository at this point in the history
Extract and check files(validate manifest)
  • Loading branch information
dev2-nomo authored Nov 22, 2023
2 parents 4796073 + fef7358 commit 29d774e
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 26 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ nomo_cli.config.js
out/nomo_manifest.json

# Webon Files
out/nomo.tar.gz
out/nomo.tar.gz

# Cached WebOn Files
cache/
Empty file added cache/.gitkeep
Empty file.
77 changes: 77 additions & 0 deletions src/util/extract-tar-gz.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { logFatal } from "../util/util";
import * as tar from "tar";
import { resolve, join } from "path";
import { existsSync, mkdirSync } from "fs";

const requiredFiles = ["index.html", "nomo_icon.svg", "nomo_manifest.json"];
const cacheDirectory = "./cache";
const cacheOutDirectory = "./cache/out";

export async function extractAndCache(args: {
tarFilePath: string;
destinationDir?: string;
}) {
const { tarFilePath, destinationDir = cacheDirectory } = args;

if (!existsSync(destinationDir)) {
console.log(`Creating cache directory: ${destinationDir}`);
mkdirSync(destinationDir);
}

try {
await tar.x({
file: tarFilePath,
cwd: resolve(destinationDir),
});

/* Maybe possible to fetch fileNames as stream before extracting:
const getEntryFilenamesSync = (tarFilePath as any) => {
const filenames = requiredFiles;
tar.t({
file: tarFilePath,
onentry: (entry) => filenames.push(entry.path),
sync: true,
});
return filenames
};*/

const missingFiles = requiredFiles.filter((file) => {
const filePath = join(resolve(destinationDir), "/out/", file);
return !existsSync(filePath);
});
if (missingFiles.length > 0) {
logFatal(
`Error: The following required files are missing: ${missingFiles.join(
", "
)}`
);
}
console.log(`Tar.gz file extracted successfully to: ${destinationDir}`);
} catch (error) {
logFatal(`Error extracting tar.gz file: ${error}`);
}
}

export function getCachedIndexHtmlPath(): string {
const path = join(resolve(cacheOutDirectory), "index.html");
if (!existsSync(path)) {
logFatal(`Error: ${path} is missing.`);
}
return path;
}

export function getCachedNomoIconPath(): string {
const path = join(resolve(cacheOutDirectory), "nomo_icon.svg");
if (!existsSync(path)) {
logFatal(`Error: ${path} is missing.`);
}
return path;
}

export function getCachedNomoManifestPath(): string {
const path = join(resolve(cacheOutDirectory), "nomo_manifest.json");
if (!existsSync(path)) {
logFatal(`Error: ${path} is missing.`);
}
return path;
}
22 changes: 22 additions & 0 deletions src/util/ssh-manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { logFatal, readCliConfig, runCommandsSequentially } from "../util/util";
import {
extractAndCache,
getCachedIndexHtmlPath,
getCachedNomoIconPath,
getCachedNomoManifestPath,
} from "../util/extract-tar-gz";
import { NomoManifest } from "../init/interface";
import * as fs from "fs";
import { validateManifest } from "../util/validate-manifest";

let sshConnect = "";

Expand All @@ -21,9 +30,16 @@ export async function connectToSSH(args: {
const portOption = sshPort ? `-p ${sshPort}` : "";
sshConnect = `ssh -t ${sshHost} ${portOption}`;

await extractAndCache({
tarFilePath: archive,
});
const manifestPath = getCachedNomoManifestPath();
manifestChecks(manifestPath);
const commands = [ls(), checkCreateDir(sshBaseDir)];

await runCommandsSequentially(commands);

const iconPath = getCachedNomoIconPath();
}

function ls(): string {
Expand All @@ -34,3 +50,9 @@ function checkCreateDir(sshBaseDir: string): string {
const mkdirCommand = `if [ ! -d ${sshBaseDir} ]; then mkdir -p ${sshBaseDir} && echo "Directory created"; else echo "Directory already exists"; fi`;
return `${sshConnect} "${mkdirCommand}"`;
}

function manifestChecks(manifestFilePath: string) {
const nomoManifestContent = fs.readFileSync(manifestFilePath, "utf-8");
const nomoManifest: NomoManifest = JSON.parse(nomoManifestContent);
validateManifest(nomoManifest);
}
69 changes: 44 additions & 25 deletions src/util/validate-manifest.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { NomoManifest } from "../init/interface";
import { logFatal } from "../util/util";

class WebOnError extends Error {
constructor(message: string) {
super(message);
this.name = "WebOnError";
logFatal(this.message);
}
}

async function validateManifest(
manifest: NomoManifest,
webonUrl: string,
{ devMode }: { devMode: boolean }
): Promise<void> {
export async function validateManifest(manifest: NomoManifest): Promise<void> {
const webonVersion = manifest.webon_version;

if (!_isValidSemanticVersion(webonVersion)) {
throw new WebOnError(
`webon_version ${webonVersion} does not comply with semantic versioning regexp`
Expand All @@ -36,40 +35,60 @@ async function validateManifest(
}

const minNomoVersion = manifest.min_nomo_version;
if (minNomoVersion != null) {
if (!_isValidSemanticVersion(minNomoVersion)) {
throw new WebOnError(
`min_nomo_version ${minNomoVersion} does not comply with semantic versioning regexp`
);
}
// Assume you have a function similar to versionTwoGreaterThanVersionOne
const currentVersion = "1.2.0"; // You need to replace this with the actual version
if (versionTwoGreaterThanVersionOne(currentVersion, minNomoVersion)) {
throw new WebOnError(
`Nomo App outdated! This WebOn requires ${minNomoVersion}, but the current version is ${currentVersion}`
);
}
const webOnVersion = manifest.webon_version;

//if (minNomoVersion != null) {
// if (!_isValidSemanticVersion(minNomoVersion)) {
// throw new WebOnError(
// `min_nomo_version ${minNomoVersion} does not comply with semantic versioning regexp`
// );
// }
// Assume you have a function similar to versionTwoGreaterThanVersionOne
const currentVersion = "0.1.0";
// TODO: set the currentVersion to manifest.webon_version and compare it to the manifest version from server
console.log("currentVersion: " + currentVersion);
console.log("webOnversion" + webOnVersion);
if (versionTwoGreaterThanVersionOne(currentVersion, webOnVersion)) {
throw new WebOnError(
`Your WebOn is outdated! This WebOn requires ${webOnVersion}, but the current version is ${currentVersion}`
);
} else if (currentVersion === webOnVersion) {
throw new WebOnError(
`Your webOn version is equal to the version your already uploaded: ${webOnVersion}, please update your webOn_version in nomo_manifest.json.`
);
}
}

//}

function _isValidSemanticVersion(version: string): boolean {
const pattern = /^(\d+)\.(\d+)\.(\d+)$/;
const regex = new RegExp(pattern);
return regex.test(version);
}

// Assuming versionTwoGreaterThanVersionOne is a function you have implemented
function versionTwoGreaterThanVersionOne(
versionTwo: string,
versionOne: string
): boolean {
// Implement the comparison logic here
const v1Components = versionOne.split(".");
const v2Components = versionTwo.split(".");

for (let i = 0; i < Math.max(v1Components.length, v2Components.length); i++) {
const v1 = parseInt(v1Components[i] || "0", 10);
const v2 = parseInt(v2Components[i] || "0", 10);

if (v1 > v2) {
return false;
} else if (v1 < v2) {
return true;
}
}

return false;
}

export function isValidWebOnId(webon_id: string): boolean {
const webonIdRegExp =
/^(?:[a-zA-Z0-9_-]+\.)*[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)+$/;
return webonIdRegExp.test(webon_id);
}
const webonIdRegExp =
/^(?:[a-zA-Z0-9_-]+\.)*[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)+$/;
return webonIdRegExp.test(webon_id);
}

0 comments on commit 29d774e

Please sign in to comment.