Skip to content

Add retrieve and extract methods for salesforce package #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
language: node_js
node_js:
- 0.10
- 0.10
75 changes: 54 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# gulp-jsforce-deploy

[![Build Status](https://travis-ci.org/jsforce/gulp-jsforce-deploy.svg?branch=master)](https://travis-ci.org/jsforce/gulp-jsforce-deploy)

A gulp plugin for deploying Salesforce package, using JSforce's Metadata API feature.
A gulp plugin for deploying and retrieving Salesforce package, using JSforce's Metadata API feature.
As it is implemented purely in Node.js, you do not have to setup Force.com Migration Tool (Ant, Java) anymore.

## Setup
Expand All @@ -11,7 +12,7 @@ $ npm init
$ npm install gulp gulp-zip gulp-jsforce-deploy --save-dev
```

## Example
## Example

### Project Directory

Expand All @@ -29,25 +30,57 @@ $ npm install gulp gulp-zip gulp-jsforce-deploy --save-dev
### gulpfile.js

```javascript
var gulp = require('gulp');
var zip = require('gulp-zip');
var forceDeploy = require('gulp-jsforce-deploy');

gulp.task('deploy', function() {
gulp.src('./pkg/**', { base: "." })
.pipe(zip('pkg.zip'))
.pipe(forceDeploy({
username: process.env.SF_USERNAME,
password: process.env.SF_PASSWORD
//, loginUrl: 'https://test.salesforce.com'
//, pollTimeout: 120*1000
//, pollInterval: 10*1000
//, version: '33.0'
}));
});
```

### Deploy
var gulp = require('gulp')
var zip = require('gulp-zip')
// Backwards compatible with version
var forceDeploy = require('gulp-jsforce-deploy')
// Or new API
var { deploy, retrieve, extract } = require('gulp-jsforce-deploy')

gulp.task('deploy', async function () {
return new Promise((resolve, reject) => {
gulp
.src('./pkg/**', { base: '.' })
.pipe(zip('pkg.zip'))
.pipe(
forceDeploy({
username: process.env.SF_USERNAME,
password: process.env.SF_PASSWORD
//, loginUrl: 'https://test.salesforce.com'
//, pollTimeout: 120*1000
//, pollInterval: 10*1000
//, version: '33.0'
})
)
})
})

gulp.task('retrieve', async function () {
return new Promise((resolve, reject) => {
gulp
.src('./package.xml')
.pipe(
retrieve({
// Filename is optional; uses name 'package.zip' by default.
filename: 'pkg.zip',
username: process.env.SF_USERNAME,
password: process.env.SF_PASSWORD
//, loginUrl: 'https://test.salesforce.com'
//, pollTimeout: 120*1000
//, pollInterval: 10*1000
//, version: '33.0'
})
)
// If the extract pipe is omitted, then the zip file will be written to the destination.
.pipe(extract())
.pipe(gulp.dest('./pkg'))
.on('finish', resolve)
.on('error', reject)
})
})
```

### Sample commands

```
$ [email protected] SF_PASSWORD=yourpassword gulp deploy
Expand Down
60 changes: 38 additions & 22 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
/* global process, __dirname */
'use strict';
var fs = require('fs');
var gulp = require('gulp');
var zip = require('gulp-zip');
var forceDeploy = require('./');
'use strict'
var fs = require('fs')
var gulp = require('gulp')
var zip = require('gulp-zip')
var prettier = require('prettier-standard')
var forceDeploy = require('./')

gulp.task('forceDeploy', function() {
gulp.src("./pkg/**", { base: "." })
.pipe(zip("pkg.zip"))
.pipe(forceDeploy({
username: process.env.SF_USERNAME,
password: process.env.SF_PASSWORD
//, loginUrl: 'https://test.salesforce.com'
//, pollTimeout: 120*1000
//, pollInterval: 10*1000
//, version: '33.0'
}));
});
gulp.task('forceDeploy', function () {
gulp
.src('./pkg/**', { base: '.' })
.pipe(zip('pkg.zip'))
.pipe(
forceDeploy({
username: process.env.SF_USERNAME,
password: process.env.SF_PASSWORD
//, loginUrl: 'https://test.salesforce.com'
//, pollTimeout: 120*1000
//, pollInterval: 10*1000
//, version: '33.0'
})
)
})

gulp.task('build', function(cb) {
var data = "Random: " + Math.random();
fs.writeFile(__dirname + '/pkg/staticresources/GulpJSforceTestResource.resource', data, cb);
});
gulp.task('build', function (cb) {
var data = 'Random: ' + Math.random()
fs.writeFile(
__dirname + '/pkg/staticresources/GulpJSforceTestResource.resource',
data,
cb
)
})

gulp.task('deploy', [ 'build', 'forceDeploy' ]);
gulp.task('deploy', gulp.series('build', 'forceDeploy'))

gulp.task('format', async () => {
await prettier.run('./', {})
})

gulp.task('lint', async () => {
await prettier.run('./', { check: true, lint: true })
})
189 changes: 167 additions & 22 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,174 @@
'use strict';
var gutil = require('gulp-util');
var through = require('through2');
var meta = require('jsforce-metadata-tools');

module.exports = function(options) {
return through.obj(function(file, enc, callback) {
var err;
'use strict'
var meta = require('jsforce-metadata-tools')
var PluginError = require('plugin-error')
var decompress = require('decompress')
var fancyLog = require('fancy-log')
var through = require('through2')
var parser = require('xml2js')
var Vinyl = require('vinyl')

var forceDeploy = function deploy (options) {
return through.obj(function (file, enc, callback) {
if (file.isNull()) {
return callback(null, file);
return callback(null, file)
}

if (file.isStream()) {
err = new gutil.PluginError('gulp-jsforce-deploy', 'Stream input is not supported');
return callback(err);
return callback(
new PluginError('gulp-jsforce-deploy', 'Stream input is not supported')
)
}
options.logger = gutil;
meta.deployFromZipStream(file.contents, options)
.then(function(res) {
meta.reportDeployResult(res, gutil, options.verbose);

var deployFactory = this
options.logger =
options.logger === undefined
? Object.assign({ log: fancyLog }, fancyLog)
: options.logger

meta
.deployFromZipStream(file.contents, options)
.then(function (res) {
var resultFile
meta.reportDeployResult(res, options.logger, options.verbose)

if (!res.success) {
return callback(new Error('Deploy Failed.'));
if (options.checkOnly && options.checkOnlyNoFail) {
fancyLog(
'Deploy Failed. Error suppressed by option; check output for reason.'
)
} else {
return callback(
new PluginError('gulp-jsforce-deploy', 'Deploy Failed.')
)
}
}

if (options.resultPassThrough || options.resultOnly) {
resultFile = new Vinyl({
cwd: './',
base: './',
path: './deploy-result.json',
contents: new Buffer(JSON.stringify(res, null, 2), 'utf8')
})
}

if (options.resultPassThrough && !options.resultOnly) {
deployFactory.push(resultFile)
}
callback(null, file);

if (options.resultOnly && !options.resultPassThrough) {
file = resultFile
}

callback(null, file)
})
.catch(function (err) {
callback(err)
})
})
}

forceDeploy.deploy = function deploy (options) {
return forceDeploy(options)
}

forceDeploy.retrieve = function retrieve (options) {
return through.obj(function (file, enc, callback) {
if (file.isNull()) {
return callback(null, file)
}

if (file.isStream()) {
return callback(
new PluginError('gulp-jsforce-deploy', 'Stream input is not supported')
)
}

options.logger =
options.logger === undefined
? Object.assign({ log: fancyLog }, fancyLog)
: options.logger

parser
.parseStringPromise(file.contents.toString('utf8'))
.then(function (dom) {
delete dom.Package.$
options.unpackaged = dom.Package
return meta.retrieve(options)
})
.catch(function(err) {
callback(err);
});
});
};
.then(function (res) {
meta.reportRetrieveResult(res, options.logger, options.verbose)

if (!res.success) {
return callback(
new PluginError('gulp-jsforce-deploy', 'Retrieve Failed.')
)
}

if (options.resultPassThrough) {
deployFactory.push(
new Vinyl({
cwd: './',
base: './',
path: './retrieve-result.json',
contents: new Buffer(JSON.stringify(res, null, 2), 'utf8')
})
)
}

callback(
null,
new Vinyl({
cwd: file.cwd,
base: file.base,
path: file.base + '/' + (options.filename || 'package.zip'),
contents: new Buffer(res.zipFile, 'base64')
})
)
})
.catch(function (err) {
callback(err)
})
})
}

forceDeploy.extract = function extract (options = {}) {
return through.obj(function (file, enc, callback) {
if (file.isNull()) {
return callback(null, file)
}

if (file.isStream()) {
return callback(
new PluginError('gulp-jsforce-deploy', 'Stream input is not supported')
)
}

var extractFactory = this

decompress(file.contents)
.then(function (files) {
files.forEach(file => {
var path = file.path.replace(/^unpackaged\//, '')

extractFactory.push(
new Vinyl({
cwd: './',
path,
contents: file.data
})
)

if (options.verbose) fancyLog(`Extracted file '${path}'`)
})

fancyLog(`Finished extracting ${files.length} files.`)
callback()
})
.catch(function (err) {
callback(err)
})
})
}

module.exports = forceDeploy
Loading