Gulp-octo is ignoring my choice of output directory - gulp

I'm trying to build an Octopus Deploy package for an angular-cli project using Gulp and Gulp-Octo:
const gulp = require("gulp"),
octopus = require("#octopusdeploy/gulp-octo"),
version = require("./package.json").version;
gulp.task("octopack",
["build-prod"],
() => gulp.src("dist/*")
.pipe(octopus.pack(
"zip", // octopackjs does not support nupkg format yet
{
id: "myprojectid",
version: `${version}.${commandLineOptions.buildnumber}`
}))
.pipe(gulp.dest('./octopus'))
);
This creates a package with the correct contents and version number, but it always goes into the current directory (alongside gulpfile.js) instead of the directory that I specified in gulp.dest().
I have tried all of the following variations in the call to gulp.dest, with the same result:
./octopus
./octopus/
octopus/
octopus
path.join(__dirname, 'octopus')
Am I misunderstanding how gulp.dest() works, or is octopus.pack() doing something weird?
(Note: If I leave out the gulp.dest() altogether then no zip file is created.)

It's a bug in gulp-octo. In this line they set the path of the generated archive. Unfortunately they just use the filename of the archive instead of a full path (which is what they're supposed to do), so the file is always written relative to the current working directory.
I might send them a pull request when I get the chance, since this is an easy fix.
In the meantime you can use the following workaround:
var path = require('path');
gulp.task("default",
() => gulp.src("dist/*")
.pipe(octopus.pack(
"zip", // octopackjs does not support nupkg format yet
{
id: "myprojectid",
version: `${version}.${commandLineOptions.buildnumber}`
}))
.on('data', (f) => { f.path = path.join(f.base, f.path) })
.pipe(gulp.dest('./octopus'))
);

Related

gulp polymer-build not generating expected bundle?

I have the following gulp task (please see below), which I'm trying to run to automate the polymer build. However, all I'm seeing in the resulting /build folder is an index.html. No dependencies, and I was under the impression that the resulting file would be called shared-bundle.html. Also, it's not fetching any of my bower dependencies:
const PolymerProject = require('polymer-build').PolymerProject;
const project = new PolymerProject(require('./polymer.json'));
gulp.task('build', () => {
mergeStream(project.sources(), project.dependencies())
.pipe(project.bundler())
.pipe(gulp.dest('./build/'));
});
This is the documentation I was referencing: https://www.npmjs.com/package/polymer-build
Any ideas what I might be missing?
Apparently I was just missing the entrypoint param here:
const project = new PolymerProject({entrypoint: 'my-page.html'});

Polymer: two gulp errors at build time: 'async completion' and 'apply' property

