Add clean build files command and auto-clean on version change (#181)

* Add clean build files command and auto-clean on version change

* Update __main__.py
This commit is contained in:
Otto Winter 2018-10-14 18:52:21 +02:00 committed by GitHub
parent 8d395e5338
commit e34365dc7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 123 additions and 7 deletions

View file

@ -355,6 +355,17 @@ def command_version(args):
return 0
def command_clean(args, config):
build_path = relative_path(config[CONF_ESPHOMEYAML][CONF_BUILD_PATH])
try:
writer.clean_build(build_path)
except OSError as err:
_LOGGER.error("Error deleting build files: %s", err)
return 1
_LOGGER.info("Done!")
return 0
def command_dashboard(args):
from esphomeyaml.dashboard import dashboard
@ -375,6 +386,7 @@ POST_CONFIG_ACTIONS = {
'run': command_run,
'clean-mqtt': command_clean_mqtt,
'mqtt-fingerprint': command_mqtt_fingerprint,
'clean': command_clean,
}
@ -445,6 +457,8 @@ def parse_args(argv):
subparsers.add_parser('version', help="Print the esphomeyaml version and exit.")
subparsers.add_parser('clean', help="Delete all temporary build files.")
dashboard = subparsers.add_parser('dashboard',
help="Create a simple webserver for a dashboard.")
dashboard.add_argument("--port", help="The HTTP port to open connections on.", type=int,

View file

@ -124,6 +124,13 @@ class EsphomeyamlCleanMqttHandler(EsphomeyamlCommandWebSocket):
return ["esphomeyaml", config_file, "clean-mqtt"]
class EsphomeyamlCleanHandler(EsphomeyamlCommandWebSocket):
def build_command(self, message):
js = json.loads(message)
config_file = os.path.join(CONFIG_DIR, js['configuration'])
return ["esphomeyaml", config_file, "clean"]
class SerialPortRequestHandler(BaseHandler):
def get(self):
if not self.is_authenticated():
@ -221,6 +228,7 @@ def make_app(debug=False):
(r"/compile", EsphomeyamlCompileHandler),
(r"/validate", EsphomeyamlValidateHandler),
(r"/clean-mqtt", EsphomeyamlCleanMqttHandler),
(r"/clean", EsphomeyamlCleanHandler),
(r"/download.bin", DownloadBinaryRequestHandler),
(r"/serial-ports", SerialPortRequestHandler),
(r"/wizard.html", WizardRequestHandler),

View file

@ -220,6 +220,7 @@
</div>
<ul id="dropdown-{{ i }}" class="dropdown-content">
<li><a href="#" class="action-clean-mqtt" data-node="{{ file }}">Clean MQTT</a></li>
<li><a href="#" class="action-clean" data-node="{{ file }}">Clean Build</a></li>
</ul>
</div>
</div>
@ -484,6 +485,18 @@
</div>
</div>
<div id="modal-clean" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Clean Build Files <code class="inlinecode filename"></code></h4>
<div class="log-container">
<pre class="log"></pre>
</div>
</div>
<div class="modal-footer">
<a class="modal-close waves-effect waves-green btn-flat stop-logs">Stop</a>
</div>
</div>
<a class="btn-floating btn-large ribbon-fab waves-effect waves-light pink accent-2" id="setup-wizard-start">
<i class="material-icons">add</i>
</a>
@ -849,6 +862,54 @@
});
});
const cleanModalElem = document.getElementById("modal-clean");
document.querySelectorAll(".action-clean").forEach((btn) => {
btn.addEventListener('click', (e) => {
configuration = e.target.getAttribute('data-node');
const modalInstance = M.Modal.getInstance(cleanModalElem);
const log = cleanModalElem.querySelector(".log");
log.innerHTML = "";
const stopLogsButton = cleanModalElem.querySelector(".stop-logs");
let stopped = false;
stopLogsButton.innerHTML = "Stop";
modalInstance.open();
const filenameField = cleanModalElem.querySelector('.filename');
filenameField.innerHTML = configuration;
const logSocket = new WebSocket(wsUrl + "/clean");
logSocket.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
if (data.event === "line") {
const msg = data.data;
log.innerHTML += colorReplace(msg);
} else if (data.event === "exit") {
if (data.code === 0) {
M.toast({html: "Program exited successfully."});
downloadButton.classList.remove('disabled');
} else {
M.toast({html: `Program failed with code ${data.code}`});
}
stopLogsButton.innerHTML = "Close";
stopped = true;
}
});
logSocket.addEventListener('open', () => {
const msg = JSON.stringify({configuration: configuration});
logSocket.send(msg);
});
logSocket.addEventListener('close', () => {
if (!stopped) {
M.toast({html: 'Terminated process.'});
}
});
modalInstance.options.onCloseStart = () => {
logSocket.close();
};
});
});
const modalSetupElem = document.getElementById("modal-wizard");
const setupWizardStart = document.getElementById('setup-wizard-start');
const startWizard = () => {

View file

@ -3,7 +3,9 @@ from __future__ import print_function
import codecs
import errno
import json
import logging
import os
import shutil
from esphomeyaml import core
from esphomeyaml.config import iter_components
@ -14,6 +16,8 @@ from esphomeyaml.core import ESPHomeYAMLError
from esphomeyaml.core_config import VERSION_REGEX
from esphomeyaml.helpers import relative_path
_LOGGER = logging.getLogger(__name__)
CPP_AUTO_GENERATE_BEGIN = u'// ========== AUTO GENERATED CODE BEGIN ==========='
CPP_AUTO_GENERATE_END = u'// =========== AUTO GENERATED CODE END ============'
INI_AUTO_GENERATE_BEGIN = u'; ========== AUTO GENERATED CODE BEGIN ==========='
@ -111,17 +115,19 @@ def get_ini_content(config, path):
lib_version = config[CONF_ESPHOMEYAML][CONF_ESPHOMELIB_VERSION]
lib_path = os.path.join(path, 'lib')
dst_path = os.path.join(lib_path, 'esphomelib')
this_version = None
if CONF_REPOSITORY in lib_version:
tag = next((lib_version[x] for x in (CONF_COMMIT, CONF_BRANCH, CONF_TAG)
if x in lib_version), None)
if tag is None:
lib_deps.add(lib_version[CONF_REPOSITORY])
else:
lib_deps.add(lib_version[CONF_REPOSITORY] + '#' + tag)
this_version = lib_version[CONF_REPOSITORY]
if tag is not None:
this_version += '#' + tag
lib_deps.add(this_version)
if os.path.islink(dst_path):
os.unlink(dst_path)
else:
src_path = relative_path(lib_version[CONF_LOCAL])
elif CONF_LOCAL in lib_version:
this_version = lib_version[CONF_LOCAL]
src_path = relative_path(this_version)
do_write = True
if os.path.islink(dst_path):
old_path = os.path.join(os.readlink(dst_path), lib_path)
@ -144,6 +150,25 @@ def get_ini_content(config, path):
lib_deps.add(dep['name'] + '@' + dep['version'])
else:
lib_deps.add(dep['version'])
else:
this_version = lib_version
lib_deps.add(lib_version)
version_file = os.path.join(path, '.esphomelib_version')
version = None
if os.path.isfile(version_file):
with open(version_file, 'r') as ver_f:
version = ver_f.read()
if version != this_version:
_LOGGER.info("Esphomelib version change detected. Cleaning build files...")
try:
clean_build(path)
except OSError as err:
_LOGGER.warn("Error deleting build files (%s)! Ignoring...", err)
with open(version_file, 'w') as ver_f:
ver_f.write(this_version)
lib_deps |= get_build_flags(config, 'LIB_DEPS')
lib_deps |= get_build_flags(config, 'lib_deps')
@ -207,7 +232,6 @@ def write_platformio_ini(content, path):
content_format = find_begin_end(text, INI_AUTO_GENERATE_BEGIN, INI_AUTO_GENERATE_END)
else:
prev_file = None
mkdir_p(os.path.dirname(path))
content_format = INI_BASE_FORMAT
full_file = content_format[0] + INI_AUTO_GENERATE_BEGIN + '\n' + \
content + INI_AUTO_GENERATE_END + content_format[1]
@ -218,6 +242,7 @@ def write_platformio_ini(content, path):
def write_platformio_project(config, path):
mkdir_p(path)
platformio_ini = os.path.join(path, 'platformio.ini')
content = get_ini_content(config, path)
if 'esp32_ble_beacon' in config or 'esp32_ble_tracker' in config:
@ -268,3 +293,11 @@ def determine_platformio_version_settings():
settings['flash_mode_key'] = 'board_build.flash_mode'
return settings
def clean_build(build_path):
for directory in ('.piolibdeps', '.pioenvs'):
dir_path = os.path.join(build_path, directory)
if os.path.isdir(dir_path):
_LOGGER.info("Deleting %s", dir_path)
shutil.rmtree(dir_path)