2 # -*- coding: utf-8 -*-
7 Copyright (c) 2014 Frédéric Massart - FMCorz.net
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 http://github.com/FMCorz/mdk
28 import watchdog
.events
29 import watchdog
.observers
31 from ..command
import Command
34 class CssCommand(Command
):
40 'action': 'store_true',
42 'help': 'compile the theme less files'
51 'help': 'the sheets to work on without their extensions. When not specified, it is guessed from the less folder.',
61 'help': 'the theme to work on. The default is \'bootstrapbase\' but is ignored if we are in a theme folder.',
67 'action': 'store_true',
69 'help': 'produce an unminified debugging version with source maps'
75 'action': 'store_true',
77 'help': 'watch the directory'
84 'help': 'name of the instances',
90 _description
= 'Wrapper for CSS functions'
94 Mlist
= self
.Wp
.resolveMultiple(args
.names
)
96 raise Exception('No instances to work on. Exiting...')
98 # Resolve the theme folder we are in.
100 mpath
= os
.path
.join(Mlist
[0].get('path'), 'theme')
101 cwd
= os
.path
.realpath(os
.path
.abspath(os
.getcwd()))
102 if cwd
.startswith(mpath
):
103 candidate
= cwd
.replace(mpath
, '').strip('/')
105 (head
, tail
) = os
.path
.split(candidate
)
106 if not head
and tail
:
109 logging
.info('You are in the theme \'%s\', using that.' %
(args
.theme
))
111 elif not head
and not tail
:
112 # Nothing, let's leave.
116 # We have not found anything, falling back on the default.
118 args
.theme
= 'bootstrapbase'
122 logging
.info('Compiling theme \'%s\' on %s' %
(args
.theme
, M
.get('identifier')))
123 processor
= css
.Css(M
)
124 processor
.setDebug(args
.debug
)
126 processor
.setCompiler('lessc')
127 elif M
.branch_compare(29, '<'):
128 # Grunt was only introduced for 2.9.
129 processor
.setCompiler('recess')
131 processor
.compile(theme
=args
.theme
, sheets
=args
.sheets
)
133 # Setting up watchdog. This code should be improved when we will have more than a compile option.
135 if args
.compile and args
.watch
:
136 observer
= watchdog
.observers
.Observer()
139 if args
.watch
and args
.compile:
140 processor
= css
.Css(M
)
141 processorArgs
= {'theme': args
.theme
, 'sheets': args
.sheets
}
142 handler
= LessWatcher(M
, processor
, processorArgs
)
143 observer
.schedule(handler
, processor
.getThemeLessPath(args
.theme
), recursive
=True)
144 logging
.info('Watchdog set up on %s/%s, waiting for changes...' %
(M
.get('identifier'), args
.theme
))
146 if observer
and args
.compile and args
.watch
:
152 except KeyboardInterrupt:
158 class LessWatcher(watchdog
.events
.FileSystemEventHandler
):
165 def __init__(self
, M
, processor
, args
):
166 super(self
.__class__
, self
).__init__()
168 self
._processor
= processor
171 def on_modified(self
, event
):
174 def on_moved(self
, event
):
177 def process(self
, event
):
178 if event
.is_directory
:
180 elif not event
.src_path
.endswith(self
._ext
):
183 filename
= event
.src_path
.replace(self
._processor
.getThemeLessPath(self
._args
['theme']), '').strip('/')
184 logging
.info('[%s] Changes detected in %s!' %
(self
._M
.get('identifier'), filename
))
185 self
._processor
.compile(**self
._args
)