140 lines
5.1 KiB
Python
140 lines
5.1 KiB
Python
import sublime
|
|
import sublime_plugin
|
|
import os
|
|
import re
|
|
import sys
|
|
#import subprocess
|
|
|
|
basicTasks = [
|
|
["lint", "Validate files with JSHint.", "Grunt default tasks"],
|
|
["qunit", "Run QUnit unit tests in a headless PhantomJS instance.", "Grunt default tasks"],
|
|
["min", "Minify files with UglifyJS.", "Grunt default tasks"],
|
|
["watch", "Run predefined tasks whenever watched files change.", "Grunt default tasks"],
|
|
["server", "Start a static web server.", "Grunt default tasks"],
|
|
["concat", "Concatenate files.", "Grunt default tasks"],
|
|
["test", "Run unit tests with nodeunit.", "Grunt default tasks"],
|
|
["init", "Generate project scaffolding from a predefined template.", "Grunt default tasks"]
|
|
]
|
|
|
|
rFiles = re.compile(r'loadNpmTasks\(\'(.*)\'\)', re.M | re.I)
|
|
rSingle = re.compile(r'registerTask.*\(.*\'(.*)\'.*,.*\'(.*)\'.*\)', re.M | re.I)
|
|
rMulti = re.compile(r'registerMultiTask.*\(.*\'(.*)\'.*,.*\'(.*)\'.*,', re.M | re.I)
|
|
rFunc = re.compile(r'registerMultiTask.*\(.*\'(.*)\'.*,.*\'(.*)\'.*,.*function\((.*)\).*{', re.M | re.I)
|
|
|
|
|
|
class GruntConsole(object):
|
|
def __init__(self, window):
|
|
self.window = window
|
|
|
|
@property
|
|
def view(self):
|
|
v = self.window.new_file()
|
|
v.set_name("Grunt")
|
|
v.set_scratch(True)
|
|
return v
|
|
|
|
|
|
class GruntfileParser(object):
|
|
def __init__(self, window):
|
|
self.window = window
|
|
self.grunt_files = []
|
|
self.folders = []
|
|
for f in self.window.folders():
|
|
self.folders.append(f)
|
|
if os.path.exists(os.path.join(f, "grunt.js")):
|
|
self.grunt_files.append(os.path.join(f, "grunt.js"))
|
|
elif os.path.exists(os.path.join(f, "Gruntfile.js")):
|
|
self.grunt_files.append(os.path.join(f, "Gruntfile.js"))
|
|
if len(self.grunt_files) > 0:
|
|
if len(self.grunt_files) == 1:
|
|
self.choose_file(0)
|
|
else:
|
|
self.window.show_quick_panel(self.grunt_files, self.choose_file)
|
|
else:
|
|
sublime.error_message("Gruntfile not found!")
|
|
|
|
def extractTasks(self, file, source):
|
|
tasks = []
|
|
try:
|
|
f = open(file, "r")
|
|
for line in f:
|
|
# Single Tasks
|
|
matchSingle = rSingle.search(line)
|
|
matchFunc = rFunc.search(line)
|
|
matchMulti = rMulti.search(line)
|
|
if matchSingle:
|
|
l = list(matchSingle.groups())
|
|
l.append(source)
|
|
tasks.append(l)
|
|
print(l)
|
|
# Function Tasks
|
|
elif matchFunc:
|
|
l = list(matchFunc.groups())
|
|
l.append(source)
|
|
l[0] = l[0] + ' *'
|
|
tasks.append(l)
|
|
print(l)
|
|
# Multi Tasks
|
|
elif matchMulti:
|
|
l = list(matchMulti.groups())
|
|
l.append(source)
|
|
l[0] = l[0] + ' **'
|
|
tasks.append(l)
|
|
print(l)
|
|
#match = rMulti.search(line)
|
|
#if match:
|
|
# self.tasks.append(list(match.groups()))
|
|
# print(list(match.groups()))
|
|
f.close()
|
|
except IOError:
|
|
sys.stderr.write("[sublime-grunt] - Error: Could not open %s\n" % (file))
|
|
sys.exit(-1)
|
|
except:
|
|
sys.stderr.write("[sublime-grunt] - Error =( \n")
|
|
sys.exit(-1)
|
|
return tasks
|
|
|
|
def extractNpmFiles(self, file):
|
|
files = []
|
|
try:
|
|
f = open(file, "r")
|
|
for line in f:
|
|
match = rFiles.search(line)
|
|
if match:
|
|
files.append(match.groups()[0])
|
|
except IOError:
|
|
sys.stderr.write("[sublime-grunt] - Error: Could not open %s\n" % (file))
|
|
sys.exit(-1)
|
|
finally:
|
|
f.close()
|
|
return files
|
|
|
|
def choose_file(self, file):
|
|
self.wd = os.path.dirname(self.grunt_files[file])
|
|
npmTasks = []
|
|
|
|
files = self.extractNpmFiles(self.grunt_files[file])
|
|
for f in files:
|
|
taskFiles = [tf for tf in os.listdir(os.path.join(self.wd, "node_modules", f, "tasks")) if tf.lower().endswith('.js')]
|
|
for tf in taskFiles:
|
|
npmTasks = npmTasks + self.extractTasks(os.path.join(self.wd, "node_modules", f, "tasks", tf), "Module: %s" % f)
|
|
self.tasks = self.extractTasks(self.grunt_files[file], self.grunt_files[file]) + npmTasks + basicTasks
|
|
self.window.show_quick_panel(self.tasks, self.on_done)
|
|
#self.window.show_quick_panel(files, self.on_done)
|
|
|
|
def on_done(self, task):
|
|
if task > -1:
|
|
exec_args = settings().get('exec_args')
|
|
exec_args.update({'cmd': u"grunt --no-color " + self.tasks[task][0], 'shell': True, 'working_dir': self.folders[0]})
|
|
self.window.run_command("exec", exec_args)
|
|
|
|
|
|
def settings():
|
|
return sublime.load_settings('SublimeGrunt.sublime-settings')
|
|
|
|
|
|
class GruntCommand(sublime_plugin.TextCommand):
|
|
def run(self, edit):
|
|
self.window = self.view.window()
|
|
GruntfileParser(self.window)
|