I'm trying to run gulp to build my app like Rob Dodson explains here.
Original error
At the command line, if I run:
npm run build
I get the following error:
[20:50:55] Using gulpfile ~/path/to/gulpfile.js
[20:50:55] Starting 'default'...
Deleting build/ directory...
[20:50:56] The following tasks did not complete: default
[20:50:56] Did you forget to signal async completion?
It appears there is some task described as "signal async completion?" What does this mean? And how do I do it?
Alternate error
However if I run the following at the command line:
gulp
I get a different error message as follows:
[23:40:57] Using gulpfile ~/path/to/gulpfile.js
/usr/local/lib/node_modules/gulp/bin/gulp.js:129
gulpInst.start.apply(gulpInst, toRun);
^
TypeError: Cannot read property 'apply' of undefined
at /usr/local/lib/node_modules/gulp/bin/gulp.js:129:19
at nextTickCallbackWith0Args (node.js:420:9)
at process._tickCallback (node.js:349:13)
at Function.Module.runMain (module.js:443:11)
at startup (node.js:139:18)
at node.js:968:3
Why would there be different error messages? Does that give a hint what's actually causing the errors? If so, what is it? And what can I do to fix it?
My code
I just copied the files package.json, polymer.json and gulpfile.js from the sample code Rob supplied here. Then I ran npm install as this answer describes.
gulpfile.js
'use strict';
// Documentation on what goes into PolymerProject.
const path = require('path');
const gulp = require('gulp');
const mergeStream = require('merge-stream');
const del = require('del');
const polymerJsonPath = path.join(process.cwd(), 'polymer.json');
const polymerJSON = require(polymerJsonPath);
const polymer = require('polymer-build');
const polymerProject = new polymer.PolymerProject(polymerJSON);
const buildDirectory = 'build/bundled';
/**
* Waits for the given ReadableStream
*/
function waitFor(stream) {
return new Promise((resolve, reject) => {
stream.on('end', resolve);
stream.on('error', reject);
});
}
function build() {
return new Promise((resolve, reject) => {
// Okay, so first thing we do is clear the build
console.log(`Deleting build/ directory...`);
del([buildDirectory])
.then(_ => {
// Okay, now lets get your source files
let sourcesStream = polymerProject.sources()
// Oh, well do you want to minify stuff? Go for it!
// Here's how splitHtml & gulpif work
.pipe(polymerProject.splitHtml())
.pipe(gulpif(/\.js$/, uglify()))
.pipe(gulpif(/\.css$/, cssSlam()))
.pipe(gulpif(/\.html$/, htmlMinifier()))
.pipe(polymerProject.rejoinHtml());
// Okay now lets do the same to your dependencies
let depsStream = polymerProject.dependencies()
.pipe(polymerProject.splitHtml())
.pipe(gulpif(/\.js$/, uglify()))
.pipe(gulpif(/\.css$/, cssSlam()))
.pipe(gulpif(/\.html$/, htmlMinifier()))
.pipe(polymerProject.rejoinHtml());
// Okay, now lets merge them into a single build stream.
let buildStream = mergeStream(sourcesStream, depsStream)
.once('data', () => {
console.log('Analyzing build dependencies...');
});
// If you want bundling, do some bundling! Explain why?
buildStream = buildStream.pipe(polymerProject.bundler);
// If you want to add prefetch links, do it! Explain why?
// buildStream = buildStream.pipe(new PrefetchTransform(polymerProject));
// Okay, time to pipe to the build directory
buildStream = buildStream.pipe(gulp.dest(buildDirectory));
// waitFor the buildStream to complete
return waitFor(buildStream);
})
.then(_ => {
// You did it!
console.log('Build complete!');
resolve();
});
});
}
gulp.task('default', build);
The original error is unrelated to the "alternate error".
While the build task runs gulp, npm run prioritizes the locally-installed gulp (at node_modules/.bin/gulp) before the system-installed gulp. Running gulp yourself (without npm run) would invoke the globally-installed gulp, which may result in an error if it's incompatible with your project (e.g., Gulp 3 binary with Gulp 4 API in your scripts, which appears to be the case). You could either install Gulp 4 so that you can run gulp yourself, or continue using npm run build.
To troubleshoot the original error, I recommend starting from the Polycast's original source (if you haven't already) to determine what the difference could be.
If you prefer to stick with your current track, I suggest a few things:
Verify the paths in your HTML imports, as a path to a non-existent file would cause a silent error (polymer-build issue 88). It might be helpful to run polymer build -v (verbose build).
Add buildStream.on('error', (err) => console.log(err)) after let buildStream = ... in case any unsuppressed error events crop up in that stream.
I recommend you use the new version of PSK Custom Build:
https://github.com/PolymerElements/generator-polymer-init-custom-build/
It has the gulpfile.js updated.
The problem was caused by an incorrect import path.
incorrect path
<link rel="import" href="../../../bower_components/polymer/polymer.html">
correct path
<link rel="import" href="../../bower_components/polymer/polymer.html">
As #tony19, correctly described, that errant import path caused a silent failure.
I found this by pursuing the path suggested by #abdonrd. I followed the instructions here as follows.
First, I copied my project. Then I loaded into the my-app directory per the below described procedure.
https://github.com/PolymerElements/generator-polymer-init-custom-build/
npm install -g polymer-cli
npm install -g generator-polymer-init-custom-build
mkdir my-app
cd my-app
polymer init custom-build
polymer build -v # the results of this command highlighted my error in red
The error showed the path of the missing file. Which I noticed was located one level higher than it should have been because the root directory my-app/ was missing from the path. Then I had to search manually through all the files using the search string polymer/polymer.html until I found a mismatch between the number of ../ in the import path (3 in this case) and the number of folders deep into the root directory the importing file was (2 in this case).
After I corrected the file path, I again ran:
polymer build -v # building the project again, correctly this time
polymer serve build/bundled # to test serve the build/bundled version

