forked from pderichs/sublime_rubocop
-
Notifications
You must be signed in to change notification settings - Fork 1
/
rubocop_daemon_runner.py
116 lines (100 loc) · 3.18 KB
/
rubocop_daemon_runner.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
from os.path import expanduser
from os import path
import socket
import os
import signal
import sublime
import subprocess
BUFFER_SIZE = 4096
STATUS_ID = "rubocop_daemon_runner"
class RubocopDaemonRunner(object):
def __init__(self, view, args):
self.view = view
self.config_file = ''
self.port = None
self.token = None
self.socket = None
self.workspace = None
self.auto_correct = False
self.auto_correct_all = False
self.start_daemon_automaticly = False
vars(self).update(args)
def run(self, pathlist, options=[]):
if not self.workspace:
self.set_short_status(self.view, "Rubocop Daemon: Workspace path not defined")
return ""
if not self.daemon_online():
if self.start_daemon_automaticly:
self.start_daemon()
self.set_short_status(self.view, "Rubocop Daemon starting ...")
else:
self.set_short_status(self.view, "Rubocop Daemon not running")
return ""
self.connect_to_socket()
self.send_to_socket(pathlist, options)
return self.recvall_from_socket()
def set_short_status(self, active_view, text):
def erase_status():
active_view.erase_status(STATUS_ID)
active_view.set_status(STATUS_ID, text)
sublime.set_timeout_async(erase_status, 2000)
def start_daemon(self):
subprocess.Popen(self.start_daemon_automaticly, cwd=self.workspace)
def send_to_socket(self, pathlist, options):
options_string = self.options_string(pathlist, options)
send_body = "%s %s exec %s" % (self.token, self.workspace, options_string)
self.socket.sendall(send_body.encode())
def daemon_online(self):
self.token = self.daemon_file("token")
self.port = self.daemon_file("port")
pid = self.daemon_file("pid")
if self.token == "" or self.port == "" or pid == "": return False
self.port = int(self.port)
try:
os.kill(int(pid), 0)
except OSError:
return False
else:
return True
def connect_to_socket(self):
self.socket = socket.socket()
self.socket.connect(('localhost', self.port))
def recvall_from_socket(self):
self.socket.shutdown(socket.SHUT_WR)
data = b''
while True:
part = self.socket.recv(BUFFER_SIZE)
data += part
if len(part) < BUFFER_SIZE:
# either 0 or end of data
break
self.socket.close()
return data
def daemon_file(self, name):
sub_path = self.workspace.strip("/").replace('/', '+')
file = path.join(expanduser("~"), ".cache/rubocop-daemon/%s/%s" % (sub_path, name))
if not path.isfile(file):
return ""
try:
with open(file, "r") as stream:
return stream.read()
except OSError:
return ""
def options_string(self, pathlist, options=[]):
list = self.options_list(pathlist, options)
return ' '.join(list)
def options_list(self, pathlist, options=[]):
result = []
if options:
for option in options:
result.append(option)
if self.config_file:
result.append('-c')
result.append(self.config_file)
if self.auto_correct_all:
result.append('-A')
elif self.auto_correct:
result.append('-a')
for path in pathlist:
result.append(path)
return result