gastonelhordoy / grunt-rpm Goto Github PK
View Code? Open in Web Editor NEWGrunt plugin to create an RPM out of a project for distribution.
License: MIT License
Grunt plugin to create an RPM out of a project for distribution.
License: MIT License
Hi!
I'm trying to install a file for my service into /etc/init.d/
Usually the idea would be (going by the documentation) to do it like this:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jshint: {
all: ['Gruntfile.js','app.js','lib/routes/index.js']
},
rpm: {
options: {
destination: 'build/',
release: true,
summary: grunt.file.readJSON('package.json').description,
distribution: 'centos',
vendor: 'Andreas Marschke <[email protected]>',
requires: [ 'node', 'npm' ],
defaultUsername: 'app',
defaultGroupname: 'appgroup',
group: 'System Environment/Daemons',
license: 'LGPL'
},
release: {
options: {
release: true
},
files: [
{ src: [ 'config/*'], dest: 'etc/app/'},
{ src: 'share/init.d', dest: 'etc/init.d/app' }
]
},
}
}
It's an express app with forever. The init.d file is a service so as to auto start the service after the system has come back up and other things.
Running "rpm:release" (rpm) task
[D] Task source: /root/app/node_modules/grunt-rpm/tasks/rpm.js
Verifying property rpm.release exists in config...OK
Files: lib/routes/index.js, app.js, -> opt/app/
Files: config/master.json -> opt/app/
Files: share/init.d -> etc/init.d/app
Options: destination="build/", release, summary="A recieving Server for app.js data queries", distribution="centos", vendor="Andreas Marschke <[email protected]>", requires=["node","npm"], defaultUsername="app", defaultGroupname="app", group="System Environment/Daemons", license="LGPL"
Deleting build/...OK
Copying file "lib/routes/index.js" to "build/tmp/opt/app/lib/routes/index.js"
Reading lib/routes/index.js...OK
Writing build/tmp/opt/app/lib/routes/index.js...OK
Copying file "app.js" to "build/tmp/opt/app/app.js"
Reading app.js...OK
Writing build/tmp/opt/app/app.js...OK
Copying file "config/master.json" to "build/tmp/opt/app/config/master.json"
Reading config/master.json...OK
Writing build/tmp/opt/app/config/master.json...OK
Copying file "share/init.d" to "build/tmp/etc/init.d/app"
Reading share/init.d...OK
Writing build/tmp/etc/init.d/app...OK
Reading package.json...OK
Parsing package.json...OK
Spawning rpmbuild: {"cmd":"rpmbuild","args":["-bb","--target","noarch","--buildroot","/root/app/build/tmp","/root/app/build/SPECS/app.spec"]}
Warning: error: File not found: /root/app/build/tmp/etc/init.d/app/share/init.d
File not found: /root/app/build/tmp/etc/init.d/app/share/init.d Used --force, continuing.
Done, but with warnings.
My question is: Why is it copying "build/tmp/etc/init.d/app" doubly at the bottom? Can I avoid this?
I am getting this error while trying to run grunt rpm
.
Running "rpm:files" (rpm) task
Warning: Cannot read property '0' of undefined Use --force to continue.
rpm: {
options: {
// Task-specific options go here.
release: false,
summary: 'My Summary'
},
files: {
src: ['<%= yeoman.dist %>/**/*.*'],
dest: '.'
}
},
My Gruntfile.js was pre-generated by Yeoman and then I added above section into it.
I am new to grunt, so probably I am missing something.
Do you know how to solve this?
I also get
Local Npm module "rpm" not found. Is it installed?
but. ./node_modules/grunt-rpm is available
I'm using Yeoman and want to package my application as an rpm with grunt-rpm.
After the grunt build, my minified application is in the dist
folder, so I specify something like this for my files specification:
grunt.initConfig({
rpm: {
release: {
options: {
destination: 'rpm',
name: 'foo_client',
version: '1.0.0',
release: false,
homepage: 'http://www.example.com',
summary: 'foo',
vendor: 'foo',
description: 'foo',
targetArch: 'noarch',
},
files: {
'/usr/share/foo/html/': [ 'dist/**' ]
},
},
},
Unfortunately this generates a package where the files are installed to /usr/share/foo/html/dist
instead of /usr/share/foo/html
. So I do some digging around and see that grunt will let me specify cwd
on a file specification, which seems like just the right thing, so I try:
files: [
{
dest: '/usr/share/foo/html/',
src: [ '**' ],
cwd: 'dist/'
}
],
Which actually gives me the right file specification (I logged out console.log('files: ' + JSON.stringify(files, null, 4));
in filterFiles
:
files: [
{
"dest": "/usr/share/fio/html/",
"src": [
"",
"app.full.min.css",
"app.full.min.js",
"index.html"
],
"cwd": "dist/",
"orig": {
"dest": "/usr/share/fio/html/",
"src": [
"**"
],
"cwd": "dist/"
}
}
]
But grunt-rpm doesn't understand the cwd property and fails with ENOENT.
The example shown in the top-level README doesn't work. I had to look in the test files to see that the structure has to be like this for Gruntfile.js
:
grunt.initConfig({
rpm: {
release: {
options: {
// ...
},
files: {
'/usr/share/foo/': [ 'dist/**' ]
},
},
},
There problem with what is shown in the READMEis that there must be a 'configuration name' dictionary in rpm
that contains the settings for options
and files
. I am not sure how this name is used other than to group options
and files
together. This is clearly shown in the test data.
This is the same problem than the one recently fixed by sbt/sbt-native-packager#22, invoking the rpmbuild
command-line, but from scala (instead of from Node+Grunt).
[...]
Spawning rpmbuild: {"cmd":"rpmbuild","args":["-bb","--target","noarch","--buildroot","/Users/kowalskif/Desktop/GIT/hp-ws/mpf-client/_rpmbuild/tmp","/Users/kowalskif/Desktop/GIT/hp-ws/mpf-client/_rpmbuild/SPECS/mpf-client.spec"]}
Warning: error: Unable to open temp file.
Unable to open temp file. Use --force to continue.
Aborted due to warnings.
Here is the spawned command-line execution job:
$ rpmbuild -vvv -bb --target noarch --buildroot /Users/kowalskif/Desktop/GIT/hp-ws/mpf-client/_rpmbuild/t
mp /Users/kowalskif/Desktop/GIT/hp-ws/mpf-client/_rpmbuild/SPECS/mpf-client.spec
Building target platforms: noarch
D: target platform: noarch
Processing files: mpf-client-0.1.0-SNAPSHOT20140616220711
D: execv(/opt/local/lib/rpm/find-provides) pid 83186
D: waitpid(83186) rc 83186 status 0
Finding Provides: /opt/local/lib/rpm/find-provides
D: execv(/opt/local/lib/rpm/find-requires) pid 83200
D: waitpid(83200) rc 83200 status 0
Finding Requires: /opt/local/lib/rpm/find-requires
Checking for unpackaged file(s): /opt/local/lib/rpm/check-files /Users/kowalskif/Desktop/GIT/hp-ws/mpf-client/_rpmbuild/tmp
D: execv(/opt/local/lib/rpm/check-files) pid 83219
D: waitpid(83219) rc 83219 status 0
error: Unable to open temp file.
RPM build errors:
Unable to open temp file.
Once the generated command is changed into the following format, it works fine:
$ rpmbuild -vvv -bb --target noarch --buildroot /Users/kowalskif/Desktop/GIT/hp-ws/mpf-client/_rpmbuild/t
mp --define "_topdir /Users/kowalskif/Desktop/GIT/hp-ws/mpf-client/_rpmbuild" --define "_tmppath /tmp" /Users/kowalskif/Desktop/GIT/hp-ws/mpf-client/_rpmbuild/SPECS/mpf-cli
ent.spec
As a confirmation, here is the content generated rpm:
$ rpm -qlp _rpmbuild/RPMS/noarch/mpf-client-0.1.0-SNAPSHOT20140616220711.noarch.rpm
/export/u1/pos-static/mpf/lib/bower_components/angular/angular-csp.css
/export/u1/pos-static/mpf/lib/bower_components/angular/angular.js
/export/u1/pos-static/mpf/lib/bower_components/angular/angular.min.js
[...]
Hopefully I'm doing something wrong. If you supply the dest without a trailing slash it treats the destination as a file.
e.g
files: [
{ dest: '/opt/some/folder', src : [ 'src/*/' ]}
],
The task would treat /opt/some/folder as a file and copy everything in src to rpm/tmp/app/opt/some/folder. I would get a very misleading error message:
Spawning rpmbuild: {"cmd":"rpmbuild","args":["-bb","--target","noarch","--buildroot","/usr/local/src/sample-rpm/rpm/app/tmp","/usr/local/src/sample-rpm/rpm/app/SPECS/sample.spec"]}
Warning: error: File not found: /usr/local/src/sample-rpm/rpm/app/tmp/opt/sample-app/src/Class.php
error: File not found: /usr/local/src/sample-rpm/rpm/app/tmp/opt/sample-app/src/Stuff/Other.php
File not found: /usr/local/src/sample-rpm/rpm/app/tmp/opt/sample-app/src/Class.php
File not found: /usr/local/src/sample-rpm/rpm/app/tmp/opt/sample-app/src/Stuff/Other.php Use --force to continue.
If I added a trailing slash, it worked as expected e.g.
files: [
{ dest: '/opt/some/folder/', src : [ 'src/*/' ]}
],
I only did a simple package after pulling my hair out. In src I made a subdir and two files with junk in them:
src/Stuff/Other.php
src/Class.php
{
"name": "my-sample",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-cli": "~0.1.13",
"grunt-rpm": "~0.1.6",
"grunt-bump": "0.0.14",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-copy": "~0.5.0",
"grunt-init": "~0.3.2",
"grunt-contrib-uglify": "~0.4.0",
"grunt-contrib-nodeunit": "~0.4.0",
"grunt-contrib-jshint": "~0.10.0"
}
}
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
rpm: {
app: {
options: {
release: true,
destination: 'rpm/app',
name: 'sample',
version: null,
release: true,
homepage: 'https://github.com/russellsimpkins',
summary: 'Sample RPM',
license: 'Proprietary',
distribution: 'limited',
vendor: 'undefined',
group: 'dev',
requires: null,
description: 'Sample application',
defaultFilemode: null,
defaultUsername: null,
defaultGroupname: null,
defaultDirmode: null,
preInstall: null,
postInstall: null,
preUninstall: null,
postUninstall: null,
},
files: [{ dest: '/opt/sample-app/', src : [ 'src//.' ], filter: function(filepath) {
return ! (filepath.match(/.git|.svn|phpunit/) ? true : false);
}
} ],
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-bump');
grunt.loadNpmTasks('grunt-rpm');
grunt.registerTask('default', ['rpm']);
};
In my setup grunt-rpm works properly but it fails on some projects, where dependencies have binaries in distribution. It's not the problem of grunt-rpm
itself, but of .spec
file it is generating.
To fix issue you should add %define _binaries_in_noarch_packages_terminate_build 0
into output rpm spec.
The readme is really lacking on how to define one of these and I haven't been able to get through it reading the source. It looks like you're looking for a external file to be defined to run, but the type for these are an object. I've tried:
postUninstall: 'myScript.sh'
and
postUninstall: { src: ['myScript.sh''] }
With not much luck. Anyone have a good example of how to specify a postinstall scriptlet here? Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.