aws lambda nodejs - error when uploading a zip file compressing by GULP

I'm using Gulp to compress a zip file and then upload it to AWS Lambda. The upload zip file is done manually. Only the process of compressing is handled by Gulp.
Here is my gulpfile.js
var gulp = require('gulp');
var zip = require('gulp-zip');
var del = require('del');
var install = require('gulp-install');
var runSequence = require('run-sequence');
var awsLambda = require("node-aws-lambda");
gulp.task('clean', function() {
return del(['./dist', './dist.zip']);
});
gulp.task('js', function() {
return gulp.src('index.js')
.pipe(gulp.dest('dist/'));
});
gulp.task('npm', function() {
return gulp.src('./package.json')
.pipe(gulp.dest('dist/'))
.pipe(install({production: true}));
});
gulp.task('zip', function() {
return gulp.src(['dist/**/*', '!dist/package.json'])
.pipe(zip('dist.zip'))
.pipe(gulp.dest('./'));
});
gulp.task('deploy', function(callback) {
return runSequence(
['clean'],
['js', 'npm'],
['zip'],
callback
);
});
After running the deploy task, a zip folder named dist.zip is created consists of a index.js file and a node_modules folder. The node_modules folder contains only a lodash library.
This is index.js
var _ = require('lodash');
console.log('Loading function');
exports.handler = (event, context, callback) => {
//console.log('Received event:', JSON.stringify(event, null, 2));
var b = _.chunk(['a', 'b', 'c', 'd', 'e'], 3);
console.log(b);
callback(null, event.key1); // Echo back the first key value
//callback('Something went wrong');
};
After using AWS lambda console to upload the dist.zip folder. There is an error showing that the lodash library cannot be found
{
"errorMessage": "Cannot find module 'lodash'",
"errorType": "Error",
"stackTrace": [
"Function.Module._load (module.js:276:25)",
"Module.require (module.js:353:17)",
"require (internal/module.js:12:17)",
"Object.<anonymous> (/var/task/index.js:1:71)",
"Module._compile (module.js:409:26)",
"Object.Module._extensions..js (module.js:416:10)",
"Module.load (module.js:343:32)",
"Function.Module._load (module.js:300:12)",
"Module.require (module.js:353:17)"
]
}
But in the zip folder, there is a node_modules directory that contains the lodash lib.
dist.zip
|---node_modules
|--- lodash
|---index.js
When i zip the node_modules directory and the file index.js manually, it works fine.
Does anyone have idea what wrongs ? Maybe when compressing using Gulp, there is a misconfigured for the lib path ?
I had same problem few days back.
Everyone pointed to gulp zip, however it was not problem with gulp zip.
Below worked fine:
gulp
.src(['sourceDir/**'], {nodir: true, dot: true} )
.pipe(zip('target.zip'))
.pipe(gulp.dest('build/'));
That is, note the below, in 2nd param of src, in the above:
{nodir: true, dot: true}
That is, we have to include dot files for the zip (ex: .config, .abc, etc.)
So, include above in .src of gulp, else all others like copy, zip, etc. will be improper.
The package gulp-zip is massively popular (4.3k downloads per day) and there does not seem to be any Gulp substitute. The problem is definitely with relative paths and how gulp-zip processes them. Even when using a base path option in the gulp.src function (example below), gulp-zip finds a way to mess it up.
gulp.task("default", ["build-pre-zip"], function () {
return gulp.src([
"dist/**/*"
], { base: "dist/" })
.pipe(debug())
.pipe(zip("dist.zip"))
.pipe(gulp.dest("./dist/"));
});
Since there is no good Gulp solution as of 1/4/2017 I suggest a work-around. I use Gulp to populate the dist folder first, exactly how I need it with the proper node_modules folder. Then it is time to zip the dist folder properly with relative file paths stored. To do that and also update Lambda, I use a batch file (Windows) of command line options to get the job done. Here is the upload.bat file I created to take the place of the gulp-zip task:
start /wait cmd /c "gulp default"
start /wait cmd /c "C:\Program Files\WinRAR\WinRAR.exe" a -r -ep1 dist\dist.zip dist\*.*
aws lambda update-function-code --zip-file fileb://dist/dist.zip --function-name your-fn-name-here
If you use WinRAR you will find their command line docs here, for WinZip go here. That .bat file assumes you are using the AWS Command Line Interface (CLI) which is a godsend; get it here.
If you are wishing this answer pointed you towards a 100% Gulp solution, to that I say, "You and me both!". Good luck.

