mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 00:18:11 +01:00
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:
parent
8d395e5338
commit
e34365dc7c
4 changed files with 123 additions and 7 deletions
|
@ -355,6 +355,17 @@ def command_version(args):
|
||||||
return 0
|
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):
|
def command_dashboard(args):
|
||||||
from esphomeyaml.dashboard import dashboard
|
from esphomeyaml.dashboard import dashboard
|
||||||
|
|
||||||
|
@ -375,6 +386,7 @@ POST_CONFIG_ACTIONS = {
|
||||||
'run': command_run,
|
'run': command_run,
|
||||||
'clean-mqtt': command_clean_mqtt,
|
'clean-mqtt': command_clean_mqtt,
|
||||||
'mqtt-fingerprint': command_mqtt_fingerprint,
|
'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('version', help="Print the esphomeyaml version and exit.")
|
||||||
|
|
||||||
|
subparsers.add_parser('clean', help="Delete all temporary build files.")
|
||||||
|
|
||||||
dashboard = subparsers.add_parser('dashboard',
|
dashboard = subparsers.add_parser('dashboard',
|
||||||
help="Create a simple webserver for a dashboard.")
|
help="Create a simple webserver for a dashboard.")
|
||||||
dashboard.add_argument("--port", help="The HTTP port to open connections on.", type=int,
|
dashboard.add_argument("--port", help="The HTTP port to open connections on.", type=int,
|
||||||
|
|
|
@ -124,6 +124,13 @@ class EsphomeyamlCleanMqttHandler(EsphomeyamlCommandWebSocket):
|
||||||
return ["esphomeyaml", config_file, "clean-mqtt"]
|
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):
|
class SerialPortRequestHandler(BaseHandler):
|
||||||
def get(self):
|
def get(self):
|
||||||
if not self.is_authenticated():
|
if not self.is_authenticated():
|
||||||
|
@ -221,6 +228,7 @@ def make_app(debug=False):
|
||||||
(r"/compile", EsphomeyamlCompileHandler),
|
(r"/compile", EsphomeyamlCompileHandler),
|
||||||
(r"/validate", EsphomeyamlValidateHandler),
|
(r"/validate", EsphomeyamlValidateHandler),
|
||||||
(r"/clean-mqtt", EsphomeyamlCleanMqttHandler),
|
(r"/clean-mqtt", EsphomeyamlCleanMqttHandler),
|
||||||
|
(r"/clean", EsphomeyamlCleanHandler),
|
||||||
(r"/download.bin", DownloadBinaryRequestHandler),
|
(r"/download.bin", DownloadBinaryRequestHandler),
|
||||||
(r"/serial-ports", SerialPortRequestHandler),
|
(r"/serial-ports", SerialPortRequestHandler),
|
||||||
(r"/wizard.html", WizardRequestHandler),
|
(r"/wizard.html", WizardRequestHandler),
|
||||||
|
|
|
@ -220,6 +220,7 @@
|
||||||
</div>
|
</div>
|
||||||
<ul id="dropdown-{{ i }}" class="dropdown-content">
|
<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-mqtt" data-node="{{ file }}">Clean MQTT</a></li>
|
||||||
|
<li><a href="#" class="action-clean" data-node="{{ file }}">Clean Build</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -484,6 +485,18 @@
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<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>
|
<i class="material-icons">add</i>
|
||||||
</a>
|
</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 modalSetupElem = document.getElementById("modal-wizard");
|
||||||
const setupWizardStart = document.getElementById('setup-wizard-start');
|
const setupWizardStart = document.getElementById('setup-wizard-start');
|
||||||
const startWizard = () => {
|
const startWizard = () => {
|
||||||
|
|
|
@ -3,7 +3,9 @@ from __future__ import print_function
|
||||||
import codecs
|
import codecs
|
||||||
import errno
|
import errno
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
|
|
||||||
from esphomeyaml import core
|
from esphomeyaml import core
|
||||||
from esphomeyaml.config import iter_components
|
from esphomeyaml.config import iter_components
|
||||||
|
@ -14,6 +16,8 @@ from esphomeyaml.core import ESPHomeYAMLError
|
||||||
from esphomeyaml.core_config import VERSION_REGEX
|
from esphomeyaml.core_config import VERSION_REGEX
|
||||||
from esphomeyaml.helpers import relative_path
|
from esphomeyaml.helpers import relative_path
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
CPP_AUTO_GENERATE_BEGIN = u'// ========== AUTO GENERATED CODE BEGIN ==========='
|
CPP_AUTO_GENERATE_BEGIN = u'// ========== AUTO GENERATED CODE BEGIN ==========='
|
||||||
CPP_AUTO_GENERATE_END = u'// =========== AUTO GENERATED CODE END ============'
|
CPP_AUTO_GENERATE_END = u'// =========== AUTO GENERATED CODE END ============'
|
||||||
INI_AUTO_GENERATE_BEGIN = u'; ========== AUTO GENERATED CODE BEGIN ==========='
|
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_version = config[CONF_ESPHOMEYAML][CONF_ESPHOMELIB_VERSION]
|
||||||
lib_path = os.path.join(path, 'lib')
|
lib_path = os.path.join(path, 'lib')
|
||||||
dst_path = os.path.join(lib_path, 'esphomelib')
|
dst_path = os.path.join(lib_path, 'esphomelib')
|
||||||
|
this_version = None
|
||||||
if CONF_REPOSITORY in lib_version:
|
if CONF_REPOSITORY in lib_version:
|
||||||
tag = next((lib_version[x] for x in (CONF_COMMIT, CONF_BRANCH, CONF_TAG)
|
tag = next((lib_version[x] for x in (CONF_COMMIT, CONF_BRANCH, CONF_TAG)
|
||||||
if x in lib_version), None)
|
if x in lib_version), None)
|
||||||
if tag is None:
|
this_version = lib_version[CONF_REPOSITORY]
|
||||||
lib_deps.add(lib_version[CONF_REPOSITORY])
|
if tag is not None:
|
||||||
else:
|
this_version += '#' + tag
|
||||||
lib_deps.add(lib_version[CONF_REPOSITORY] + '#' + tag)
|
lib_deps.add(this_version)
|
||||||
if os.path.islink(dst_path):
|
if os.path.islink(dst_path):
|
||||||
os.unlink(dst_path)
|
os.unlink(dst_path)
|
||||||
else:
|
elif CONF_LOCAL in lib_version:
|
||||||
src_path = relative_path(lib_version[CONF_LOCAL])
|
this_version = lib_version[CONF_LOCAL]
|
||||||
|
src_path = relative_path(this_version)
|
||||||
do_write = True
|
do_write = True
|
||||||
if os.path.islink(dst_path):
|
if os.path.islink(dst_path):
|
||||||
old_path = os.path.join(os.readlink(dst_path), lib_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'])
|
lib_deps.add(dep['name'] + '@' + dep['version'])
|
||||||
else:
|
else:
|
||||||
lib_deps.add(dep['version'])
|
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')
|
||||||
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)
|
content_format = find_begin_end(text, INI_AUTO_GENERATE_BEGIN, INI_AUTO_GENERATE_END)
|
||||||
else:
|
else:
|
||||||
prev_file = None
|
prev_file = None
|
||||||
mkdir_p(os.path.dirname(path))
|
|
||||||
content_format = INI_BASE_FORMAT
|
content_format = INI_BASE_FORMAT
|
||||||
full_file = content_format[0] + INI_AUTO_GENERATE_BEGIN + '\n' + \
|
full_file = content_format[0] + INI_AUTO_GENERATE_BEGIN + '\n' + \
|
||||||
content + INI_AUTO_GENERATE_END + content_format[1]
|
content + INI_AUTO_GENERATE_END + content_format[1]
|
||||||
|
@ -218,6 +242,7 @@ def write_platformio_ini(content, path):
|
||||||
|
|
||||||
|
|
||||||
def write_platformio_project(config, path):
|
def write_platformio_project(config, path):
|
||||||
|
mkdir_p(path)
|
||||||
platformio_ini = os.path.join(path, 'platformio.ini')
|
platformio_ini = os.path.join(path, 'platformio.ini')
|
||||||
content = get_ini_content(config, path)
|
content = get_ini_content(config, path)
|
||||||
if 'esp32_ble_beacon' in config or 'esp32_ble_tracker' in config:
|
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'
|
settings['flash_mode_key'] = 'board_build.flash_mode'
|
||||||
|
|
||||||
return settings
|
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)
|
||||||
|
|
Loading…
Reference in a new issue