26
26
import shutil
27
27
import subprocess
28
28
import platform
29
- from re import match , I
29
+ import fileinput
30
+ import re
31
+ from datetime import datetime
30
32
from clint .textui import colored , prompt
31
33
import adafruit_platformdetect
32
34
@@ -42,6 +44,7 @@ class Shell:
42
44
43
45
def __init__ (self ):
44
46
self ._group = None
47
+ self ._dirstack = []
45
48
46
49
@staticmethod
47
50
def select_n (message , selections ):
@@ -80,13 +83,22 @@ def run_command(self, cmd, suppress_message=False):
80
83
81
84
def info (self , message ):
82
85
"""
83
- Display some inforrmation
86
+ Display a message with the group in green
84
87
"""
85
88
if self ._group is not None :
86
89
print (colored .green (self ._group ) + " " + message )
87
90
else :
88
91
print (message )
89
92
93
+ def warn (self , message ):
94
+ """
95
+ Display a message with the group in yellow
96
+ """
97
+ if self ._group is not None :
98
+ print (colored .yellow (self ._group ) + " " + message )
99
+ else :
100
+ print (message )
101
+
90
102
def bail (self , message = None ):
91
103
"""
92
104
Exit and display an error message if given
@@ -133,10 +145,10 @@ def prompt(self, message, *, default=None, force_arg=None):
133
145
if reply == "" and default is not None :
134
146
return default == "y"
135
147
136
- if match ("y(?:es)?" , reply , I ):
148
+ if re . match ("y(?:es)?" , reply , re . I ):
137
149
return True
138
150
139
- if match ("n(?:o)?" , reply , I ):
151
+ if re . match ("n(?:o)?" , reply , re . I ):
140
152
return False
141
153
142
154
@staticmethod
@@ -164,9 +176,34 @@ def chdir(self, directory):
164
176
"""
165
177
Change directory
166
178
"""
167
- if directory [0 ] != "/" and directory [0 ] != "." :
168
- directory = self .getcwd () + "/" + directory
169
- return os .chdir (directory )
179
+ # if directory[0] != "/" and directory[0] != ".":
180
+ # directory = self.getcwd() + "/" + directory
181
+ directory = self .path (directory )
182
+ if not self .exists (directory ):
183
+ raise ValueError ("Directory does not exist" )
184
+ if not self .isdir (directory ):
185
+ raise ValueError ("Given location is not a directory" )
186
+ os .chdir (directory )
187
+
188
+ def pushd (self , directory ):
189
+ """
190
+ Change directory
191
+ """
192
+ # Add current dir to stack
193
+ self ._dirstack .append (self .getcwd ())
194
+ # change dir
195
+ self .chdir (directory )
196
+
197
+ def popd (self ):
198
+ """
199
+ Change directory
200
+ """
201
+ # Add current dir to stack
202
+ if len (self ._dirstack ) > 0 :
203
+ directory = self ._dirstack .pop ()
204
+ self .chdir (directory )
205
+ else :
206
+ raise RuntimeError ("Directory stack empty" )
170
207
171
208
@staticmethod
172
209
def path (file_path ):
@@ -205,6 +242,81 @@ def grep(self, search_term, location):
205
242
"grep {} {}" .format (search_term , location ), suppress_message = True
206
243
)
207
244
245
+ @staticmethod
246
+ def date ():
247
+ """
248
+ Return a string containing the current date and time
249
+ """
250
+ return datetime .now ().ctime ()
251
+
252
+ def reconfig (self , file , pattern , replacement ):
253
+ """
254
+ Given a filename, a regex pattern to match and a replacement string,
255
+ perform replacement if found, else append replacement to end of file.
256
+ """
257
+ if not self .isdir (file ):
258
+ if self .pattern_search (file , pattern ):
259
+ # Pattern found; replace in file
260
+ self .pattern_replace (file , pattern , replacement )
261
+ else :
262
+ # Not found; append (silently)
263
+ self .write_text_file (file , replacement , append = True )
264
+
265
+ def pattern_search (self , location , pattern , multi_line = False ):
266
+ """
267
+ Similar to grep, but uses pure python
268
+ multi_line will search the entire file as a large text glob,
269
+ but certain regex patterns such as ^ and $ will not work on a
270
+ line-by-line basis
271
+ returns True/False if found
272
+ """
273
+ location = self .path (location )
274
+ found = False
275
+
276
+ if self .exists (location ) and not self .isdir (location ):
277
+ if multi_line :
278
+ with open (location , "r+" ) as file :
279
+ if re .search (pattern , file .read (), flags = re .DOTALL ):
280
+ found = True
281
+ else :
282
+ for line in fileinput .FileInput (location ):
283
+ if re .search (pattern , line ):
284
+ found = True
285
+
286
+ return found
287
+
288
+ def pattern_replace (self , location , pattern , replace = "" , multi_line = False ):
289
+ """
290
+ Similar to sed, but uses pure python
291
+ multi_line will search the entire file as a large text glob,
292
+ but certain regex patterns such as ^ and $ will not work on a
293
+ line-by-line basis
294
+ """
295
+ location = self .path (location )
296
+ if self .pattern_search (location , pattern , multi_line ):
297
+ if multi_line :
298
+ regex = re .compile (pattern , flags = re .DOTALL )
299
+ with open (location , "r+" ) as file :
300
+ data = file .read ()
301
+ file .seek (0 )
302
+ file .write (regex .sub (replace , data ))
303
+ file .truncate ()
304
+ file .close ()
305
+ else :
306
+ regex = re .compile (pattern )
307
+ for line in fileinput .FileInput (location , inplace = True ):
308
+ if re .search (pattern , line ):
309
+ print (regex .sub (replace , line ), end = "" )
310
+ else :
311
+ print (line , end = "" )
312
+
313
+ def isdir (self , location ):
314
+ """
315
+ Check if a location exists and is a directory
316
+ """
317
+ location = self .path (location )
318
+ return os .path .exists (location ) and os .path .isdir (location )
319
+
208
320
def exists (self , location ):
209
321
"""
210
322
Check if a path or file exists
@@ -267,7 +379,7 @@ def is_armhf():
267
379
Check if Platform.machine() (same as uname -m) returns an ARM platform that
268
380
supports hardware floating point
269
381
"""
270
- return bool (match ("armv.l" , platform .machine ()))
382
+ return bool (re . match ("armv.l" , platform .machine ()))
271
383
272
384
@staticmethod
273
385
def is_armv6 ():
@@ -376,6 +488,13 @@ def kernel_minimum(version):
376
488
"""
377
489
return platform .release () >= str (version )
378
490
491
+ @staticmethod
492
+ def release ():
493
+ """
494
+ Return the latest kernel release version
495
+ """
496
+ return platform .release ()
497
+
379
498
def argument_exists (self , arg , prefix = "-" ):
380
499
"""
381
500
Check if the given argument was supplied
0 commit comments