Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Commit

Permalink
Use the provided less sources instead of reading them from disk
Browse files Browse the repository at this point in the history
  • Loading branch information
Antonio Scandurra committed Mar 9, 2017
1 parent cf87c73 commit 52fb96f
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 9 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"grunt-contrib-coffee": "^1.0.0",
"grunt-shell": "^1.3.0",
"jasmine-focused": "1.x",
"temp": "^0.8.3",
"tmp": "0.0.28"
}
}
65 changes: 65 additions & 0 deletions spec/less-cache-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ fs = require 'fs'
{dirname, join} = require 'path'

tmp = require 'tmp'
temp = require('temp').track()
fstream = require 'fstream'

LessCache = require '../src/less-cache'
Expand Down Expand Up @@ -294,3 +295,67 @@ describe "LessCache", ->

expect(cache.stats.hits).toBe 1
expect(cache.stats.misses).toBe 0

describe "when providing a resource path and less sources by relative file path", ->
it "reads from the provided sources first, and falls back to reading from disk if a valid source isn't available", ->
cacheDir = temp.mkdirSync()
cache1 = new LessCache
cacheDir: cacheDir
importPaths: [join(fixturesDir, 'imports-1'), join(fixturesDir, 'imports-2')]
resourcePath: fixturesDir
lessSourcesByRelativeFilePath: {
'imports.less': """
@import "a";
@import "b";
@import "c";
@import "d";
some-selector {
prop-1: @a;
prop-2: @b;
prop-3: @c;
prop-4: @d;
}
"""
}

expect(cache1.readFileSync(join(fixturesDir, 'imports.less'))).toBe("""
some-selector {
prop-1: 1;
prop-2: 2;
prop-3: 3;
prop-4: 4;
}\n
""")

cache2 = new LessCache
cacheDir: cacheDir
importPaths: [join(fixturesDir, 'imports-1'), join(fixturesDir, 'imports-2')]
resourcePath: fixturesDir
lessSourcesByRelativeFilePath: {
'imports.less': """
@import "a";
@import "b";
@import "c";
@import "d";
some-selector {
prop-1: @a;
prop-2: @b;
prop-3: @c;
prop-4: @d;
}
""",
'imports-1/c.less': """
@c: "changed";
"""
}

expect(cache2.readFileSync(join(fixturesDir, 'imports.less'))).toBe("""
some-selector {
prop-1: 1;
prop-2: 2;
prop-3: "changed";
prop-4: 4;
}\n
""")
32 changes: 23 additions & 9 deletions src/less-cache.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class LessCache
#
# * fallbackDir: A string path to a directory containing a readable cache to read
# from an entry is not found in this cache (optional)
constructor: ({@cacheDir, @importPaths, @resourcePath, @fallbackDir, @syncCaches}={}) ->
constructor: ({@cacheDir, @importPaths, @resourcePath, @fallbackDir, @syncCaches, @lessSourcesByRelativeFilePath}={}) ->
@lessSourcesByRelativeFilePath ?= {}
@importsCacheDir = @cacheDirectoryForImports(@importPaths)
if @fallbackDir
@importsFallbackDir = join(@fallbackDir, basename(@importsCacheDir))
Expand Down Expand Up @@ -88,9 +89,9 @@ class LessCache
lessFs ?= require 'less/lib/less-node/fs.js'
originalFsReadFileSync = lessFs.readFileSync
lessFs.readFileSync = (filePath, args...) =>
content = originalFsReadFileSync(filePath, args...)
filePath = @relativize(@resourcePath, filePath) if @resourcePath
importedPaths.push({path: filePath, digest: @digestForContent(content)})
relativeFilePath = @relativize(@resourcePath, filePath) if @resourcePath
content = @lessSourcesByRelativeFilePath[relativeFilePath] ? originalFsReadFileSync(filePath, args...)
importedPaths.push({path: relativeFilePath ? filePath, digest: @digestForContent(content)})
content

try
Expand All @@ -104,8 +105,17 @@ class LessCache

writeJson: (filePath, object) -> fs.writeFileSync(filePath, JSON.stringify(object))

digestForPath: (filePath) ->
@digestForContent(fs.readFileSync(filePath))
digestForPath: (relativeFilePath) ->
lessSource = @lessSourcesByRelativeFilePath[relativeFilePath]
unless lessSource?
absoluteFilePath = null
if @resourcePath and not fs.isAbsolute(relativeFilePath)
absoluteFilePath = join(@resourcePath, relativeFilePath)
else
absoluteFilePath = relativeFilePath
lessSource = fs.readFileSync(absoluteFilePath)

@digestForContent(lessSource)

digestForContent: (content) ->
crypto.createHash('SHA1').update(content, 'utf8').digest('hex')
Expand Down Expand Up @@ -137,7 +147,6 @@ class LessCache

for {path, digest} in cacheEntry.imports
try
path = join(@resourcePath, path) if @resourcePath and not fs.isAbsolute(path)
return if @digestForPath(path) isnt digest
catch error
return
Expand Down Expand Up @@ -176,8 +185,13 @@ class LessCache
# filePath: A string path to a Less file.
#
# Returns the compiled CSS for the given path.
readFileSync: (filePath) ->
@cssForFile(filePath, fs.readFileSync(filePath, 'utf8'))
readFileSync: (absoluteFilePath) ->
fileContents = null
if @resourcePath and fs.isAbsolute(absoluteFilePath)
relativeFilePath = @relativize(@resourcePath, absoluteFilePath)
fileContents = @lessSourcesByRelativeFilePath[relativeFilePath]

@cssForFile(absoluteFilePath, fileContents ? fs.readFileSync(absoluteFilePath, 'utf8'))

# Return either cached CSS or the newly
# compiled CSS from `lessContent`. This method caches the compiled CSS after it is generated. This cached
Expand Down

0 comments on commit 52fb96f

Please sign in to comment.