Cannot read property 'emit' of undefined in gulp-browserify

i am running into a problem. I have created my own seed: https://github.com/damirkusar/leptir-angular-seed with gulp, browserify and more.
Everything worked fine, since i had the good idea to update node from 10.32 to 12.5, i am getting the below error. I think that this is since then. I tried it also on a different machine, same setup, same error.
so, after npm install and bower install i am starting the app with:
gulp
or when trying to build the project with
gulp build
i am getting this error:
leptir-angular-seed/node_modules/gulp-browserify/node_modules/browserify/node_modules/module-deps/index.js:162
rs.on('error', function (err) { tr.emit('error', err) });
^
TypeError: Cannot read property 'emit' of undefined
at ReadStream.<anonymous> (/leptir-angular-seed/node_modules/gulp-browserify/node_modules/browserify/node_modules/module-deps/index.js:162:39)
at ReadStream.emit (events.js:107:17)
at fs.js:1618:12
at FSReqWrap.oncomplete (fs.js:95:15)
Here is also the link to the package.json: https://github.com/damirkusar/leptir-angular-seed/blob/450ffe99943036cd5a670e54ec3884c02bd7bb8a/package.json.
but luckily, karma start executes the tests and all tests are passing..
Maybe some versions are not really supported correctly?
Does anybody have an idea what causes this problem?
-- edit 2015-June-25 14:23
I am using the module which cause the problem in my gulp file like this:
// Browserify task
gulp.task('browserify', function () {
gulp.src(paths.browserify[0])
.pipe(browserify({
insertGlobals: true,
debug: true
}))
// Bundle to a single file
.pipe(concat('bower.js'))
// Output it to our dist folder
.pipe(gulp.dest(paths.destination_public))
.pipe(refresh(lrServer)); // Tell the lrServer to refresh;
gulp.src(paths.browserify[1])
.pipe(browserify({
insertGlobals: true,
debug: true
}))
// Bundle to a single file
.pipe(concat('app.js'))
// Output it to our dist folder
.pipe(gulp.dest(paths.destination_public))
.pipe(refresh(lrServer)); // Tell the lrServer to refresh;
});
which browserifyies these app.js file and its content:
require('./modules/core');
require('./modules/core');
and bower.js with its content:
'use strict';
require('jquery');
require('bootstrap');
require('moment');
require('underscore');
require('angular');
require('angular-animate');
require('angular-bootstrap');
require('angular-bootstrap-tpls');
require('angular-cookies');
require('angular-mocks');
require('angular-resource');
require('angular-ui-router');
require('angular-ui-utils');
require('angular-translate');
require('angular-translate-loader-static-files');
require('angular-translate-loader-url');
require('angular-translate-storage-cookie');
require('angular-translate-storage-local');
thank you so much
"...but in fact, otherwise i am not using this module which causes the error." - damir
modules has dependencies too. it seems to be a problem with one of these modules that are used by an other module.
It could be possible that a module you are using has a dependency on a node component of the old version. Try to get the old back until the bug is fixed.
On a windows machine (instead of mine mac) it showed me a better error message.
I referenced bower packages which where not installed.. but totally forgot to remove it from package.json and bower.js.
so i removed code in the above files which referenced the following packages:
angular-translate-storage-cookie
angular-translate-storage-local
-- UPDATE 27th June 2015 - 22:41 --
I saw that gulp-browserify is blacklisted by gulpjs, so i thought its better to get rid of it, because i faced also problems on windows machines. Instead of using gulp-browserify, i am using plain browserify with vinyl-transform.
First, update your package.json with this:
"browserify": "9.0.4",
"vinyl-transform": "1.0.0"
You see, that i am using exactly these two versions, this is because with newer browserify versions, things are not really working, so to be sure that it works also when i update my packages, i keep them in this versions.
Then lets update our gulp file. We will need to add these two lines:
var browserify = require('browserify'),
transform = require('vinyl-transform');
and my new task looks like this:
gulp.task('browserify', function () {
var browserified = transform(function(filename) {
var b = browserify(filename);
return b.bundle();
});
return gulp.src(paths.browserify)
.pipe(browserified)
.pipe(gulp.dest(paths.destination_public));
});
its now shorter and much cleaner. My paths are configured like this..
var paths = {
...
browserify: ['./public/bower.js', './public/app.js'],
...
destination_public: './dist/'
};
now my seed is working on mac and windows the same way.
https://github.com/damirkusar/leptir-angular-seed

