From 4ff722ed69e1a3510610c7c286bd45e262428d03 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Wed, 20 Feb 2019 18:39:40 +0100 Subject: [PATCH] Finish grunt removal Zipball can now be created using `npm run dist`. --- .travis.yml | 1 - NEWS.md | 1 + README.md | 4 +- gruntfile.js | 110 ---------------------------------------- package.json | 10 ++-- utils/create-zipball.js | 102 +++++++++++++++++++++++++++++++++++++ utils/package.sh | 2 +- 7 files changed, 110 insertions(+), 120 deletions(-) delete mode 100644 gruntfile.js create mode 100644 utils/create-zipball.js diff --git a/.travis.yml b/.travis.yml index 23b8513426..edf942c79f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,6 @@ cache: before_install: - nvm install 6 - - npm install -g grunt-cli - npm install - if [ -n "$GH_TOKEN" ]; then composer config github-oauth.github.com ${GH_TOKEN}; fi - utils/install-phars.sh diff --git a/NEWS.md b/NEWS.md index 4d60e2350b..a24ee22b77 100644 --- a/NEWS.md +++ b/NEWS.md @@ -46,6 +46,7 @@ - More of user interface is now translatable ([#1054](https://github.com/SSilence/selfoss/pull/1054)) - Open Sans font is no longer bundled, resulting in smaller installations. Additionally, `use_system_font` option was removed. The typeface is still set as the default font family, so if you want to use it, install it to your devices. If you want to use a different typeface, add `body { font-family: 'Foo Face'; }` to your `user.css`. ([#1072](https://github.com/SSilence/selfoss/pull/1072)) - The file name of exported sources now includes a timestamp ([#1078](https://github.com/SSilence/selfoss/pull/1078)) +- Developers, we no longer use Grunt. Build the package using `npm run dist` and check the code using `npm run check`; see the `scripts` section in top-level `package.json`. ([#1093](https://github.com/SSilence/selfoss/pull/1093)) ## 2.18 – 2018-03-05 diff --git a/README.md b/README.md index e830b9a0b5..aa9b0da963 100644 --- a/README.md +++ b/README.md @@ -77,9 +77,9 @@ DEVELOPMENT Selfoss uses [composer](https://getcomposer.org/) for installing external libraries. When you clone the repository you have to issue `composer install` to retrieve the external sources. -For the client side, you will also need JavaScript dependencies installed by calling `npm install` in the `public` directory. +For the client side, you will also need JavaScript dependencies installed by calling `npm install` in the `public` directory. You can use `npm run install-dependencies` as a shortcut for installing both dependencies. -If you want to create a package with all the dependencies bundled, you will additionally require [grunt](https://gruntjs.com/). After installing it, execute `npm install` in the selfoss directory to obtain the required tasks. Then you can run `grunt` command to produce a zipball. As a bonus, you can also use `grunt install` as a shortcut for installing the selfoss dependencies described above. +If you want to create a package with all the dependencies bundled, you can run `npm run dist` command to produce a zipball. Every patch is expected to adhere to our coding style, which is checked automatically by Travis. You can install the checkers locally either with your package manager or by calling `utils/install-phars.sh`, and then run the checks using `npm run check` before submitting a pull request. diff --git a/gruntfile.js b/gruntfile.js deleted file mode 100644 index 5d56589ed5..0000000000 --- a/gruntfile.js +++ /dev/null @@ -1,110 +0,0 @@ -const path = require('path'); - -function isNotUnimportant(dest) { - const filename = path.basename(dest); - - const filenameDisallowed = [ - /^changelog/i, - /^contributing/i, - /^upgrading/i, - /^copying/i, - /^readme/i, - /^licen[cs]e/i, - /^version/i, - /^phpunit/, - /^l?gpl\.txt$/, - /^composer\.(json|lock)$/, - /^Makefile$/, - /^build\.xml$/, - /^phpcs-ruleset\.xml$/, - /^phpmd\.xml$/ - ].some(function(expr) { return expr.test(filename); }); - - const destDisallowed = [ - /^vendor\/htmlawed\/htmlawed\/htmLawed(Test\.php|(.*\.(htm|txt)))$/, - /^vendor\/smottt\/wideimage\/demo/, - /^vendor\/simplepie\/simplepie\/(db\.sql|autoload\.php)$/, - /^vendor\/composer\/installed\.json$/, - /^vendor\/[^/]+\/[^/]+\/(test|doc)s?/i, - /^vendor\/smalot\/pdfparser\/samples/, - /^vendor\/smalot\/pdfparser\/src\/Smalot\/PdfParser\/Tests/, - ].some(function(expr) { return expr.test(dest); }); - - const allowed = !(filenameDisallowed || destDisallowed); - - return allowed; -} - -module.exports = function(grunt) { - const requiredAssets = (function() { - const files = grunt.file.readJSON('public/package.json').extra.requiredFiles; - - return files.css.concat(files.js); - })(); - - grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - - /* Install client-side dependencies */ - auto_install: { - subdir: { - options: { - cwd: 'public', - npm: '--production' - } - } - }, - - /* create zip */ - compress: { - main: { - options: { - archive: 'selfoss-<%= pkg.ver %>.zip' - }, - files: [ - { expand: true, cwd: 'controllers/', src: ['**'], dest: '/controllers'}, - { expand: true, cwd: 'daos/', src: ['**'], dest: '/daos'}, - { expand: true, cwd: 'helpers/', src: ['**'], dest: '/helpers'}, - { expand: true, cwd: 'vendor/', src: ['**'], dest: '/vendor', filter: isNotUnimportant}, - - // do not pack bundled assets and assets not listed in index.php - { expand: true, cwd: 'public/', src: ['**'], dest: '/public', filter: function(file) { - const bundle = file === 'public/all.js' || file === 'public/all.css'; - const thirdPartyRubbish = file.startsWith('public/node_modules/') && requiredAssets.indexOf(file) === -1; - const allowed = !bundle && !thirdPartyRubbish; - - return allowed; - }}, - - // copy data: only directory structure and .htaccess for deny - { expand: true, cwd: 'data/', src: ['**'], dest: '/data', filter: 'isDirectory'}, - { src: ['data/cache/.htaccess'], dest: '' }, - { src: ['data/logs/.htaccess'], dest: '' }, - { src: ['data/sqlite/.htaccess'], dest: '' }, - { expand: true, cwd: 'data/fulltextrss', src: ['**'], dest: '/data/fulltextrss'}, - - { expand: true, cwd: 'spouts/', src: ['**'], dest: '/spouts'}, - { expand: true, cwd: 'templates/', src: ['**'], dest: '/templates'}, - - { src: ['.htaccess'], dest: '' }, - { src: ['README.md'], dest: '' }, - { src: ['defaults.ini'], dest: '' }, - { src: ['index.php'], dest: '' }, - { src: ['common.php'], dest: '' }, - { src: ['run.php'], dest: '' }, - { src: ['cliupdate.php'], dest: '' } - ] - } - }, - }); - - grunt.loadNpmTasks('grunt-auto-install'); - grunt.loadNpmTasks('grunt-contrib-compress'); - grunt.loadNpmTasks('grunt-composer'); - - grunt.registerTask('client:install', 'Install client-side dependencies.', ['auto_install']); - grunt.registerTask('server:install', 'Install server-side dependencies.', ['composer:install:no-dev:optimize-autoloader:prefer-dist']); - grunt.registerTask('install', 'Install both client-side and server-side dependencies.', ['client:install', 'server:install']); - grunt.registerTask('default', ['install', 'compress']); - grunt.registerTask('zip', ['compress']); -}; diff --git a/package.json b/package.json index adcbbc9243..9f7397fe60 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,8 @@ "url": "https://github.com/SSilence/selfoss.git" }, "devDependencies": { - "eslint": "^5.14.1", - "grunt": "^0.4.5", - "grunt-auto-install": "^0.3.1", - "grunt-cli": "^1.2.0", - "grunt-composer": "^0.4.5", - "grunt-contrib-compress": "^0.10.0" + "archiver": "^3.0.0", + "eslint": "^5.14.1" }, "engines": { "npm": ">=5" @@ -23,6 +19,8 @@ "check:client": "npm run lint:client", "check:server": "npm run lint:server && npm run cs:server", "cs:server": "composer run-script cs", + "dist": "npm install && npm run install-dependencies && node utils/create-zipball.js", + "install-dependencies": "composer install --no-dev --optimize-autoloader --prefer-dist && cd public && npm install --production", "lint:client": "eslint public/js/selfoss-*.js", "lint:server": "composer run-script lint", "postinstall": "npm install --prefix public/" diff --git a/utils/create-zipball.js b/utils/create-zipball.js new file mode 100644 index 0000000000..8f98f826ce --- /dev/null +++ b/utils/create-zipball.js @@ -0,0 +1,102 @@ +const fs = require('fs'); +const path = require('path'); +const archiver = require('archiver'); + +function filterEntry(fn) { + return (entry) => { + const obj = path.join(entry.prefix, entry.name).replace(/^\//, ''); + + return fn(obj) ? entry : false; + } +} + +function isNotUnimportant(dest) { + const filename = path.basename(dest); + + const filenameDisallowed = [ + /^\.git(ignore|attributes|keep)$/, + /^\.travis\.yml$/, + /^\.editorconfig$/, + /^changelog/i, + /^contributing/i, + /^upgrading/i, + /^copying/i, + /^readme/i, + /^licen[cs]e/i, + /^version/i, + /^phpunit/, + /^l?gpl\.txt$/, + /^composer\.(json|lock)$/, + /^Makefile$/, + /^build\.xml$/, + /^phpcs-ruleset\.xml$/, + /^\.php_cs$/, + /^phpmd\.xml$/ + ].some(expr => expr.test(filename)); + + const destDisallowed = [ + /^vendor\/htmlawed\/htmlawed\/htmLawed(Test\.php|(.*\.(htm|txt)))$/, + /^vendor\/smalot\/pdfparser\/\.atoum\.php$/, + /^vendor\/smottt\/wideimage\/demo/, + /^vendor\/simplepie\/simplepie\/(db\.sql|autoload\.php)$/, + /^vendor\/composer\/installed\.json$/, + /^vendor\/[^/]+\/[^/]+\/(test|doc)s?/i, + /^vendor\/[^/]+\/[^/]+\/\.git(\/|$)/, + /^vendor\/smalot\/pdfparser\/samples/, + /^vendor\/smalot\/pdfparser\/src\/Smalot\/PdfParser\/Tests/, + ].some(expr => expr.test(dest)); + + const allowed = !(filenameDisallowed || destDisallowed); + + return allowed; +} + +const requiredAssets = (function() { + const files = JSON.parse(fs.readFileSync('public/package.json', 'utf-8')).extra.requiredFiles; + + return files.css.concat(files.js); +})(); + + +const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8')); + +var output = fs.createWriteStream(`selfoss-${pkg.ver}.zip`); +var archive = archiver('zip'); +archive.pipe(output); + + +// fill archive with data + +archive.directory('controllers/', '/controllers'); +archive.directory('daos/', '/daos'); +archive.directory('helpers/', '/helpers'); +archive.directory('vendor/', '/vendor', filterEntry(isNotUnimportant)); + +// do not pack bundled assets and assets not listed in index.php +archive.directory('public/', '/public', filterEntry(file => { + const bundle = file === 'public/all.js' || file === 'public/all.css'; + const thirdPartyRubbish = file.startsWith('public/node_modules/') && requiredAssets.indexOf(file) === -1; + const allowed = !bundle && !thirdPartyRubbish; + + return allowed; +})); + +// copy data: only directory structure and .htaccess for deny +archive.directory('data/', '/data', filterEntry(file => fs.lstatSync(file).isDirectory())); +archive.file('data/cache/.htaccess'); +archive.file('data/logs/.htaccess'); +archive.file('data/sqlite/.htaccess'); +archive.directory('data/fulltextrss', '/data/fulltextrss'); + +archive.directory('spouts/', '/spouts'); +archive.directory('templates/', '/templates'); + +archive.file('.htaccess'); +archive.file('README.md'); +archive.file('defaults.ini'); +archive.file('index.php'); +archive.file('common.php'); +archive.file('run.php'); +archive.file('cliupdate.php'); + +archive.finalize(); diff --git a/utils/package.sh b/utils/package.sh index 051b75731a..9ebc6187cc 100755 --- a/utils/package.sh +++ b/utils/package.sh @@ -5,4 +5,4 @@ if [ -z "$TRAVIS_TAG" ]; then npm run bump-version $NEW_VERSION fi -grunt +npm run dist