Repository: jbrodriguez/hugulp
Branch: master
Commit: 32d69d613179
Files: 33
Total size: 35.7 KB
Directory structure:
gitextract_nmjweurq/
├── .cix.yml
├── .gitignore
├── .prettierrc
├── CHANGES
├── LICENSE
├── README.md
├── VERSION
├── docker/
│ ├── Dockerfile.template
│ └── docker-compose.yaml.template
├── gulp/
│ ├── build.js
│ ├── util.js
│ └── watch.js
├── index.js
├── metadata/
│ └── changes/
│ ├── 0.1.0.txt
│ ├── 1.0.0.txt
│ ├── 1.1.0.txt
│ ├── 1.1.1.txt
│ ├── 1.1.2.txt
│ ├── 1.2.0.txt
│ ├── 1.3.0.txt
│ ├── 1.4.0.txt
│ ├── 2.0.0.txt
│ ├── 2.0.1.txt
│ ├── 2.0.2.txt
│ ├── 2.0.3.txt
│ ├── 2.0.4.txt
│ ├── 2.0.5.txt
│ └── 2.0.6.txt
├── package.json
└── scripts/
├── bump-hook
├── create-docker-machine-and-run-it
├── create-hugo-site
└── rel-push-prog
================================================
FILE CONTENTS
================================================
================================================
FILE: .cix.yml
================================================
test:
script:
# - scripts/rel-push-prog
only:
- /^wrk.*$/
deploy:
script:
- scripts/rel-push-prog
- npm publish
only:
- /^rel.*$/
================================================
FILE: .gitignore
================================================
.DS_Store
public
# node
node_modules
*.log
# bower
bower_components
src/vendor
# docker
Dockerfile
docker-compose.yaml
================================================
FILE: .prettierrc
================================================
{
"singleQuote": true,
"printWidth": 80,
"semi": false,
"useTabs": false,
"tabWidth": 2
}
================================================
FILE: CHANGES
================================================
Version 2.0.6 - 2018-10-28
- log relative path while watching styles (#45)
Version 2.0.5 - 2017-12-12
- Fix scripts task build source
Version 2.0.4 - 2017-12-12
- Set saner htmlmin defaults
Version 2.0.3 - 2017-12-12
- Make cleancss the default styles transformation
- Display pipeline being executed
- Restore default styles logic
- Add callback to sequence call
- Display space optimization achieved
Version 2.0.2 - 2017-12-12
- Fix plugin names
Version 2.0.1 - 2017-12-12
- Run styles/scripts tasks on watch invocation
- Use proper JSON syntax
- Fix update instructions
- Add granular imagemin configuration
- Adjust default .hugulprc
Version 2.0.0 - 2017-12-12
- Read/compile sass and scss (#37)
- Replace var (#34)
- Replace yarn with npm5
- Use standard format
- Implement hugulp next
- Add init command
- Clean up & add logging
- Code refactoring
- Add missing package
- Update docs for v2
- Implements next
- Remove v1 code
- Fix inclusion of production files
- Use vscode instead of atom
Version 1.4.0 - 2017-11-27
- Add docker support (#24)
- Minifyhtml (#31)
Version 1.3.0 - 2017-03-20
- Add less support
- Ignore log files
- Expand glob for assets
- Update README
- Remove log file
- Release 1.2.0
- Display hugulp version
- Add less to watched files
- Upgrade dependencies
- Replace gulp.watch with gulp-watch
- Fix styles folder watch
- Update README
Version 1.2.0 - 2017-03-18
- Ignore log files
- Add less support
- Expand glob for assets
- Update README
- Remove log file
Version 1.1.2 - 2017-03-17
- Process subdirectories
Version 1.1.1 - 2017-02-12
- Fix build command
Version 1.1.0 - 2017-01-28
- Use hugo default config file
Version 1.0.0 - 2017-01-08
- Add commander dependency
- Create cli interface
- Rename src folder to assets
- Remove files no longer required
- Support css files
- Rewrite instructions
- Publish to npm on CI
- Update package.json upon new release
Version 0.1.0 - 2017-01-06
- Initial commit
- syntax fix for package.json
- Add missing semicolons
- Replace tabs with spaces
- Update reference.js
- - Update packages
- Improve project details and instructions
- Fix syntax error
- Delete public folder when running gulp task. Also delete (if existing) the public folder inside hugo.
- Update dependencies
- Implement CI automation
- Add missing variable
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2015 Juan B. Rodriguez
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# DEPRECATION NOTICE
I'll archive the repo by the end of August 2021.
The main reason is [Hugo pipes](https://gohugo.io/hugo-pipes/) are built-in and pretty much cover what Hugulp does.
I think the only part missing is image optimization, but I think you can build a pipe to do it.
The other reason is it badly needs an update to gulp 4 and although it doesn't seem like that hard a task, I don't have the appetite to do it.
# hugulp 2
## v2 Breaking changes
If you're using hugulp v1, please take note of the following changes:
* hugo is no longer invoked by hugulp
use hugo as per its docs, then invoke hugulp build
* put your assets in the static folder
for example, static/styles, static/images, static/scripts
* themes are supported out of the box
_Note: If you need sass/less/js pre-processing, read v2 docs below_
## Description
`hugulp` is a tool to optimize the assets of a [Hugo](https://gohugo.io) website.
The main idea is to recreate the famous [Ruby on Rails Asset Pipeline](http://guides.rubyonrails.org/asset_pipeline.html), which minifies, concatenates and fingerprints the assets used in your website.
This leads to less and smaller network requests to your page, improving overall user experience.
Read [this blog post](https://jbrio.net/posts/mobile-friendly-website-2/) and [this article](https://medium.com/@juanbrodriguez/hugulp-a-hugo-gulp-toolchain-94f72ccc3577) for additional context.
_Note: These articles refer to v1_
It's internally driven by [Gulp](https://gulpjs.com).
This project Includes the following tools, tasks and workflows:
* [sass](https://github.com/dlmanning/gulp-sass) (super fast libsass)
* [less](https://github.com/plus3network/gulp-less)
* [autoprefixer](https://github.com/sindresorhus/gulp-autoprefixer)
* [clean-css](https://github.com/scniro/gulp-clean-css)
* [jshint](https://github.com/spalger/gulp-jshint)
* [uglify](https://github.com/terinjokes/gulp-uglify)
* [imagemin](https://github.com/sindresorhus/gulp-imagemin) (only [changed images](https://github.com/sindresorhus/gulp-changed))
* [gulp-rev](https://github.com/sindresorhus/gulp-rev), [gulp-rev-replace](https://github.com/jamesknelson/gulp-rev-replace) (fingerprinting)
* [htmlmin](https://github.com/jonschlinkert/gulp-htmlmin)
* [watch](https://github.com/floatdrop/gulp-watch)
## Installation
[Node](https://nodejs.org) needs to be installed in your system.
Then just
```bash
$ npm install -g hugulp
```
Or you can build and run using [docker](https://www.docker.com):
```bash
# Default docker setup:
$ ./scripts/create-docker-machine-and-run-it
# -- OR --
# Run with custom machine name, specific hugo version, specific node version and run docker in detached mode:
$ ./scripts/create-docker-machine-and-run-it -a app-devel -g 0.20.6 -n 6.10.0 -d
```
**Note:** You only run the `./scripts/create-docker-machine-and-run-it` if you want to create a new docker machine. Once the docker machine is created, you have to use docker commands to manage it. Please be familiar with docker in this regard.
## Getting Started
The most common usage scenario would be:
```bash
$ hugo new site yoursite
$ cd yoursite
$ hugulp init
# create content
# add images (static/images), css (static/styles) and javascript (static/scripts)
$ hugo server -D # for development
# development is done, ready to publish
$ rm -rf public # clean up public folder, it will be re-generated by hugo
$ hugo # for release/production/deployment
$ hugulp build # optimize the site by running the asset pipeline
```
Another scenario would be to include sass/less pre-processing:
```bash
$ hugo new site yoursite
$ cd yoursite
$ hugulp init
# create content
# add images (static/images), and javascript (static/scripts)
# add sass/less (assets/styles)
$ hugo server -D # for development
$ hugulp watch # to convert sass/less (assets/styles) into css (static/styles)
# development is done, ready to publish
$ rm -rf public # clean up public folder, it will be re-generated by hugo
$ hugo # for release/production/deployment
$ hugulp build # optimize the site by running the asset pipeline
```
In both cases, you could chain the last 3 commands:
```bash
$ rm -rf public && hugo && hugulp build
```
`hugulp` requires a configuration file (`.hugulprc`), which is created by the `hugulp init` command (you can create the file manually if you want).
This is the default `.hugulprc`:
```json
{
"version": 2,
"pipeline": ["images", "styles", "scripts", "fingerprint", "html"],
"path": {
"styles": "styles",
"images": "images",
"scripts": "scripts"
},
"watch": {
"source": "assets",
"target": "static"
},
"build": {
"source": "public",
"target": "public"
},
"autoprefixer": {
"browsers": ["last 2 versions"]
},
"cleancss": {
"advanced": false
},
"htmlmin": {
"collapseWhitespace": true
},
"gifsicle": { "interlaced": true },
"jpegtran": { "progressive": true },
"optipng": { "optimizationLevel": 5 },
"svgo": {
"plugins": [{ "removeViewBox": true }, { "cleanupIDs": false }]
}
}
```
You can easily customize `hugulp`'s behavior, by modifying this configuration file, as described below.
## Available Commands
### hugulp watch
`hugulp` will assist you if you're using sass/less (and javascript), which require pre-processing.
It will watch for changes to styles or script files, process them and write them to hugo's static folder, according to the following table
| In Folder | Looks for | Operation | Written to |
| -------------- | :------------------: | -------------------------------------- | -------------- |
| assets/styles | s[a\|c]ss, less, css | Convert sass/less to css | static/styles |
| assets/scripts | js | Lint javascript code (_soon babelify_) | static/scripts |
_Note: It searches the folders recursively_
The table above applies to `hugulp` run with a default `.hugulprc`.
You can customize the folder names: `resources` instead of `assets`, `js` instead of `scripts` and so on.
This is described in the `.hugulprc` section below.
### hugulp build
It optimizes the site that hugo built, by running the asset pipeline as defined in `.hugulprc` (field _pipeline_).
Additionally, files are not watched for changes
### hugulp version
Display installed version.
### hugulp init
Create a default `.hugulprc`.
## Configuration
By editing the `.hugulprc` configuration file, you can customize almost anything about `hugulp`.
Description of each field follows:
### pipeline
Defines which tasks of the asset pipeline will be executed (`hugulp build` command)
Type: array
Default:
```json
"pipeline": ["images", "styles", "scripts", "fingerprint", "html"]
```
| Task | Description |
| ----------- | ------------------------------------------------------------------ |
| images | minify images with `imagemin` |
| styles | pre-process `sass`/`less`/css, then `clean-css` |
| scripts | `jshint`, then `uglify` |
| fingerprint | fingerprint with `rev`, then replace references with `rev-replace` |
| html | minify html with `htmlmin` |
Let's say you don't want to fingerprint the assets. Just set _pipeline_ to
```json
"pipeline": ["images", "styles", "scripts", "html"]
```
By removing the _fingerprint_ task, it will not be executed.
Note that tasks are executed sequentially.
### path
Defines the name of the folders where your assets are located/will be transferred to.
Type: object
Default:
```json
"path": {
"styles": "styles",
"images": "images",
"scripts": "scripts"
}
```
So if you prefer your styles folder to be called css, and scripts to be called js, you would change it to:
```json
"path": {
"styles": "css",
"images": "images",
"scripts": "js"
}
```
### watch
Define which folders to watch for changes, for the `hugulp watch` command.
Type: object
Default:
```json
"watch": {
"source": "assets",
"target": "static"
}
```
This field works together with the path field.
With a default `.hugulprc`, it will watch `assets/styles` and `assets/scripts` (recursively).
If you customized `path` as per above, it will watch `assets/css` and `assets/js`.
If you additionally want the `assets` folder to be called `resources`, change _source_ to `resources`
```json
"watch": {
"source": "resources",
"target": "static"
}
```
then it will watch `resources/css` and `resources/js`
Finally, the changes will be written to the well-known hugo static folder.
With a default `.hugulprc`, files will be written to `static/styles` and `static/scripts`.
### build
Defines the folders referenced during the `hugulp build` command
Type: object
Default:
```json
"build": {
"source": "public",
"target": "public"
}
```
This should generally be left unchanged.
`hugo` will output to the public folder by default, so `hugulp build` will process the files in-place.
### autoprefixer
Options for `autoprefixer`. Check [gulp-autoprefixer](https://github.com/sindresorhus/gulp-autoprefixer) for documentation.
Task: `styles`
Type: object
Default:
```json
"autoprefixer": {
"browsers": ["last 2 versions"]
}
```
### cleancss
Options for `clean-css`. Check [gulp-clean-css](https://github.com/scniro/gulp-clean-css) for documentation.
Task: `styles`
Default:
```json
"cleancss": {
"advanced": false
}
```
### htmlmin
Options for `htmlmin`. Check [gulp-htmlmin](https://github.com/jonschlinkert/gulp-htmlmin) for documentation.
Task: `html`
Default:
```json
"htmlmin": {
"collapsedWhitespace": true
}
```
### gifsicle
Options for `gifsicle`. Check [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin) for documentation.
Task: `images`
Default:
```json
"gifsicle": {
"interlaced": true
}
```
### jpegtran
Options for `jpegtran`. Check [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin) for documentation.
Task: `images`
Default:
```json
"jpegtran": {
"progressive": true
}
```
### optipng
Options for `optipng`. Check [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin) for documentation.
Task: `images`
Default:
```json
"optipng": {
"optimizationLevel": 5
}
```
### svgo
Options for `svgo`. Check [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin) for documentation.
Task: `images`
Default:
```json
"svgo": {
"plugins": [{ "removeViewBox": true }, { "cleanupIDs": false }]
}
```
## How to update
Whenever a new `hugulp` version becomes available, you can update it by running
```bash
$ npm install -g hugulp
```
## PR
Pull Requests are welcome :thumbsup:.
## Share
Made by [Juan B. Rodriguez](http://jbrodriguez.io), with a MIT License.
Please [share the article or leave your comments](http://jbrodriguez.io/mobile-friendly-website-2/).
================================================
FILE: VERSION
================================================
2.0.6
================================================
FILE: docker/Dockerfile.template
================================================
FROM node:7.9.0-alpine
# Set environment variable
ARG RUN_AS=node
ARG HUGO_VERSION=0.20.6
ARG HUGO_BINARY="hugo_${HUGO_VERSION}_Linux-64bit"
RUN apk update && apk add py-pygments && rm -rf /var/cache/apk/*
# Download and install hugo
RUN mkdir /usr/local/hugo
ADD https://github.com/spf13/hugo/releases/download/v${HUGO_VERSION}/${HUGO_BINARY}.tar.gz \
/usr/local/hugo/
RUN tar xzf /usr/local/hugo/${HUGO_BINARY}.tar.gz -C /usr/local/hugo/ \
&& ln -s /usr/local/hugo/hugo /usr/local/bin/hugo \
&& rm /usr/local/hugo/${HUGO_BINARY}.tar.gz
RUN npm install -g hugulp
ENV HOME=/home/$RUN_AS
COPY package.json $HOME/web/
RUN chmod 755 $HOME/* && chown -R $RUN_AS:$RUN_AS $HOME/*
USER $RUN_AS
# Change working directory
WORKDIR $HOME/web/
USER root
COPY . $HOME/web/
RUN chown -R $RUN_AS:$RUN_AS $HOME/*
USER $RUN_AS
================================================
FILE: docker/docker-compose.yaml.template
================================================
---
version: '3'
services:
app:
labels:
app: "app"
build:
context: .
command: /bin/sh -c './scripts/create-hugo-site -a ./app;cd app;hugulp watch'
volumes:
- .:/home/node/app
- /home/node/app/node_modules
ports:
- "3000:3000"
- "3001:3001"
================================================
FILE: gulp/build.js
================================================
// system
const fs = require('fs')
const path = require('path')
// parameters
const config = JSON.parse(
fs.readFileSync(path.join(process.cwd(), '.hugulprc'))
)
// common
const gulp = require('gulp')
const sequence = require('run-sequence')
const debug = require('gulp-debug')
const size = require('gulp-size')
const pump = require('pump')
const gutil = require('gulp-util')
// images
const imagemin = require('gulp-imagemin')
// styles
const autoprefixer = require('gulp-autoprefixer')
const cleancss = require('gulp-clean-css')
const merge = require('merge-stream')
const concat = require('gulp-concat')
const helper = require('./util')
// const changed = require('gulp-changed')
// scripts
const jshint = require('gulp-jshint')
const uglify = require('gulp-uglify')
// revision
const rev = require('gulp-rev')
const revdel = require('rev-del')
const delorg = require('gulp-rev-delete-original')
const del = require('del')
// reference
const replace = require('gulp-rev-replace')
// minify html
const htmlmin = require('gulp-htmlmin')
gulp.task('build', function(cb) {
gutil.log(
gutil.colors.green(`building site ... (${JSON.stringify(config.pipeline)})`)
)
// config.pipeline is an array of task names
// i.e.: ['images', 'styles']
sequence(...config.pipeline, cb)
})
// .pipe(changed('staging/img'))
gulp.task('images', function() {
return gulp
.src(path.join(config.build.source, config.path.images, '**', '*.*')) // i.e.: public/images/**/*.*
.pipe(
imagemin([
imagemin.gifsicle(config.gifsicle),
imagemin.jpegtran(config.jpegtran),
imagemin.optipng(config.optipng),
imagemin.svgo(config.svgo)
])
)
.pipe(gulp.dest(path.join(config.build.target, config.path.images))) // i.e.: public/images
})
gulp.task('styles:cleancss', function() {
const streams = helper.getStylesStreams()
return merge(...streams)
.pipe(autoprefixer(config.autoprefixer))
.pipe(cleancss(config.cleancss))
.pipe(concat('styles.css'))
.pipe(size({ title: 'styles: ' }))
.pipe(gulp.dest(path.join(config.build.target, config.path.styles))) // i.e.: public/styles/styles.css
})
// default styles task
gulp.task('styles', function(cb) {
sequence('styles:cleancss', cb)
})
gulp.task('scripts', function() {
return gulp
.src(path.join(config.watch.source, config.path.scripts, '**', '*.js'))
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(uglify())
.pipe(size({ title: 'scripts: ' }))
.pipe(gulp.dest(path.join(config.build.target, config.path.scripts)))
})
gulp.task('revision', function() {
return gulp
.src(
[
path.join(config.build.source, config.path.styles, '**/*.css'),
path.join(config.build.source, config.path.scripts, '**/*.js'),
path.join(config.build.source, config.path.images, '**/*.*')
],
{ base: path.join(process.cwd(), config.build.source) }
)
.pipe(rev())
.pipe(delorg())
.pipe(gulp.dest(config.build.target))
.pipe(rev.manifest())
.pipe(revdel({ dest: config.build.target }))
.pipe(gulp.dest(config.build.target))
})
gulp.task('reference', function() {
const manifest = gulp.src(path.join(config.build.source, 'rev-manifest.json'))
return gulp
.src([
path.join(config.build.source, '**/*.html'),
path.join(config.build.source, '**/*.xml'),
path.join(config.build.source, '**/*.css')
])
.pipe(
replace({
manifest: manifest,
replaceInExtensions: ['.html', '.xml', '.css']
})
)
.pipe(gulp.dest(config.build.target))
})
gulp.task('fingerprint', function(cb) {
sequence('revision', 'reference', cb)
})
gulp.task('html', function(cb) {
pump(
[
gulp.src(path.join(config.build.source, '**', '*.html')),
htmlmin(config.htmlmin),
size({ title: 'html: ' }),
gulp.dest(config.build.target)
],
cb
)
})
================================================
FILE: gulp/util.js
================================================
// system
const fs = require('fs')
const path = require('path')
// common
const gulp = require('gulp')
// styles
const sass = require('gulp-sass')
const less = require('gulp-less')
const concat = require('gulp-concat')
// parameters
const config = JSON.parse(
fs.readFileSync(path.join(process.cwd(), '.hugulprc'))
)
// helper functions
function getStylesStreams() {
const lessStream = gulp
.src(path.join(config.watch.source, config.path.styles, '**/*.less')) // i.e.: assets/styles/**/*.less
.pipe(less())
.pipe(concat('less-files.css'))
const scssStream = gulp
.src(path.join(config.watch.source, config.path.styles, '**/*.s[a|c]ss')) // i.e.: assets/styles/**/*.s[a|c]ss
.pipe(sass())
.pipe(concat('scss-files.css'))
const cssStream = gulp
.src(path.join(config.watch.source, config.path.styles, '**/*.css')) // i.e.: assets/styles/**/*.css
.pipe(concat('css-files.css'))
return [lessStream, scssStream, cssStream]
}
module.exports = { getStylesStreams }
================================================
FILE: gulp/watch.js
================================================
// system
const fs = require('fs')
const path = require('path')
// parameters
const config = JSON.parse(
fs.readFileSync(path.join(process.cwd(), '.hugulprc'))
)
// common
const gulp = require('gulp')
const sequence = require('run-sequence')
const watch = require('gulp-watch')
const gutil = require('gulp-util')
// styles
const merge = require('merge-stream')
const concat = require('gulp-concat')
const helper = require('./util')
// scripts
const jshint = require('gulp-jshint')
gulp.task('watch', function() {
const styles = [
path.join(config.watch.source, config.path.styles, '**', '*.s[a|c]ss'),
path.join(config.watch.source, config.path.styles, '**', '*.less'),
path.join(config.watch.source, config.path.styles, '**', '*.css')
]
gutil.log(gutil.colors.green(`running styles task ...`))
gulp.start('styles')
gutil.log(gutil.colors.green(`watching ${JSON.stringify(styles)}`))
watch(styles, {}, function handle(param) {
const relativePath = function(path) {
return path.substring(String(process.cwd()).length)
}
gutil.log(
gutil.colors.yellow(
`styles: ${JSON.stringify(relativePath(param.history[0]))} - ${param.event}`
)
)
gulp.start('styles')
})
const scripts = [
path.join(config.watch.source, config.path.scripts, '**', '*.js')
]
gutil.log(gutil.colors.green(`running scripts task ...`))
gulp.start('scripts')
gutil.log(gutil.colors.green(`watching ${JSON.stringify(scripts)}`))
watch(scripts, {}, function handle(param) {
gutil.log(
gutil.colors.yellow(
`scripts: ${JSON.stringify(param.history[0])} - ${param.event}`
)
)
gulp.start('scripts')
})
})
gulp.task('styles:cleancss', function() {
const streams = helper.getStylesStreams()
return merge(...streams)
.pipe(concat('styles.css'))
.pipe(gulp.dest(path.join(config.watch.target, config.path.styles))) // i.e.: static/styles/styles.css
})
// default styles task
gulp.task('styles', function(cb) {
sequence('styles:cleancss', cb)
})
gulp.task('scripts', function() {
return gulp
.src(path.join(config.watch.source, config.path.scripts, '**', '*.js'))
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(gulp.dest(path.join(config.watch.target, config.path.scripts)))
})
================================================
FILE: index.js
================================================
#!/usr/bin/env node
const path = require('path')
const fs = require('fs')
const program = require('commander')
const gulp = require('gulp')
const pkginfo = require('pkginfo')(module, 'version')
const gutil = require('gulp-util')
function init() {
gutil.log(gutil.colors.red(`hugulp v${module.exports.version}`))
const hugulpRc = path.join(process.cwd(), '.hugulprc')
if (fs.existsSync(hugulpRc)) {
gutil.log(
gutil.colors.yellow('.hugulprc already exists (initialization skipped)')
)
return
}
const config = {
version: 2,
pipeline: ['images', 'styles', 'scripts', 'fingerprint', 'html'],
path: {
styles: 'styles',
images: 'images',
scripts: 'scripts'
},
watch: {
source: 'assets',
target: 'static'
},
build: {
source: 'public',
target: 'public'
},
autoprefixer: {
browsers: ['last 2 versions']
},
cleancss: {
advanced: false
},
htmlmin: {
collapseWhitespace: true
},
gifsicle: { interlaced: true },
jpegtran: { progressive: true },
optipng: { optimizationLevel: 5 },
svgo: {
plugins: [{ removeViewBox: true }, { cleanupIDs: false }]
}
}
fs.writeFileSync(hugulpRc, JSON.stringify(config, null, ' '))
gutil.log(
gutil.colors.green(
'hugulp has been initialized (.hugulprc was created with default values)'
)
)
}
function build() {
gutil.log(gutil.colors.red(`hugulp v${module.exports.version}`))
require(path.join(fs.realpathSync(__dirname), 'gulp', 'build'))
gulp.start('build')
}
function watch() {
gutil.log(gutil.colors.red(`hugulp v${module.exports.version}`))
require(path.join(fs.realpathSync(__dirname), 'gulp', 'watch'))
gulp.start('watch')
}
function version() {
console.log('hugulp v' + module.exports.version)
}
program
.command('init')
.description('create default .hugulprc')
.action(init)
program
.command('version')
.description('display version information')
.action(version)
program
.command('build')
.description('optimize site (for publishing purposes)')
.action(build)
program
.command('watch')
.description('watch for changes to styles and/or javascript')
.action(watch)
program.parse(process.argv)
================================================
FILE: metadata/changes/0.1.0.txt
================================================
2017-01-06 - 0.1.0
- Initial commit
- syntax fix for package.json
- Add missing semicolons
- Replace tabs with spaces
- Update reference.js
- - Update packages
- Improve project details and instructions
- Fix syntax error
- Delete public folder when running gulp task. Also delete (if existing) the public folder inside hugo.
- Update dependencies
- Implement CI automation
- Add missing variable
================================================
FILE: metadata/changes/1.0.0.txt
================================================
2017-01-08 - 1.0.0
hugulp is now a standalone tool.
This allows for the following improvements
- Easier to work on multiple sites
- Easier to update
- Can be used in CI/CD workflows
================================================
FILE: metadata/changes/1.1.0.txt
================================================
2017-01-28 - 1.1.0
hugulp now uses hugo default config file (config.toml)
You can specify an alternative config, via a command line switch
-c, --config
================================================
FILE: metadata/changes/1.1.1.txt
================================================
2017-02-12 - 1.1.1
```hugulp build``` now creates a site without drafts and without
baseUrl
================================================
FILE: metadata/changes/1.1.2.txt
================================================
2017-03-17 - 1.1.2
```hugulp``` now processes subdirectories in the assets folders, if present.
================================================
FILE: metadata/changes/1.2.0.txt
================================================
2017-03-18 - 1.2.0
Add support for less files
================================================
FILE: metadata/changes/1.3.0.txt
================================================
2017-03-20 - 1.3.0
Added a command to display the current version: ```hugulp version```
A bug that was preventing the styles folder to react to changes was fixed.
Additionally:
- Upgrade dependencies
- Replace gulp.watch with gulp-watch
================================================
FILE: metadata/changes/1.4.0.txt
================================================
2017-11-27 - 1.4.0
- Add docker support (#24)
- Minifyhtml (#31)
================================================
FILE: metadata/changes/2.0.0.txt
================================================
2017-12-12 - 2.0.0
This is a re-thinking of hugulp, in order to be more flexible and better support hugo's features.
hugulp now works as a post-processor, optimizing the output that hugo generates in the public folder.
You can now invoke hugo from the command line as it best suits you and use any theme you want.
Check the README for v2 docs.
================================================
FILE: metadata/changes/2.0.1.txt
================================================
2017-12-12 - 2.0.1
- Run styles/scripts tasks on watch invocation
- Add granular imagemin configuration
- Adjust default .hugulprc
- Fix JSON syntax in README
- Fix update instructions
================================================
FILE: metadata/changes/2.0.2.txt
================================================
2017-12-12 - 2.0.2
- Fix plugin names
================================================
FILE: metadata/changes/2.0.3.txt
================================================
2017-12-12 - 2.0.3
- Make sure all tasks are executed
- Display pipeline being executed
- Display space optimization achieved
================================================
FILE: metadata/changes/2.0.4.txt
================================================
2017-12-12 - 2.0.4
- Set saner htmlmin defaults
================================================
FILE: metadata/changes/2.0.5.txt
================================================
2017-12-12 - 2.0.5
- Fix scripts task build source
================================================
FILE: metadata/changes/2.0.6.txt
================================================
2018-10-28 - 2.0.6
- Log relative path while watching styles
================================================
FILE: package.json
================================================
{
"name": "hugulp",
"version": "2.0.6",
"description": "website",
"files": [
"index.js",
"gulp"
],
"bin": {
"hugulp": "./index.js"
},
"scripts": {
"gulp": "gulp",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Juan B. Rodriguez",
"license": "MIT",
"dependencies": {
"commander": "^2.12.2",
"del": "^3.0.0",
"gulp": "^3.9.1",
"gulp-autoprefixer": "^4.0.0",
"gulp-changed": "^3.1.1",
"gulp-clean-css": "^3.9.0",
"gulp-concat": "^2.6.1",
"gulp-debug": "^3.1.0",
"gulp-htmlmin": "^3.0.0",
"gulp-imagemin": "^4.0.0",
"gulp-jshint": "^2.0.4",
"gulp-less": "^3.3.2",
"gulp-rev": "^8.1.0",
"gulp-rev-delete-original": "^0.2.3",
"gulp-rev-replace": "^0.4.3",
"gulp-sass": "^3.1.0",
"gulp-size": "^2.1.0",
"gulp-svgmin": "^1.2.4",
"gulp-uglify": "^3.0.0",
"gulp-util": "^3.0.8",
"gulp-watch": "^4.3.11",
"jshint": "^2.9.5",
"merge-stream": "^1.0.1",
"path": "^0.12.7",
"pkginfo": "^0.4.1",
"pump": "^2.0.0",
"rev-del": "^1.0.5",
"run-sequence": "^2.2.0"
}
}
================================================
FILE: scripts/bump-hook
================================================
#!/usr/bin/env bash
function error {
NAME=$1
printf "$1"
exit 1
}
APP_VERSION=$(cat VERSION 2> /dev/null)
if [[ -z $APP_VERSION ]]; then
error "Unable to find VERSION file. Please check and try again"
fi
echo "Version is $APP_VERSION"
npm --no-git-tag-version -f version ${APP_VERSION}
TAG=`git describe --abbrev=0 --tags 2> /dev/null`
if [[ -z "$TAG" ]]; then
COMMITS=`git --no-pager log --reverse --pretty=format:'- %s' | egrep -v '.*Closes' | egrep -v '.*Merge' 2> /dev/null`
else
COMMITS=`git --no-pager log --reverse --pretty=format:'- %s' "$TAG"...HEAD | egrep -v '.*Closes' | egrep -v '.*Merge' 2> /dev/null`
fi
PREVIOUS=`cat metadata/changes/${TAG}.txt 2> /dev/null`
cat < metadata/changes/${APP_VERSION}.txt
`date +%F` - ${APP_VERSION}
${COMMITS}
${PREVIOUS}
EOF
code metadata/changes/${APP_VERSION}.txt
echo "Bumped versions successfully"
================================================
FILE: scripts/create-docker-machine-and-run-it
================================================
#!/bin/bash
#
# Setup a docker machine for development
set -eu
readonly PROGNAME=$(basename "$0")
readonly ARGS=("$@")
# Docker settings
HUGO_VERSION=0.20.6
NODE_VERSION="7.9.0-alpine"
APP_NAME="app"
DETACHED=
check_where_cmd_is_run() {
# Check if script is being run from the root directory
if [ ! -d 'gulp' ]; then
cat <<- EOF
Please run this script from the root directory.
Example:
./scripts/create-docker-machine-and-run-it
-- OR --
bash ./scripts/create-docker-machine-and-run-it
EOF
exit 1
fi
}
usage() {
cat <<- EOF
Usage: ./scripts/$PROGNAME optional options
Setups a docker machine and runs it for development.
OPTIONS:
-g --hugo-version the hugo version to be installed. Minus v or version prefix. It defaults to 0.9
-n --node-version the node version to be installed. Minus v or version prefix. It defaults to 6.10.0
-a --app-name the name of the app. It defaults to app
-d --detached detached mode: Run containers in the background, print new container names.
-h --help show this help
Examples:
Run with default settings:
./scripts/$PROGNAME
Run with custom machine name, specific hugo version, specific node version and run docker in detached mode:
bash ./scripts/$PROGNAME -a app-name -g 0.9 -n 6.10.0
EOF
}
cmdline() {
local arg=
local args=
for arg; do
local delim=""
case "$arg" in
# Copied from: http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/
# Translate --machine-name to -m (short options)
--hugo-version) args="${args}-g ";;
--node-version) args="${args}-n ";;
--app-name) args="${args}-a ";;
--detached) args="${args}-d ";;
--help) args="${args}-h ";;
#pass through anything else
*) [[ "${arg:0:1}" == "-" ]] || delim="\""
args="${args}${delim}${arg}${delim} ";;
esac
done
while getopts "g:n:a:dh" OPTION; do
case "$OPTION" in
h)
usage
exit 0
;;
g)
HUGO_VERSION=$OPTARG
;;
n)
NODE_VERSION=$OPTARG
;;
a)
APP_NAME=$OPTARG
;;
d)
DETACHED='-d'
;;
esac
done
return 0
}
create_docker_file() {
# Check to make sure Dockerfile exist
if [ ! -f './docker/Dockerfile.template' ]; then
echo "This script requires ./docker/Dockerfile.template file to setup docker."
exit 1
fi
echo "Creating Dockerfile file..."
cp ./docker/Dockerfile.template ./Dockerfile
# Replace some lines in existing Dockerfile.
# Set sed -i option to '' to prevent it from creating backup files
# Replace node version set value
sed -i '' -e "s|^FROM node:\([0-9\.]*\).*|FROM node:$NODE_VERSION|" \
Dockerfile
# Replace hugo version with set value
sed -i '' -e "s|^ARG HUGO_VERSION=\([0-9\.]*\).*|ARG HUGO_VERSION=$HUGO_VERSION|" \
Dockerfile
# Replace app home directory with set value
sed -i '' -e "s|\$HOME/[a-zA-Z0-9]*/$|\$HOME/$APP_NAME/|g" \
Dockerfile
echo "Dockerfile successfully created."
}
setup_docker() {
# Check if docker is installed on the machine
if ! docker version > /dev/null; then
echo "Please docker-engine and docker-compose are required to be installed on the host machine"
echo "https://docs.docker.com/engine/installation/"
echo "https://docs.docker.com/compose/"
exit 1
fi
create_docker_file
}
setup_docker_compose() {
# Check to make sure docker-compose template file exist
if [ ! -f './docker/docker-compose.yaml.template' ]; then
echo "This script requires ./docker/docker-compose.yaml.template file to setup docker-compose."
exit 1
fi
echo "Creating docker-compose.yaml file..."
cp ./docker/docker-compose.yaml.template ./docker-compose.yaml
echo "docker-compose.yaml successfully created."
sed -i '' -e "s/app:/${APP_NAME}:/" \
docker-compose.yaml
sed -i '' -e "s/app/$APP_NAME/g" \
docker-compose.yaml
if [[ "$DETACHED" != "" ]]; then
docker-compose up --build "$DETACHED" "$APP_NAME"
else
docker-compose up --build "$APP_NAME"
fi
}
#######################
# Main function #
#######################
if [[ $# -gt 0 ]]; then
cmdline "${ARGS[@]}"
fi
check_where_cmd_is_run
setup_docker
setup_docker_compose
================================================
FILE: scripts/create-hugo-site
================================================
#!/bin/sh
#
# Creates pre-requiste hugo site
set -eu
readonly PROGNAME=$(basename "$0")
readonly ARGS="$@"
APP_NAME="app"
usage() {
cat <<- EOF
Usage: ./scripts/$PROGNAME optional options
Creates folders needed to run hulgulp if they do not exist
OPTIONS:
-a --app-name the name of the app. It defaults to app
-h --help show this help
Example:
Run with a hugo website name set to website
./scripts/$PROGNAME -a website
EOF
}
cmdline() {
local arg=
local args=
for arg; do
local delim=""
case "$arg" in
# Copied from: http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/
# Translate --machine-name to -m (short options)
--app-name) args="${args}-a ";;
--help) args="${args}-h ";;
#pass through anything else
*) [[ "${arg:0:1}" == "-" ]] || delim="\""
args="${args}${delim}${arg}${delim} ";;
esac
done
OPTIND=1
while getopts "ha:" OPTION; do
case "$OPTION" in
h)
usage
exit 0
;;
a)
APP_NAME=$OPTARG
;;
esac
done
shift "$((OPTIND-1))" # Shift off the options and optional --.
return 0
}
create_hugo_site() {
if [ ! -d "$APP_NAME" ]; then
hugo new site "$APP_NAME"
fi
}
create_assets_folders() {
if [ ! -d "${APP_NAME}/assets" ]; then
mkdir -p "${APP_NAME}"/assets/img
mkdir -p "${APP_NAME}"/assets/styles
mkdir -p "${APP_NAME}"/assets/scripts
fi
}
#######################
# Main function #
#######################
if [[ $# -gt 0 ]]; then
cmdline "$@"
fi
create_hugo_site
create_assets_folders
================================================
FILE: scripts/rel-push-prog
================================================
#!/usr/bin/env bash
function error {
echo -e "$1" >&2
exit 1
}
PROG="hugulp"
VERSION=`cat VERSION 2> /dev/null`
git checkout rel/$VERSION
# This sections deals with pushing the current tag
# to the $PROG github repo
REMOTE=`git remote get-url github 2> /dev/null`
if [[ -z "$REMOTE" ]]; then
git remote add github gitjbr:jbrodriguez/$PROG.git
else
git remote set-url github gitjbr:jbrodriguez/$PROG.git
fi
# TAG=`git describe --abbrev=0 --tags 2> /dev/null`
# if [[ -z "$TAG" ]]; then
# error "Unable to retrieve latest tag"
# fi
BRANCH=$(git rev-parse --abbrev-ref HEAD 2> /dev/null)
if [[ -z $BRANCH ]]; then
error "Unable to obtain branch name. Please check and try again."
fi
git push --tags github $BRANCH
if [ $? -ne 0 ]; then
error "Unable to push branch ${BRANCH} to github"
fi
DESCRIPTION=`cat metadata/changes/$VERSION.txt 2> /dev/null`
github-release --verbose release \
--user jbrodriguez \
--repo "$PROG" \
--tag "$VERSION" \
--name "$VERSION" \
--description "$DESCRIPTION" \