Skip to content

Commit

Permalink
Add "createTempDir" and "zip" function to shellFS
Browse files Browse the repository at this point in the history
  • Loading branch information
OrigamingWasTaken committed Oct 6, 2024
1 parent 8d5049b commit a66cb8b
Showing 1 changed file with 175 additions and 86 deletions.
261 changes: 175 additions & 86 deletions frontend/src/windows/main/ts/tools/shellfs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,26 +167,6 @@ export interface OpenOptions extends ExecuteOptions {
* Opens the file or directory at the specified path.
* @param path - The path of the file or directory to open.
* @param options - Options for the open command and execution.
* @param options.editInTextEdit - Open the file with TextEdit (-e)
* @param options.openInDefaultTextEditor - Open the file with default text editor (-t)
* @param options.readStdin - Read input from standard input and open with TextEdit (-f)
* @param options.freshInstance - Open the application "fresh," without restoring windows (-F)
* @param options.wait - Wait for the application to terminate before returning (-W)
* @param options.reveal - Reveal the file in the Finder instead of opening it (-R)
* @param options.newInstance - Open a new instance of the application (-n)
* @param options.background - Do not bring the application to the foreground (-g)
* @param options.hidden - Launch the app hidden (-j)
* @param options.openHeaderFile - Search for and open the header file (-h)
* @param options.url - URL to open (-u)
* @param options.sdk - SDK to use (-s)
* @param options.bundleIdentifier - Bundle identifier of the application to open (-b)
* @param options.application - Application to use for opening the file (-a)
* @param options.env - Environment variables to set (--env)
* @param options.stderr - Path to redirect stderr (--stderr)
* @param options.stdin - Path to redirect stdin (--stdin)
* @param options.stdout - Path to redirect stdout (--stdout)
* @param options.architecture - Architecture to use (--arch)
* @param options.args - Additional arguments to pass to the application (--args)
*/
export async function open(path: string, options: OpenOptions = {}): Promise<void> {
const args: string[] = [];
Expand Down Expand Up @@ -225,37 +205,41 @@ export async function open(path: string, options: OpenOptions = {}): Promise<voi
}

type PermissionTarget = 'u' | 'g' | 'o' | 'a';

/**
* Options for the chmod command.
*/
export interface ChmodOptions extends ExecuteOptions {
/** Apply changes recursively to directories and their contents (-R) */
recursive?: boolean;
/** Use the numeric mode specification */
numeric?: boolean;
/** Change the file mode bits of the symbolic link itself, not the file it points to (-h) */
modifySymlink?: boolean;
/** Use silent mode; suppress most error messages (-f) */
silent?: boolean;
/** Display information about the changes made (-v) */
verbose?: boolean;
/** Don't change any file modes; useful for testing (-n) */
dryRun?: boolean;
/** Change the user ID of the file (-u) */
setUserId?: boolean;
/** Change the group ID of the file (-g) */
setGroupId?: boolean;
/** Set the sticky bit (-t) */
setSticky?: boolean;
/** Remove read permission (u-r, g-r, o-r, a-r) */
removeRead?: PermissionTarget;
/** Remove write permission (u-w, g-w, o-w, a-w) */
removeWrite?: PermissionTarget;
/** Remove execute permission (u-x, g-x, o-x, a-x) */
removeExecute?: PermissionTarget;
/** Add read permission (u+r, g+r, o+r, a+r) */
addRead?: PermissionTarget;
/** Add write permission (u+w, g+w, o+w, a+w) */
addWrite?: PermissionTarget;
/** Add execute permission (u+x, g+x, o+x, a+x) */
addExecute?: PermissionTarget;
/** Apply changes recursively to directories and their contents (-R) */
recursive?: boolean;
/** Use the numeric mode specification */
numeric?: boolean;
/** Change the file mode bits of the symbolic link itself, not the file it points to (-h) */
modifySymlink?: boolean;
/** Use silent mode; suppress most error messages (-f) */
silent?: boolean;
/** Display information about the changes made (-v) */
verbose?: boolean;
/** Don't change any file modes; useful for testing (-n) */
dryRun?: boolean;
/** Change the user ID of the file (-u) */
setUserId?: boolean;
/** Change the group ID of the file (-g) */
setGroupId?: boolean;
/** Set the sticky bit (-t) */
setSticky?: boolean;
/** Remove read permission (u-r, g-r, o-r, a-r) */
removeRead?: PermissionTarget;
/** Remove write permission (u-w, g-w, o-w, a-w) */
removeWrite?: PermissionTarget;
/** Remove execute permission (u-x, g-x, o-x, a-x) */
removeExecute?: PermissionTarget;
/** Add read permission (u+r, g+r, o+r, a+r) */
addRead?: PermissionTarget;
/** Add write permission (u+w, g+w, o+w, a+w) */
addWrite?: PermissionTarget;
/** Add execute permission (u+x, g+x, o+x, a+x) */
addExecute?: PermissionTarget;
}

/**
Expand All @@ -265,46 +249,149 @@ export interface ChmodOptions extends ExecuteOptions {
* @param options - Options for the chmod command and execution.
*/
export async function chmod(path: string, mode: string, options: ChmodOptions = {}): Promise<void> {
const args: string[] = [];
const args: string[] = [];

if (options.recursive) args.push('-R');
if (options.modifySymlink) args.push('-h');
if (options.silent) args.push('-f');
if (options.verbose) args.push('-v');
if (options.dryRun) args.push('-n');

if (options.numeric) {
args.push(mode);
} else {
let symbolicMode = '';

const applyPermission = (type: PermissionTarget, action: '+' | '-', permission: 'r' | 'w' | 'x') => {
symbolicMode += `${type}${action}${permission},`;
};

if (options.setUserId) symbolicMode += 'u+s,';
if (options.setGroupId) symbolicMode += 'g+s,';
if (options.setSticky) symbolicMode += '+t,';

if (options.removeRead) applyPermission(options.removeRead, '-', 'r');
if (options.removeWrite) applyPermission(options.removeWrite, '-', 'w');
if (options.removeExecute) applyPermission(options.removeExecute, '-', 'x');
if (options.addRead) applyPermission(options.addRead, '+', 'r');
if (options.addWrite) applyPermission(options.addWrite, '+', 'w');
if (options.addExecute) applyPermission(options.addExecute, '+', 'x');

if (symbolicMode) {
args.push(symbolicMode.slice(0, -1)); // Remove trailing comma
} else {
args.push(mode);
}
}
if (options.recursive) args.push('-R');
if (options.modifySymlink) args.push('-h');
if (options.silent) args.push('-f');
if (options.verbose) args.push('-v');
if (options.dryRun) args.push('-n');

args.push(path);
if (options.numeric) {
args.push(mode);
} else {
let symbolicMode = '';

const applyPermission = (type: PermissionTarget, action: '+' | '-', permission: 'r' | 'w' | 'x') => {
symbolicMode += `${type}${action}${permission},`;
};

if (options.setUserId) symbolicMode += 'u+s,';
if (options.setGroupId) symbolicMode += 'g+s,';
if (options.setSticky) symbolicMode += '+t,';

if (options.removeRead) applyPermission(options.removeRead, '-', 'r');
if (options.removeWrite) applyPermission(options.removeWrite, '-', 'w');
if (options.removeExecute) applyPermission(options.removeExecute, '-', 'x');
if (options.addRead) applyPermission(options.addRead, '+', 'r');
if (options.addWrite) applyPermission(options.addWrite, '+', 'w');
if (options.addExecute) applyPermission(options.addExecute, '+', 'x');

if (symbolicMode) {
args.push(symbolicMode.slice(0, -1)); // Remove trailing comma
} else {
args.push(mode);
}
}

args.push(path);

await shell('chmod', args, options);
}

/**
* Options for creating a temporary directory.
*/
export interface CreateTempDirOptions extends ExecuteOptions {
/** The directory under which to create the temporary directory. Defaults to system temp directory. */
baseDir?: string;
/** A prefix for the directory name. */
prefix?: string;
/** If true, creates a directory that's only readable and writable by the current user. */
private?: boolean;
}

await shell('chmod', args, options);
/**
* Creates a temporary directory.
* @param options - Options for creating the temporary directory.
* @returns A promise that resolves with the path of the created temporary directory.
*/
export async function createTempDir(options: CreateTempDirOptions = {}): Promise<string> {
const args: string[] = ['-d'];

if (options.baseDir) {
args.push('-p', options.baseDir);
}

if (options.prefix) {
args.push(options.prefix);
} else {
args.push('tmp.XXXXXX');
}

if (options.private) {
args.unshift('-p');
}

const result = await shell('mktemp', args, options);
return result.stdOut.trim();
}

/**
* Options for the zip command.
*/
/**
* Options for the zip command.
*/
export interface ZipOptions extends ExecuteOptions {
/** Compression level (0-9, 0=no compression, 9=maximum compression) */
compressionLevel?: number;
/** Include hidden files (those starting with a dot) */
includeHidden?: boolean;
/** Recurse into directories */
recursive?: boolean;
/** Exclude specific files or patterns */
exclude?: string[];
/** Store symlinks as symlinks instead of the file they point to */
symlinks?: boolean;
/** Encrypt the contents of the zip archive using a password */
password?: string;
/** The working directory from which to execute the zip command */
cwd?: string;
}

/**
* Creates a zip archive of the specified files or directories.
* @param zipFile - The name of the zip file to create.
* @param sources - An array of file or directory paths to include in the zip.
* @param options - Options for the zip command and execution.
*/
export async function zip(zipFile: string, sources: string[], options: ZipOptions = {}): Promise<void> {
const args: string[] = ['-q'];

if (options.compressionLevel !== undefined) {
args.push(`-${options.compressionLevel}`);
}

if (options.includeHidden) {
args.push('-D');
}

if (options.recursive) {
args.push('-r');
}

if (options.symlinks) {
args.push('-y');
}

if (options.password) {
args.push('-P', options.password);
}

args.push(zipFile);

if (options.exclude) {
options.exclude.forEach(pattern => {
args.push('-x', pattern);
});
}

args.push(...sources);

await shell('zip', args, { ...options, cwd: options.cwd });
}

// Default export containing all functions
const shellFS = {
createDirectory,
Expand All @@ -318,7 +405,9 @@ const shellFS = {
exists,
getInfo,
open,
chmod
chmod,
createTempDir,
zip
};

export default shellFS;

0 comments on commit a66cb8b

Please sign in to comment.