-
Notifications
You must be signed in to change notification settings - Fork 1
/
espedite.py
executable file
·155 lines (118 loc) · 7.48 KB
/
espedite.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python
import os
import subprocess
import time
import util.opt_parser as parser
from util.toolkit import log, check_executable_exists, check_file_exists, properties, \
get_modified_files, execute_shell_command, execute_shell_command_get_output, read_file_to_list, \
check_folder_exists, remove_files_by_ext_recursively,timestamp_to_human_readable, \
get_subdirectory_structure_by_filelist, die
timestamp = 0
timestamp_file = parser.options.path + properties.osDirSeparator + properties.timeStampFilename
skip_files = []
start_time = time.time()
if parser.options.path == os.getcwd() and (parser.options.install or parser.options.skip or parser.options.profile):
die("You tried to run espedite from within its own folder. Please cd to your code folder instead and run it from there.")
# Remove any compiled files
remove_files_by_ext_recursively(parser.options.path, properties.binaryCodeExtension)
# Read timestamp
if check_file_exists(timestamp_file):
with open(timestamp_file, 'r') as f:
timestamp = f.readline().strip()
log.debug("Last execution was on {} (UNIX Timestamp: {}) ".format(timestamp_to_human_readable(timestamp), str(timestamp)))
log.info("Running script in path '{}'". format(parser.options.path))
check_executable_exists("ampy", True)
if parser.options.connect:
check_executable_exists("picocom", True)
modified_relative_files = get_modified_files(parser.options.path, timestamp, True)
if parser.options.skip:
# READ SKIPFILE
log.info("Reading skip file '{}' ....".format(parser.options.skip))
skip_files = read_file_to_list(parser.options.path + properties.osDirSeparator + parser.options.skip)
if parser.options.uninstall:
# UNINSTALL
log.info("Uninstalling ....")
installed_files = execute_shell_command_get_output("sudo ampy --port /dev/ttyUSB0 ls /").split("\n")
for f in installed_files:
# ampy returns an empty string at the end so skip that
if f == "":
continue
log.info("Removing file or folder '{}' ....".format(f))
execute_shell_command("sudo ampy --port /dev/ttyUSB0 rmdir {}".format(f), stderr=subprocess.PIPE)
execute_shell_command("sudo ampy --port /dev/ttyUSB0 rm {}".format(f), stderr=subprocess.PIPE)
# Remove timestamp file
try:
os.remove(timestamp_file)
log.info("Removing timestamp file '{}' ....".format(timestamp_file))
except OSError:
pass
log.info("Uninstallation complete ....")
if modified_relative_files and parser.options.install:
# print(get_subdirectory_structure(parser.options.path))
if parser.options.compile:
# COMPILE
log.info("Compiling ....")
if not check_folder_exists(os.getcwd() + properties.osDirSeparator + "micropython"):
log.debug("Compiling the compiler ..."),
pushd = os.getcwd()
execute_shell_command("git clone https://github.com/micropython/micropython")
os.chdir(os.getcwd() + "/micropython/mpy-cross")
execute_shell_command("make")
os.chdir(pushd)
for f in modified_relative_files:
extension = os.path.splitext(f)[1]
if extension == properties.sourceCodeExtension:
log.info("Compiling file {}".format(f))
execute_shell_command("{}/micropython/mpy-cross/mpy-cross {}".format(os.getcwd(), parser.options.path + properties.osDirSeparator + f))
if parser.options.install or parser.options.profile:
log.info("Installing ....")
# Create folder structure for modified files
dir_structure = get_subdirectory_structure_by_filelist(modified_relative_files)
log.info("Creating folder structure (if required)")
for d in dir_structure:
execute_shell_command("sudo ampy --port /dev/ttyUSB0 mkdir {}".format(d), stderr=subprocess.PIPE)
# Do this for all files modified or new
for f in modified_relative_files:
# Skip if it's included in the skip file
if f in skip_files:
log.debug("Skipping '{}' although it was modified".format(f))
continue
log.info("Installing file '{}'".format(f))
# Remove file to be uploaded
execute_shell_command("sudo ampy --port /dev/ttyUSB0 rm {}".format(f), stderr=subprocess.PIPE)
# Remove compiled file if exist
if os.path.splitext(f)[1] == properties.sourceCodeExtension:
execute_shell_command("sudo ampy --port /dev/ttyUSB0 rm {}{}".format(os.path.splitext(f)[0],
properties.binaryCodeExtension), stderr=subprocess.PIPE)
# Prefer to install compiled file rather than source
if parser.options.compile and os.path.splitext(f)[1] == properties.sourceCodeExtension:
execute_shell_command("sudo ampy --port /dev/ttyUSB0 put {} {}".format(parser.options.path + properties.osDirSeparator +
os.path.splitext(f)[0] + properties.binaryCodeExtension,
os.path.splitext(f)[0] + properties.binaryCodeExtension))
# Workaround for these two files only since Micropython expects the uncompiled versions to be present as well
if f in ['main.py', 'boot.py']:
execute_shell_command("sudo ampy --port /dev/ttyUSB0 put {} {}".format(parser.options.path + properties.osDirSeparator + f, f))
# Otherwise upload original file
else:
execute_shell_command("sudo ampy --port /dev/ttyUSB0 put {} {}".format(parser.options.path + properties.osDirSeparator + f, f))
# Apply selected profile
if parser.options.profile and check_folder_exists("{}/profile/{}".format(parser.options.path, parser.options.profile)):
log.info("Applying profile '{}'".format(parser.options.profile))
execute_shell_command("sudo ampy --port /dev/ttyUSB0 rm main.py", stderr=subprocess.PIPE)
execute_shell_command("sudo ampy --port /dev/ttyUSB0 rm main.mpy", stderr=subprocess.PIPE)
execute_shell_command("sudo ampy --port /dev/ttyUSB0 rm conf/profile.properties", stderr=subprocess.PIPE)
execute_shell_command("sudo ampy --port /dev/ttyUSB0 put {} {}".format("{}/profile/{}/{}".format(parser.options.path, parser.options.profile, "main.mpy"), "main.mpy"))
execute_shell_command("sudo ampy --port /dev/ttyUSB0 put {} {}".format("{}/profile/{}/{}".format(parser.options.path, parser.options.profile, "main.py"), "main.py"))
execute_shell_command("sudo ampy --port /dev/ttyUSB0 put {} {}".format("{}/profile/{}/conf/{}".format(parser.options.path, parser.options.profile, "profile.properties"), "conf/profile.properties"))
# Write installation timestamp
with open(timestamp_file, "w") as text_file:
text_file.write("{}\n".format(time.time()))
elif parser.options.install and not modified_relative_files:
log.warn("No modified files detected since last execution on {}. Installation skipped.".format(timestamp_to_human_readable(timestamp)))
log.info("Execution time '{} sec'".format(time.time() - start_time))
if parser.options.connect:
# CONNECT
log.info("Connecting to '{}' ....".format(parser.options.device))
execute_shell_command("sudo picocom --baud 115200 /dev/ttyUSB0")
# Salute!
log.info("Bye bye! :-)")