Skip to content
This repository has been archived by the owner on Aug 31, 2021. It is now read-only.

Commit

Permalink
umask in SFTP
Browse files Browse the repository at this point in the history
  • Loading branch information
mkloubert committed Jan 3, 2018
1 parent 126d74d commit 57ddb2d
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 23 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

## 0.15.0 (January 3rd, 2018; check for requirements)

* added `checkForRequirements`, which can execute one or more conditions by (JavaScript) code to check for (project) requirements
* added `checkForRequirements`, which can [execute one or more conditions](https://github.com/mkloubert/vscode-deploy-reloaded/wiki/check_for_requirements) by (JavaScript) code to check for (project) requirements
* can define [umask values](https://github.com/mkloubert/vscode-deploy-reloaded/wiki/target_sftp#modes-for-specific-files) for files uploaded via [sftp](https://github.com/mkloubert/vscode-deploy-reloaded/wiki/target_sftp#modes-for-specific-files) now

## 0.14.2 (January 3rd, 2018; deploy git commits)

Expand Down
19 changes: 19 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31379,6 +31379,25 @@
}
}
},
"modes": {
"description": "Defines (umask) modes for files on the server, after they have been uploaded.",
"oneOf": [
{
"description": "The (octal) value for all files.",
"type": "integer"
},
{
"description": "File patterns with octal values.",
"type": "object",
"patternProperties": {
"(.*)": {
"description": "The (octal) value for all files.",
"type": "integer"
}
}
}
]
},
"name": {
"description": "The (display) name of that target.",
"type": "string"
Expand Down
109 changes: 87 additions & 22 deletions src/clients/sftp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ export interface SFTPConnectionOptions {
* The hostname
*/
readonly host?: string;
/**
* Defines the modes for files, after they have been uploaded.
*/
readonly modes?: SFTPFileModeSettings;
/**
* The password.
*/
Expand Down Expand Up @@ -84,6 +88,21 @@ export interface SFTPConnectionOptions {
readonly user?: string;
}

/**
* A value for a file mode.
*/
export type SFTPFileMode = number | string;

/**
* Patterns with file modes.
*/
export type SFTPFileModePatterns = { [ pattern: string ]: SFTPFileMode };

/**
* A possible file mode setting value.
*/
export type SFTPFileModeSettings = SFTPFileMode | SFTPFileModePatterns;


/**
* The default value for a host address.
Expand Down Expand Up @@ -267,33 +286,79 @@ export class SFTPClient extends deploy_clients.AsyncFileListBase {
}

/** @inheritdoc */
public async uploadFile(path: string, data: Buffer): Promise<void> {
const REMOTE_DIR = toSFTPPath(
Path.dirname(path)
);
const FILE = Path.basename(path);

path = toSFTPPath(path);
public uploadFile(path: string, data: Buffer): Promise<void> {
return new Promise<void>(async (resolve, reject) => {
const COMPLETED = deploy_helpers.createCompletedAction(resolve, reject);

// check if remote directory exists
if (true !== this._checkedRemoteDirs[REMOTE_DIR]) {
try {
// check if exist
await this.client.list(REMOTE_DIR);
const REMOTE_DIR = toSFTPPath(
Path.dirname(path)
);
const FILE = Path.basename(path);

path = toSFTPPath(path);

let fileModes: SFTPFileModePatterns | false = false;
if (!deploy_helpers.isNullOrUndefined(this.options.modes)) {
let modes = this.options.modes;
if (!deploy_helpers.isObject<SFTPFileModePatterns>(modes)) {
modes = {
'**': modes
};
}

fileModes = modes;
}

// check if remote directory exists
if (true !== this._checkedRemoteDirs[REMOTE_DIR]) {
try {
// check if exist
await this.client.list(REMOTE_DIR);
}
catch (e) {
// no, try to create
await this.client.mkdir(REMOTE_DIR, true);
}

// mark as checked
this._checkedRemoteDirs[REMOTE_DIR] = true;
}

let modeToSet: number | false = false;
if (false !== fileModes) {
for (const P in fileModes) {
let pattern = P;
if (!pattern.startsWith('/')) {
pattern = '/' + pattern;
}

if (deploy_helpers.doesMatch(path, pattern)) {
modeToSet = parseInt(deploy_helpers.toStringSafe(fileModes[P]).trim(),
8);
break;
}
}
}

await this.client.put(
data,
path,
);

if (false !== modeToSet) {
this.client['sftp'].chmod(path, modeToSet, (err) => {
COMPLETED(err);
});
}
else {
COMPLETED(null);
}
}
catch (e) {
// no, try to create
await this.client.mkdir(REMOTE_DIR, true);
COMPLETED(e);
}

// mark as checked
this._checkedRemoteDirs[REMOTE_DIR] = true;
}

await this.client.put(
data,
path,
);
});
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/plugins/sftp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ export interface SFTPTarget extends deploy_targets.Target {
* The hostname
*/
readonly host?: string;
/**
* Defines the modes for files, after they have been uploaded.
*/
readonly modes?: deploy_clients_sftp.SFTPFileModeSettings;
/**
* The password.
*/
Expand Down Expand Up @@ -133,6 +137,7 @@ class SFTPPlugin extends deploy_plugins.AsyncFileClientPluginBase<SFTPTarget,
hashAlgorithm: this.replaceWithValues(target, target.hashAlgorithm),
hashes: target.hashes,
host: this.replaceWithValues(target, target.host),
modes: target.modes,
password: target.password,
port: parseInt(
deploy_helpers.toStringSafe(
Expand Down

0 comments on commit 57ddb2d

Please sign in to comment.