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)
 |