UNPKG

patternpack

Version:

Build and Document Your Interface. Then Share the Code.

372 lines (331 loc) 9.64 kB
module.exports = function (grunt) { "use strict"; var _ = require("lodash"); var log = require("./gruntLogHelper.js")(grunt); var gruntfilePath = grunt.option("gruntfile") || "."; var basePath = require("path").dirname(gruntfilePath); var autoprefixer = require("autoprefixer"); var gruntFileConfig = basePath + "/gruntfileConfig.json"; var config = grunt.file.readJSON(gruntFileConfig); function root(path) { return getPath(config.root, path); } function integrate(path) { return getPath(config.integrate, path) } function release(path) { return getPath(config.release, path); } function build(path) { return getPath(config.build, path); } function src(path) { return getPath(config.src, path); } function assets(path) { return getPath(config.assets, path); } function theme(path) { return getPath(config.theme, path); } function data(path) { return getPath(config.data, path); } function getPath(configPath, path) { path = path || ""; return configPath + path; } // return an array of paths with the src prepended // this should return the array in the same order it was configured // this is important because the styles may need to be processed in a // specific order for css cascading needs. function allPatternStructurePaths(path) { return _.map(config.patternStructure, function (structure) { return getPath(config.src + "/" + structure.path, path); }); } function getBuildTasks(tasksConfig) { var buildTasks = ["clean:build", "build-styles"]; var patternsTasks = ["build-patterns"]; var patternLibraryTasks = ["build-site"]; if (tasksConfig.library) { buildTasks = buildTasks.concat(patternLibraryTasks); } if (tasksConfig.patterns) { buildTasks = buildTasks.concat(patternsTasks); } log.verbose("PatternPack Grunt Tasks:"); log.verbose(buildTasks); return buildTasks; } function getStyleTasks(cssPreprocessorConfig) { var sassTasks = ["sass_globbing:sass", "sass"]; var lessTasks = ["sass_globbing:less", "less"]; var cssTasks = ["postcss", "copy:css"]; var tasks = []; if (cssPreprocessorConfig === "sass") { tasks = tasks.concat(sassTasks); } else if (cssPreprocessorConfig === "less") { tasks = tasks.concat(lessTasks); } tasks = tasks.concat(cssTasks); log.verbose("PatternPack CSS Preprocessor Tasks:"); log.verbose(tasks); return tasks; } grunt.initConfig({ pkg: grunt.file.readJSON("package.json"), gitadd: { task: { options: { all: true } } }, bump: { options: { files: [ root("/bower.json"), root("/package.json") ], updateConfigs: ["pkg"], commitFiles: ["-a"], push: false } }, // Concurent tasks concurrent: { build: ["styles", "assemble"] }, // Build HTML with Assemble.io assemble: { options: { patternStructure: config.patternStructure, helpers: [theme("/assemble-helpers/*.js"), "assemble-helpers/assemble-helper-*.js"], partials: theme("/partials/*.hbs"), postprocess: require("pretty"), data: data("/**/*.{json,yml}") }, // Build the pattern library (fully functioning website) patternlibrary: { options: { assets: build("/pattern-library/assets"), layout: theme("/layouts/_pattern-library.hbs") }, files: [ { expand: true, cwd: src(), src: ["**/*.{md,hbs}", "!_pattern-library/**"], dest: build("/pattern-library/") } ] }, // Bulid the patterns as raw html only (designed to be embedded in another website) patterns: { files: [ { expand: true, cwd: src(), src: ["**/*.{md,hbs}", "!_pattern-library/**"], dest: build("/patterns/") } ] } }, // Remove existing build artifacts clean: { options: { force: true }, build: build(), release: release() }, // Copy the artifacts for release copy: { release: { expand: true, cwd: build(), src: [ "**" ], dest: release() }, integrate: { expand: true, cwd: build(), src: [ "**", "!pattern-library/theme-assets/**" ], dest: integrate() }, css: { expand: true, cwd: assets(), src: [ "css/**" ], dest: build("/pattern-library/assets") }, assets: { expand: true, cwd: assets(), src: [ "**", "!sass/**" ], dest: build("/pattern-library/assets") }, themeAssets: { expand: true, cwd: theme(), src: [ "theme-assets/**" ], dest: build("/pattern-library") } }, // Build styles sass: { options: { sourceMap: true, sourceMapContents: true, outputStyle: "compressed" }, patterns: { files: [ { src: assets("/sass/" + config.css.fileName + ".scss"), dest: assets("/css/" + config.css.fileName + ".css") } ] } }, less: { options: { sourceMap: true, outputSourceFiles: true, compress: true }, patterns: { files: [ { src: assets("/less/" + config.css.fileName + ".less"), dest: assets("/css/" + config.css.fileName + ".css") } ] } }, // Import all sass styles defined for patterns // Use the pattern structures to ensure that the styles are processed // in the specific order the user configures. "sass_globbing": { sass: { src: allPatternStructurePaths("/**/*.scss"), dest: assets("/sass/_patternpack-patterns.scss") }, less: { src: allPatternStructurePaths("/**/*.less"), dest: assets("/less/_patternpack-patterns.less") } }, // Run PostCSS Autoprefixer on any CSS in the assets directory // Using the configured Autoprefixer options (defaults to last 2 versions) postcss: { options: { map: true, processors: [ autoprefixer( config.css.autoprefixer ) ] }, build: { src: assets("/css/*.css") } }, // Run tasks when files change watch: { assemble: { files: [ theme("/**/*.{md,hbs}"), src("/**/*.{md,hbs}") ], tasks: ["build-site"] }, sass: { files: src("/**/*.scss"), tasks: ["build-styles", "copy:css"] }, less: { files: src("/**/*.less"), tasks: ["build-styles", "copy:css"] }, livereload: { files: build("/pattern-library/**"), options: { livereload: true } } }, // Web server connect: { options: { base: build("/pattern-library"), hostname: "*" }, server: { options: config.server } }, eslint: { target: [ "**/*.js", "!node_modules/**" ] } }); var loadTaskConfig = { // The globbing pattern used to locate the desired grunt tasks pattern: [ "grunt-*", "assemble" ], // The list of dependencies to include // ["dependencies", "optionalDependencies"] scope: ["dependencies"] }; // If the root configuration exists it indicates that patternpack is // running from the context of another grunt process. In this case // we should use load-grunt-parent-tasks to ensure the npm packages // are loaded correctly. Otherwise, just load the tasks like normal. if (config.root) { // Load the tasks using the load-grunt-parent-tasks module. // This allows the grunt tasks to still be loaded when the // calling pattern library happens to contain one of the // dependencies used by pattern pack. For more info: // https://www.npmjs.com/package/load-grunt-parent-tasks log.verbose("load parent tasks"); require("load-grunt-parent-tasks")(grunt, loadTaskConfig); } else { log.verbose("load tasks"); require("load-grunt-tasks")(grunt, loadTaskConfig); } // Modular tasks // These smaller grunt tasks organize work into logical groups // and are typically composed together into workflows grunt.registerTask("build-styles", getStyleTasks(config.css.preprocessor)); grunt.registerTask("build-patterns", ["assemble:patterns"]); grunt.registerTask("build-pages", ["assemble:patternlibrary"]); grunt.registerTask("build-site", ["build-pages", "copy:assets", "copy:themeAssets"]); grunt.registerTask("server", ["connect", "watch"]); grunt.registerTask("release-patch", ["build", "clean:release", "copy:release", "gitadd", "bump:patch"]); grunt.registerTask("release-minor", ["build", "clean:release", "copy:release", "gitadd", "bump:minor"]); grunt.registerTask("release-major", ["build", "clean:release", "copy:release", "gitadd", "bump:major"]); // Main tasks grunt.registerTask("integrate", ["build", "copy:integrate"]); grunt.registerTask("release", ["release-patch"]); grunt.registerTask("build", getBuildTasks(config.publish)); grunt.registerTask("default", ["build", "server"]); };