In Gulp, how do I only run a task on one file if any of multiple files are newer?

I'm probably trying to make gulp do something that's not idiomatic, but here goes.
I want my build task to only run if the source files are newer than the output file.
In gulp, it seems standard practice to create a build task that always runs, and then set up a watch task to only run that build task when certain files change. That's okay, but it means that you always build on the first run.
So, is it possible to do what I want? Here's what I've got so far (newer is gulp-newer):
gulp.task('build_lib', function() {
return gulp.src(["app/**/*.ts"])
.pipe(newer("out/outputLib.js")) //are any of these files newer than the output?
** NEED SOMETHING HERE **
how do I say, "If I got _any_ files from the step before, replace all of them with a single hardcoded file "app/scripts/LibSource.ts" "?
.pipe(typescript({
declaration: true,
sourcemap: true,
emitError: false,
safe: true,
target: "ES5",
out: "outputLib.js"
}))
.pipe(gulp.dest('out/'))
});
I tried using gulpif, but it doesn't seem to work if there are no files going into it to begin with.
.pipe(gulpif(are_there_any_files_at_all,
gulp.src(["app/scripts/LibSource.ts"])))
However, my condition function isn't even called because there are no files on which to call it. gulpif calls the truthy stream in this case, so LibSource gets added to my stream, which isn't what I want.
Maybe doing all of this in a single stream really isn't the right call, since the only reason I'm passing those files through the "gulp-newer" filter is to see if any of them is newer. I'm then discarding them and replacing them with another file. My question still stands though.
You can write your own through/transform stream to handle the condition like so:
// Additional core libs needed below
var path = require('path');
var fs = require('fs');
// Additional npm libs
var newer = require('gulp-newer');
var through = require('through');
var File = require('vinyl');
gulp.task('build_lib', function() {
return gulp.src(["app/**/*.ts"])
.pipe(newer("out/outputLib.js"))
.pipe(through(function(file) {
// If any files get through newer, just return the one entry
var libsrcpath = path.resolve('app', 'scripts', 'LibSource.ts');
// Pass libsrc through the stream
this.queue(new File({
base: path.dirname(libsrcpath),
path: libsrcpath,
contents: new Buffer(fs.readFileSync(libsrcpath))
}));
// Then end this stream by passing null to queue
// this will ignore any other additional files
this.queue(null);
}))
.pipe(typescript({
declaration: true,
sourcemap: true,
emitError: true,
safe: true,
target: "ES5",
out: "outputLib.js"
}))
.pipe(gulp.dest('out/'));
});
I know like, this question was posted over 4 years ago, however; I am sure this problem crosses the path of everyone, and although I think I understand the question that is being asked, I feel that there is an easier way to perform this task, off which, I posted a similar question recently on stackoverflow at New to GULP - Is it necessary to copy all files from src directory to dist directory for a project?
It uses gulp-changed, and for me, it worked like a charm, so for others who may look at this post for similar reasons, have a look at my post and see if it is what you are looking for.
Kind Regards
You don't need to build first. You can on your 'first run' only run the watch task from which you run all the other ones.
example:
// Create your 'watch' task
gulp.task( 'watch', function() {
gulp.watch( 'scripts/*.js', [ 'lint', 'test', 'scripts' ] );
gulp.watch( 'styles/sass/*.scss', [ 'sass_dev' ] );
} );
// On your first run you will only call the watch task
gulp.task( 'default', [ 'watch' ] );
This will avoid running any task on startup. I hope this will help you out.
May I suggest gulp-newy in which you can manipulate the path and filename in your own function. Then, just use the function as the callback to the newy(). This gives you complete control of the files you would like to compare.
This will allow 1:1 or many to 1 compares.
newy(function(projectDir, srcFile, absSrcFile) {
// do whatever you want to here.
// construct your absolute path, change filename suffix, etc.
// then return /foo/bar/filename.suffix as the file to compare against
}