forked from haksy1/SassBuilder
-
Notifications
You must be signed in to change notification settings - Fork 1
/
SassBuilder.py
164 lines (109 loc) · 4.15 KB
/
SassBuilder.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import sublime, sublime_plugin
import codecs
import json
import os
import re
from functools import partial
from threading import Thread
from subprocess import PIPE, Popen
SASS_EXTENSIONS = ('.scss', '.sass')
def which(executable):
for path in os.environ['PATH'].split(os.pathsep):
path = path.strip('"')
fpath = os.path.join(path, executable)
if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
return fpath
if os.name == 'nt' and not executable.endswith('.exe'):
return which('{}.exe'.format(executable))
return None
def path_info(path):
root = os.path.dirname(path)
name = os.path.splitext(os.path.basename(path))[0]
extn = os.path.splitext(path)[1]
return {'root': root, 'name': name, 'extn': extn, 'path': path}
def find_files(pattern, path):
pattern = re.compile(pattern)
found = []
path = os.path.realpath(path)
for root, dirnames, files in os.walk(path):
for fname in files:
if fname.endswith(SASS_EXTENSIONS):
with codecs.open(os.path.join(root, fname), 'r', "utf-8") as f:
if any(pattern.search(line) for line in f):
found.append(os.path.join(root, fname))
break
return found
def grep_files(pattern, path):
path = os.path.realpath(path)
grep = '''grep -E "{}" * -lr'''.format(pattern)
proc = Popen(grep, shell=True, cwd=path, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
if err:
print(err)
sublime.error_message('SassBuilder: Hit \'ctrl+`\' to see errors.')
if not out:
return None
out = out.decode('utf8')
found = []
for f in out.split():
if f.endswith(SASS_EXTENSIONS):
found.append(os.path.join(path, f))
return found
def get_partial_files(info, project_path):
pattern = '''@import.*{}'''.format(info['name'][1:])
if which('grep'):
return grep_files(pattern, project_path)
return find_files(pattern, project_path)
def get_files(info, project_path):
if info['name'].startswith('_'):
return get_partial_files(info, project_path)
return [info['path']]
def load_settings(project_path):
try:
with open(os.sep.join([project_path, '.sassbuilder-config.json']), 'r') as f:
data = f.read()
return json.loads(data)
except:
return None
def compile_sass(files, settings):
compiled_files = []
for f in files:
info = path_info(f)
srcp = os.path.join(info['root'], settings['output_path'])
name = '.'.join([info['name'], 'css'])
path = os.path.join(srcp, name)
sass = 'sass --update \'{0}\':\'{1}\' --stop-on-error --trace {2} ' \
'--style {3}'
rules = []
if not settings['options']['cache']:
rules.append('--no-cache')
if settings['options']['debug']:
rules.append('--debug-info')
if settings['options']['line-comments']:
rules.append('--line-comments')
if settings['options']['line-numbers']:
rules.append('--line-numbers')
rules = ' '.join(rules)
sass = sass.format(info['path'], path, rules,
settings['options']['style'])
sass = Popen(sass, shell=True, cwd=info['root'], stdout=PIPE, stderr=PIPE)
out, err = sass.communicate()
if out:
compiled_files.append(name)
if err:
print(err)
sublime.error_message('SassBuilder: Hit \'ctrl+`\' to see errors.')
return
print('{0} has been compiled.'.format(', '.join(compiled_files)))
class SassBuilderCommand(sublime_plugin.EventListener):
def on_post_save(self, view):
info = path_info(view.file_name())
settings = load_settings(info['root'])
if not settings:
return None
if info['extn'] in SASS_EXTENSIONS:
print('SassBuilder started.')
files = get_files(info, settings['project_path'])
#t = Thread(target=compile_sass, args=(files, settings))
#t.start()
compile_sass(files, settings)