Skip to content

Commit 3e8e9b0

Browse files
authored
Merge pull request #4 from makermelissa/master
Added pattern find/replace, popd/pushd, date and other goodies
2 parents 9c77a98 + 35da19e commit 3e8e9b0

File tree

1 file changed

+127
-8
lines changed

1 file changed

+127
-8
lines changed

adafruit_shell.py

Lines changed: 127 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
import shutil
2727
import subprocess
2828
import platform
29-
from re import match, I
29+
import fileinput
30+
import re
31+
from datetime import datetime
3032
from clint.textui import colored, prompt
3133
import adafruit_platformdetect
3234

@@ -42,6 +44,7 @@ class Shell:
4244

4345
def __init__(self):
4446
self._group = None
47+
self._dirstack = []
4548

4649
@staticmethod
4750
def select_n(message, selections):
@@ -80,13 +83,22 @@ def run_command(self, cmd, suppress_message=False):
8083

8184
def info(self, message):
8285
"""
83-
Display some inforrmation
86+
Display a message with the group in green
8487
"""
8588
if self._group is not None:
8689
print(colored.green(self._group) + " " + message)
8790
else:
8891
print(message)
8992

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+
90102
def bail(self, message=None):
91103
"""
92104
Exit and display an error message if given
@@ -133,10 +145,10 @@ def prompt(self, message, *, default=None, force_arg=None):
133145
if reply == "" and default is not None:
134146
return default == "y"
135147

136-
if match("y(?:es)?", reply, I):
148+
if re.match("y(?:es)?", reply, re.I):
137149
return True
138150

139-
if match("n(?:o)?", reply, I):
151+
if re.match("n(?:o)?", reply, re.I):
140152
return False
141153

142154
@staticmethod
@@ -164,9 +176,34 @@ def chdir(self, directory):
164176
"""
165177
Change directory
166178
"""
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")
170207

171208
@staticmethod
172209
def path(file_path):
@@ -205,6 +242,81 @@ def grep(self, search_term, location):
205242
"grep {} {}".format(search_term, location), suppress_message=True
206243
)
207244

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+
208320
def exists(self, location):
209321
"""
210322
Check if a path or file exists
@@ -267,7 +379,7 @@ def is_armhf():
267379
Check if Platform.machine() (same as uname -m) returns an ARM platform that
268380
supports hardware floating point
269381
"""
270-
return bool(match("armv.l", platform.machine()))
382+
return bool(re.match("armv.l", platform.machine()))
271383

272384
@staticmethod
273385
def is_armv6():
@@ -376,6 +488,13 @@ def kernel_minimum(version):
376488
"""
377489
return platform.release() >= str(version)
378490

491+
@staticmethod
492+
def release():
493+
"""
494+
Return the latest kernel release version
495+
"""
496+
return platform.release()
497+
379498
def argument_exists(self, arg, prefix="-"):
380499
"""
381500
Check if the given argument was supplied

0 commit comments

Comments
 (0)