From a5fc5b030ecfbb068c3ac8646f68c6ec20df6bdf Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 22 Jan 2018 16:11:05 -0500 Subject: [PATCH] Bring back deprecated stylus package in order to fix a caching bug. This code was recently removed in PR #9445, with this commit: d644705aa8a2477c872e8070517aa6ee02386af4 Rather than removing deprecated code entirely from the codebase, I think it's sufficient to keep it in packages/deprecated, and print a deprecation notice whenever the package is used. This way it's clear that developers should migrate to other similar packages, but we can still release important patches for those who haven't been able to migrate yet. cc @hwillson @abernix --- .../.npm/plugin/compileStylusBatch/.gitignore | 1 + .../.npm/plugin/compileStylusBatch/README | 7 + .../compileStylusBatch/npm-shrinkwrap.json | 176 ++++++++++++++++ packages/deprecated/stylus/.versions | 35 ++++ packages/deprecated/stylus/package.js | 30 ++- .../stylus/plugin/compile-stylus.js | 198 ++++++++++++++++++ packages/deprecated/stylus/stylus_tests.html | 8 + .../stylus/stylus_tests.import.styl | 5 + packages/deprecated/stylus/stylus_tests.js | 27 +++ packages/deprecated/stylus/stylus_tests.styl | 16 ++ 10 files changed, 500 insertions(+), 3 deletions(-) create mode 100644 packages/deprecated/stylus/.npm/plugin/compileStylusBatch/.gitignore create mode 100644 packages/deprecated/stylus/.npm/plugin/compileStylusBatch/README create mode 100644 packages/deprecated/stylus/.npm/plugin/compileStylusBatch/npm-shrinkwrap.json create mode 100644 packages/deprecated/stylus/.versions create mode 100644 packages/deprecated/stylus/plugin/compile-stylus.js create mode 100644 packages/deprecated/stylus/stylus_tests.html create mode 100644 packages/deprecated/stylus/stylus_tests.import.styl create mode 100644 packages/deprecated/stylus/stylus_tests.js create mode 100644 packages/deprecated/stylus/stylus_tests.styl diff --git a/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/.gitignore b/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/.gitignore new file mode 100644 index 0000000000..3c3629e647 --- /dev/null +++ b/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/README b/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/README new file mode 100644 index 0000000000..3d492553a4 --- /dev/null +++ b/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/README @@ -0,0 +1,7 @@ +This directory and the files immediately inside it are automatically generated +when you change this package's NPM dependencies. Commit the files in this +directory (npm-shrinkwrap.json, .gitignore, and this README) to source control +so that others run the same versions of sub-dependencies. + +You should NOT check in the node_modules directory that Meteor automatically +creates; if you are using git, the .gitignore file tells git to ignore it. diff --git a/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/npm-shrinkwrap.json b/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/npm-shrinkwrap.json new file mode 100644 index 0000000000..91eda21624 --- /dev/null +++ b/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/npm-shrinkwrap.json @@ -0,0 +1,176 @@ +{ + "lockfileVersion": 1, + "dependencies": { + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "autoprefixer": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.3.7.tgz", + "integrity": "sha1-jt8xZt2f1hFlM2Ysi7NqA8DvyHQ=" + }, + "autoprefixer-stylus": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/autoprefixer-stylus/-/autoprefixer-stylus-0.9.4.tgz", + "integrity": "sha1-dgkUaV3OMhyZgLSQ2BpDhcCNkU0=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=" + }, + "browserslist": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.3.6.tgz", + "integrity": "sha1-lS/0jVZGPTtTj4XvL46t39KEsTM=" + }, + "caniuse-db": { + "version": "1.0.30000793", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000793.tgz", + "integrity": "sha1-PADGbkI6ehkHx92Wdpp4sq+opy4=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "css-parse": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", + "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=" + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "js-base64": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.1.tgz", + "integrity": "sha512-2h586r2I/CqU7z1aa1kBgWaVAXWAZK+zHnceGi/jFgn7+7VSluxYer/i3xOZVearCxxXvyDkLtTBo+OeJCA3kA==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==" + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multi-stage-sourcemap": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/multi-stage-sourcemap/-/multi-stage-sourcemap-0.2.1.tgz", + "integrity": "sha1-sJ/IWG6qF/gdV1xK0C4Pej9rEQU=" + }, + "nib": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/nib/-/nib-1.1.2.tgz", + "integrity": "sha1-amnt5AgblcDe+L4CSkyK4MLLtsc=" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "postcss": { + "version": "5.0.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.0.21.tgz", + "integrity": "sha1-1M9vGXdGSMSSrFfCmPavs8BMrv4=", + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=" + }, + "sax": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=" + }, + "stylus": { + "version": "https://github.com/meteor/stylus/tarball/bb47a357d132ca843718c63998eb37b90013a449", + "integrity": "sha512-j6fvtoNfjx/TEIlIOZ53OqbP6uDdF5HsQidsRfvp0IfW0D5PCtV8IeHVQa4jjbhF9PbjOXX/rrt5lP4CGpgtfw==" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } +} diff --git a/packages/deprecated/stylus/.versions b/packages/deprecated/stylus/.versions new file mode 100644 index 0000000000..14f3908784 --- /dev/null +++ b/packages/deprecated/stylus/.versions @@ -0,0 +1,35 @@ +babel-compiler@5.8.24_1 +babel-runtime@0.1.4 +base64@1.0.9 +binary-heap@1.0.9 +blaze@1.0.3 +caching-compiler@1.0.0 +callback-hook@1.0.9 +check@1.0.6 +ddp@1.1.0 +deps@1.0.12 +ecmascript@0.1.4 +ecmascript-collections@0.1.6 +ejson@1.0.12 +geojson-utils@1.0.4 +htmljs@1.0.11 +id-map@1.0.8 +jquery@1.0.2 +json@1.0.3 +local-test:stylus@2.513.5 +logging@1.0.12 +meteor@1.1.16 +minimongo@1.0.8 +mongo@1.1.0 +observe-sequence@1.0.6 +ordered-dict@1.0.8 +promise@0.4.8 +random@1.0.4 +retry@1.0.4 +stylus@2.513.5 +templating@1.0.4 +test-helpers@1.0.3 +tinytest@1.0.5 +tracker@1.0.15 +ui@1.0.0 +underscore@1.0.9 diff --git a/packages/deprecated/stylus/package.js b/packages/deprecated/stylus/package.js index dbd30525c8..ecad05868e 100644 --- a/packages/deprecated/stylus/package.js +++ b/packages/deprecated/stylus/package.js @@ -1,8 +1,32 @@ Package.describe({ - summary: 'DEPRECATED - Expressive, dynamic, robust CSS', - version: "2.999.0" + summary: 'Expressive, dynamic, robust CSS', + version: "2.513.13" +}); + +Package.registerBuildPlugin({ + name: 'compileStylusBatch', + use: ['ecmascript', 'caching-compiler'], + sources: [ + 'plugin/compile-stylus.js' + ], + npmDependencies: { + stylus: "https://github.com/meteor/stylus/tarball/bb47a357d132ca843718c63998eb37b90013a449", // fork of 0.54.5 + nib: "1.1.2", + "autoprefixer-stylus": "0.9.4" + } }); Package.onUse(function (api) { - api.addFiles('deprecation_notice.js'); + api.use('isobuild:compiler-plugin@1.0.0'); + api.addFiles("deprecation_notice.js"); +}); + +Package.onTest(function (api) { + api.use(['tinytest', 'stylus', 'test-helpers', 'templating']); + api.addFiles([ + 'stylus_tests.html', + 'stylus_tests.styl', + 'stylus_tests.import.styl', + 'stylus_tests.js' + ],'client'); }); diff --git a/packages/deprecated/stylus/plugin/compile-stylus.js b/packages/deprecated/stylus/plugin/compile-stylus.js new file mode 100644 index 0000000000..21de2eda24 --- /dev/null +++ b/packages/deprecated/stylus/plugin/compile-stylus.js @@ -0,0 +1,198 @@ +const stylus = Npm.require('stylus'); +const nib = Npm.require('nib'); +const autoprefixer = Npm.require('autoprefixer-stylus'); +const Future = Npm.require('fibers/future'); +const fs = Plugin.fs; +const path = Plugin.path; + +Plugin.registerCompiler({ + extensions: ['styl'], + archMatching: 'web' +}, () => new StylusCompiler()); + +// CompileResult is {css, sourceMap}. +class StylusCompiler extends MultiFileCachingCompiler { + constructor() { + super({ + compilerName: 'stylus', + defaultCacheSize: 1024*1024*10, + }); + } + + getCacheKey(inputFile) { + return [ + inputFile.getSourceHash(), + inputFile.getFileOptions(), + ]; + } + + compileResultSize(compileResult) { + return compileResult.css.length + + this.sourceMapSize(compileResult.sourceMap); + } + + // The heuristic is that a file is an import (ie, is not itself + // processed as a root) if it matches *.import.styl. This can be + // overridden in either direction via an explicit `isImport` file option + // in api.addFiles. + isRoot(inputFile) { + const fileOptions = inputFile.getFileOptions(); + if (fileOptions.hasOwnProperty('isImport')) { + return !fileOptions.isImport; + } + + const pathInPackage = inputFile.getPathInPackage(); + return ! /\.import\.styl$/.test(pathInPackage); + } + + compileOneFile(inputFile, allFiles) { + const referencedImportPaths = []; + + function parseImportPath(filePath, importerDir) { + if (! filePath) { + throw new Error('filePath is undefined'); + } + if (filePath === inputFile.getPathInPackage()) { + return { + packageName: inputFile.getPackageName() || '', + pathInPackage: inputFile.getPathInPackage() + }; + } + if (! filePath.match(/^\{.*\}\//)) { + if (! importerDir) { + return { packageName: inputFile.getPackageName() || '', + pathInPackage: filePath }; + } + + // relative path in the same package + const parsedImporter = parseImportPath(importerDir, null); + + // resolve path if it is absolute or relative + const importPath = + (filePath[0] === '/') ? filePath : + path.join(parsedImporter.pathInPackage, filePath); + + return { + packageName: parsedImporter.packageName, + pathInPackage: importPath + }; + } + + const match = /^\{(.*)\}\/(.*)$/.exec(filePath); + if (! match) { return null; } + + const [ignored, packageName, pathInPackage] = match; + return {packageName, pathInPackage}; + } + function absoluteImportPath(parsed) { + return '{' + parsed.packageName + '}/' + parsed.pathInPackage; + } + + const importer = { + find(importPath, paths) { + const parsed = parseImportPath(importPath, paths[paths.length - 1]); + if (! parsed) { return null; } + + if (importPath[0] !== '{') { + // if it is not a custom syntax path, it could be a lookup in a folder + for (let i = paths.length - 1; i >= 0; i--) { + const joined = path.join(paths[i], importPath); + if (statOrNull(joined)) { + return [joined]; + } + } + } + + const absolutePath = absoluteImportPath(parsed); + + if (! allFiles.has(absolutePath)) { + return null; + } + + return [absolutePath]; + }, + readFile(filePath) { + const isAbsolute = filePath[0] === '/'; + const isNib = + filePath.indexOf('/node_modules/nib/lib/nib/') !== -1; + const isStylusBuiltIn = + filePath.indexOf('/node_modules/stylus/lib/') !== -1; + + if (isAbsolute || isNib || isStylusBuiltIn) { + // absolute path? let the default implementation handle this + return fs.readFileSync(filePath, 'utf8'); + } + + const parsed = parseImportPath(filePath); + const absolutePath = absoluteImportPath(parsed); + + referencedImportPaths.push(absolutePath); + + if (! allFiles.has(absolutePath)) { + throw new Error( + `Cannot read file ${absolutePath} for ${inputFile.getDisplayPath()}` + ); + } + + return allFiles.get(absolutePath).getContentsAsString(); + } + }; + + function processSourcemap(sourcemap) { + delete sourcemap.file; + sourcemap.sourcesContent = sourcemap.sources.map(importer.readFile); + sourcemap.sources = sourcemap.sources.map((filePath) => { + const parsed = parseImportPath(filePath); + if (!parsed.packageName) + return parsed.pathInPackage; + return 'packages/' + parsed.packageName + '/' + parsed.pathInPackage; + }); + + return sourcemap; + } + + const fileOptions = inputFile.getFileOptions(); + + const f = new Future; + + let style = stylus(inputFile.getContentsAsString()).use(nib()) + + if (fileOptions.autoprefixer) { + style = style.use(autoprefixer(fileOptions.autoprefixer)) + } + + style = style.set('filename', inputFile.getPathInPackage()) + .set('sourcemap', { inline: false, comment: false }) + .set('cache', false) + .set('importer', importer); + + style.render(f.resolver()); + let css; + try { + css = f.wait(); + } catch (e) { + inputFile.error({ + message: 'Stylus compiler error: ' + e.message + }); + return null; + } + const sourceMap = processSourcemap(style.sourcemap); + return {referencedImportPaths, compileResult: {css, sourceMap}}; + } + + addCompileResult(inputFile, {css, sourceMap}) { + inputFile.addStylesheet({ + path: inputFile.getPathInPackage() + '.css', + data: css, + sourceMap: sourceMap + }); + } +} + +function statOrNull(path) { + try { + return fs.statSync(path); + } catch (e) { + return null; + } +} diff --git a/packages/deprecated/stylus/stylus_tests.html b/packages/deprecated/stylus/stylus_tests.html new file mode 100644 index 0000000000..e845cc341b --- /dev/null +++ b/packages/deprecated/stylus/stylus_tests.html @@ -0,0 +1,8 @@ + + + + diff --git a/packages/deprecated/stylus/stylus_tests.import.styl b/packages/deprecated/stylus/stylus_tests.import.styl new file mode 100644 index 0000000000..d5e4779860 --- /dev/null +++ b/packages/deprecated/stylus/stylus_tests.import.styl @@ -0,0 +1,5 @@ +// Variable used in stylus_test.styl +importDashy = dashed + +.stylus-overwrite-color + font-size: 20px !important diff --git a/packages/deprecated/stylus/stylus_tests.js b/packages/deprecated/stylus/stylus_tests.js new file mode 100644 index 0000000000..33af39cca0 --- /dev/null +++ b/packages/deprecated/stylus/stylus_tests.js @@ -0,0 +1,27 @@ + +Tinytest.add("stylus - presence", function(test) { + + var div = document.createElement('div'); + Blaze.render(Template.stylus_test_presence, div); + div.style.display = 'block'; + document.body.appendChild(div); + + var p = div.querySelector('p'); + var leftBorder = getStyleProperty(p, 'border-left-style'); + test.equal(leftBorder, "dashed"); + + document.body.removeChild(div); +}); + +Tinytest.add("stylus - @import", function(test) { + var div = document.createElement('div'); + Blaze.render(Template.stylus_test_import, div); + div.style.display = 'block'; + document.body.appendChild(div); + + var p = div.querySelector('p'); + test.equal(getStyleProperty(p, 'font-size'), "20px"); + test.equal(getStyleProperty(p, 'border-left-style'), "dashed"); + + document.body.removeChild(div); +}); diff --git a/packages/deprecated/stylus/stylus_tests.styl b/packages/deprecated/stylus/stylus_tests.styl new file mode 100644 index 0000000000..46687d5ae2 --- /dev/null +++ b/packages/deprecated/stylus/stylus_tests.styl @@ -0,0 +1,16 @@ +@import "stylus_tests.import.styl" + +#stylus-tests + zoom: 1 + +dashy = dashed + +.stylus-dashy-left-border + border-left: 1px dashy black + +.stylus-overwrite-size + // This property is overwritten in stylus_test.import.styl + font-size: 10px + +.stylus-import-dashy-border + border-left: 1px importDashy black