guard-less 0.0.4 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +48 -5
- data/lib/guard/less.rb +108 -20
- data/lib/guard/less/templates/Guardfile +2 -2
- data/lib/guard/less/version.rb +1 -1
- metadata +62 -5
data/README.md
CHANGED
@@ -21,16 +21,59 @@ Please read [Guard usage doc](https://github.com/guard/guard#readme).
|
|
21
21
|
|
22
22
|
## Guardfile
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
```ruby
|
25
|
+
guard 'less', :all_on_start => true, :all_after_change => true do
|
26
|
+
watch(%r{^.*\.less$})
|
27
|
+
end
|
28
|
+
```
|
27
29
|
|
28
30
|
Please read [Guard doc](https://github.com/guard/guard#readme) for more info about Guardfile DSL.
|
29
31
|
|
30
32
|
## Options
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
+
```ruby
|
35
|
+
:all_after_change => [true|false] # run on all files after any changed files
|
36
|
+
# default: true
|
37
|
+
|
38
|
+
:all_on_start => [true|false] # run on all the files at startup
|
39
|
+
# default: true
|
40
|
+
|
41
|
+
:output => 'relative/path' # base directory for output CSS files; if unset,
|
42
|
+
# .css files are generated in the same directories
|
43
|
+
# as their corresponding .less file
|
44
|
+
# default: nil
|
45
|
+
|
46
|
+
:import_paths => ['lib/styles'] # an array of additional load paths to pass to the
|
47
|
+
# LESS parser, used when resolving `@import`
|
48
|
+
# statements
|
49
|
+
# default: [] (see below)
|
50
|
+
```
|
51
|
+
|
52
|
+
### Output option
|
53
|
+
|
54
|
+
By default, `.css` files will be generated in the same directories as their
|
55
|
+
corresponding `.less` files (partials beginning with `_` are always excluded).
|
56
|
+
To customize the output location, pass the `:output` option as described above,
|
57
|
+
and be sure to use a match group in the regular expression in your watch to
|
58
|
+
capture nested structure that will be preserved, i.e.
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
guard 'less', :output => 'public/stylesheets' do
|
62
|
+
watch(%r{^app/stylesheets/(.+\.less)$})
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
will result in `app/stylesheets/forums/main.less` producing CSS at
|
67
|
+
`public/stylesheets/forums/main.css`.
|
68
|
+
|
69
|
+
### Import paths option
|
70
|
+
|
71
|
+
As each `.less` file is parsed, the directory containing the file is
|
72
|
+
automatically prepended to the import paths, so imports relative to your watched
|
73
|
+
dirs like `@import 'shared/_type-styles'` should always work. You can supply
|
74
|
+
additional paths with this option so that, for the `['lib/styles']` example, a
|
75
|
+
file at `lib/styles/reset.less` could be imported without a qualified path as
|
76
|
+
`@import 'reset'`.
|
34
77
|
|
35
78
|
# License
|
36
79
|
|
data/lib/guard/less.rb
CHANGED
@@ -11,44 +11,132 @@ module Guard
|
|
11
11
|
# = Guard method =
|
12
12
|
# ================
|
13
13
|
def initialize(watchers=[], options={})
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
defaults = {
|
15
|
+
:all_after_change => true,
|
16
|
+
:all_on_start => true,
|
17
|
+
:output => nil,
|
18
|
+
:import_paths => []
|
19
|
+
}
|
20
|
+
|
21
|
+
super(watchers, defaults.merge(options))
|
17
22
|
end
|
18
23
|
|
19
24
|
def start
|
20
25
|
UI.info "Guard::Less #{LessVersion::VERSION} is on the job!"
|
21
|
-
run_all
|
26
|
+
run_all if options[:all_on_start]
|
22
27
|
end
|
23
28
|
|
24
29
|
# Call with Ctrl-/ signal
|
25
30
|
# This method should be principally used for long action like running all specs/tests/...
|
26
31
|
def run_all
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
UI.info "Guard::Less: compiling all files"
|
33
|
+
patterns = watchers.map { |w| w.pattern }
|
34
|
+
files = Dir.glob('**/*.*')
|
35
|
+
paths = []
|
36
|
+
files.each do |file|
|
37
|
+
patterns.each do |pattern|
|
38
|
+
paths << file if file.match(Regexp.new(pattern))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
run(paths)
|
36
42
|
end
|
37
43
|
|
38
44
|
# Call on file(s) modifications
|
39
45
|
def run_on_change(paths)
|
40
|
-
run_all
|
46
|
+
options[:all_after_change] ? run_all : run(paths)
|
41
47
|
end
|
42
48
|
|
43
49
|
def run(paths)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
50
|
+
directories = nested_directory_map(paths)
|
51
|
+
|
52
|
+
directories.each do |destination, stylesheets|
|
53
|
+
stylesheets.each do |lessfile|
|
54
|
+
# Skip partials
|
55
|
+
basename = File.basename(lessfile)
|
56
|
+
next if basename[0,1] == "_"
|
57
|
+
|
58
|
+
cssfile = File.join(destination, basename.gsub(/\.less$/, '.css'))
|
59
|
+
|
60
|
+
# Just in case
|
61
|
+
if cssfile == lessfile
|
62
|
+
UI.info "Guard::Less: Skipping #{lessfile} since the output would overwrite the original file"
|
63
|
+
elsif mtime(cssfile) >= mtime_including_imports(lessfile)
|
64
|
+
UI.info "Guard::Less: Skipping #{lessfile} because #{cssfile} is already up-to-date"
|
65
|
+
else
|
66
|
+
UI.info "Guard::Less: #{lessfile} -> #{cssfile}\n"
|
67
|
+
FileUtils.mkdir_p(File.expand_path(destination))
|
68
|
+
compile(lessfile, cssfile)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# Parse the source lessfile and write to target cssfile
|
77
|
+
def compile(lessfile, cssfile)
|
78
|
+
import_paths = options[:import_paths].unshift(File.dirname(lessfile))
|
79
|
+
parser = ::Less::Parser.new :paths => import_paths, :filename => lessfile
|
80
|
+
File.open(lessfile,'r') do |infile|
|
81
|
+
File.open(cssfile,'w') do |outfile|
|
82
|
+
tree = parser.parse(infile.read)
|
83
|
+
outfile << tree.to_css
|
84
|
+
end
|
85
|
+
end
|
86
|
+
true
|
87
|
+
rescue Exception => e
|
88
|
+
UI.info "Guard::Less: Compiling #{lessfile} failed with message: #{e.message}"
|
89
|
+
false
|
90
|
+
end
|
91
|
+
|
92
|
+
# Creates a hash of changed files keyed by their target nested directory,
|
93
|
+
# which is based on either the original source directory or the :output
|
94
|
+
# option, plus the regex match group in a watcher like:
|
95
|
+
#
|
96
|
+
# %r{^app/stylesheets/(.+\.less)$}
|
97
|
+
def nested_directory_map(paths)
|
98
|
+
directories = {}
|
99
|
+
|
100
|
+
watchers.product(paths).each do |watcher, path|
|
101
|
+
if matches = path.match(watcher.pattern)
|
102
|
+
target = options[:output] || File.dirname(path)
|
103
|
+
if subpath = matches[1]
|
104
|
+
target = File.join(target, File.dirname(subpath)).gsub(/\/\.$/, '')
|
105
|
+
end
|
106
|
+
|
107
|
+
if directories[target]
|
108
|
+
directories[target] << path
|
109
|
+
else
|
110
|
+
directories[target] = [path]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
directories
|
116
|
+
end
|
117
|
+
|
118
|
+
# mtime checking borrowed from the old official LESS Rails plugin:
|
119
|
+
# https://github.com/cloudhead/more
|
120
|
+
def mtime(file)
|
121
|
+
return 0 unless File.file?(file)
|
122
|
+
File.mtime(file).to_i
|
123
|
+
end
|
124
|
+
|
125
|
+
# consider imports for mtime
|
126
|
+
# just 1 level deep so we do not get any looping/nesting errors
|
127
|
+
def mtime_including_imports(file)
|
128
|
+
mtimes = [mtime(file)]
|
129
|
+
File.readlines(file).each do |line|
|
130
|
+
if line =~ /^\s*@import ['"]([^'"]+)/
|
131
|
+
imported = File.join(File.dirname(file), $1)
|
132
|
+
mtimes << if imported =~ /\.le?ss$/ # complete path given ?
|
133
|
+
mtime(imported)
|
134
|
+
else # we need to add .less or .lss
|
135
|
+
[mtime("#{imported}.less"), mtime("#{imported}.lss")].max
|
136
|
+
end
|
49
137
|
end
|
50
138
|
end
|
51
|
-
|
139
|
+
mtimes.max
|
52
140
|
end
|
53
141
|
|
54
142
|
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
guard 'less', :all_on_start => true, :
|
2
|
-
watch(
|
1
|
+
guard 'less', :all_on_start => true, :all_after_change => true do
|
2
|
+
watch(%r{^.+\.less$})
|
3
3
|
end
|
data/lib/guard/less/version.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.4
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Brendan Erwin
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-08-23 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -41,11 +41,68 @@ dependencies:
|
|
41
41
|
- - ~>
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
segments:
|
44
|
-
- 1
|
45
44
|
- 2
|
46
|
-
|
45
|
+
- 0
|
46
|
+
- 5
|
47
|
+
version: 2.0.5
|
47
48
|
type: :runtime
|
48
49
|
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: bundler
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ~>
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 0
|
61
|
+
version: "1.0"
|
62
|
+
type: :development
|
63
|
+
version_requirements: *id003
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: fakefs
|
66
|
+
prerelease: false
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ~>
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
- 3
|
75
|
+
version: "0.3"
|
76
|
+
type: :development
|
77
|
+
version_requirements: *id004
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: guard-rspec
|
80
|
+
prerelease: false
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ~>
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
- 4
|
89
|
+
version: "0.4"
|
90
|
+
type: :development
|
91
|
+
version_requirements: *id005
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: rspec
|
94
|
+
prerelease: false
|
95
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ~>
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
segments:
|
101
|
+
- 2
|
102
|
+
- 6
|
103
|
+
version: "2.6"
|
104
|
+
type: :development
|
105
|
+
version_requirements: *id006
|
49
106
|
description: Guard::Less automatically compiles less (like lessc --watch)
|
50
107
|
email:
|
51
108
|
- brendanjerwin@gmail.com
|