feat(script): add formatting for script failure (#2596)
Closes #2588 * feat(script): add formatting for script failure * refactor: address review comments * doc: add changelog entry * refactor: minor cleanup
This commit is contained in:
parent
dc46251571
commit
f5bfbccfc8
@ -81,6 +81,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- `DEBUG_SHADED` cmake variable and its associated functionality.
|
- `DEBUG_SHADED` cmake variable and its associated functionality.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- `custom/script`: Add formatting for script failure (`format-fail`, `label-fail`) ([`#2588`](https://github.com/polybar/polybar/issues/2588))
|
||||||
- Support `px` and `pt` units everyhwere where before only a number of spaces
|
- Support `px` and `pt` units everyhwere where before only a number of spaces
|
||||||
or pixels could be specified.
|
or pixels could be specified.
|
||||||
([`#2578`](https://github.com/polybar/polybar/pull/2578))
|
([`#2578`](https://github.com/polybar/polybar/pull/2578))
|
||||||
|
@ -24,13 +24,14 @@ class script_runner {
|
|||||||
|
|
||||||
int get_pid() const;
|
int get_pid() const;
|
||||||
int get_counter() const;
|
int get_counter() const;
|
||||||
|
int get_exit_status() const;
|
||||||
|
|
||||||
string get_output();
|
string get_output();
|
||||||
|
|
||||||
bool is_stopping() const;
|
bool is_stopping() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool set_output(const string&&);
|
bool set_output(string&&);
|
||||||
|
|
||||||
interval run_tail();
|
interval run_tail();
|
||||||
interval run();
|
interval run();
|
||||||
@ -52,6 +53,7 @@ class script_runner {
|
|||||||
std::atomic_int m_counter{0};
|
std::atomic_int m_counter{0};
|
||||||
std::atomic_bool m_stopping{false};
|
std::atomic_bool m_stopping{false};
|
||||||
std::atomic_int m_pid{-1};
|
std::atomic_int m_pid{-1};
|
||||||
|
std::atomic_int m_exit_status{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -16,6 +16,8 @@ namespace modules {
|
|||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
string get_output();
|
string get_output();
|
||||||
|
string get_format() const;
|
||||||
|
|
||||||
bool build(builder* builder, const string& tag) const;
|
bool build(builder* builder, const string& tag) const;
|
||||||
|
|
||||||
static constexpr auto TYPE = "custom/script";
|
static constexpr auto TYPE = "custom/script";
|
||||||
@ -24,7 +26,9 @@ namespace modules {
|
|||||||
bool check_condition();
|
bool check_condition();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr const char* TAG_LABEL{"<label>"};
|
static constexpr auto TAG_LABEL = "<label>";
|
||||||
|
static constexpr auto TAG_LABEL_FAIL = "<label-fail>";
|
||||||
|
static constexpr auto FORMAT_FAIL = "format-fail";
|
||||||
|
|
||||||
const bool m_tail;
|
const bool m_tail;
|
||||||
const script_runner::interval m_interval{0};
|
const script_runner::interval m_interval{0};
|
||||||
@ -34,6 +38,7 @@ namespace modules {
|
|||||||
map<mousebtn, string> m_actions;
|
map<mousebtn, string> m_actions;
|
||||||
|
|
||||||
label_t m_label;
|
label_t m_label;
|
||||||
|
label_t m_label_fail;
|
||||||
};
|
};
|
||||||
} // namespace modules
|
} // namespace modules
|
||||||
|
|
||||||
|
@ -60,6 +60,10 @@ int script_runner::get_counter() const {
|
|||||||
return m_counter;
|
return m_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int script_runner::get_exit_status() const {
|
||||||
|
return m_exit_status;
|
||||||
|
}
|
||||||
|
|
||||||
string script_runner::get_output() {
|
string script_runner::get_output() {
|
||||||
std::lock_guard<std::mutex> guard(m_output_lock);
|
std::lock_guard<std::mutex> guard(m_output_lock);
|
||||||
return m_output;
|
return m_output;
|
||||||
@ -74,7 +78,7 @@ bool script_runner::is_stopping() const {
|
|||||||
*
|
*
|
||||||
* Returns true if the output changed.
|
* Returns true if the output changed.
|
||||||
*/
|
*/
|
||||||
bool script_runner::set_output(const string&& new_output) {
|
bool script_runner::set_output(string&& new_output) {
|
||||||
std::lock_guard<std::mutex> guard(m_output_lock);
|
std::lock_guard<std::mutex> guard(m_output_lock);
|
||||||
|
|
||||||
if (m_output != new_output) {
|
if (m_output != new_output) {
|
||||||
@ -98,16 +102,16 @@ script_runner::interval script_runner::run() {
|
|||||||
throw modules::module_error("Failed to execute command, stopping module...");
|
throw modules::module_error("Failed to execute command, stopping module...");
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = cmd->get_exit_status();
|
m_exit_status = cmd->get_exit_status();
|
||||||
int fd = cmd->get_stdout(PIPE_READ);
|
int fd = cmd->get_stdout(PIPE_READ);
|
||||||
assert(fd != -1);
|
assert(fd != -1);
|
||||||
bool changed = io_util::poll_read(fd) && set_output(cmd->readline());
|
bool changed = io_util::poll_read(fd) && set_output(cmd->readline());
|
||||||
|
|
||||||
if (!changed && status != 0) {
|
if (!changed && m_exit_status != 0) {
|
||||||
clear_output();
|
clear_output();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == 0) {
|
if (m_exit_status == 0) {
|
||||||
return m_interval;
|
return m_interval;
|
||||||
} else {
|
} else {
|
||||||
return std::max(m_interval, interval{1s});
|
return std::max(m_interval, interval{1s});
|
||||||
@ -142,7 +146,7 @@ script_runner::interval script_runner::run_tail() {
|
|||||||
return 0s;
|
return 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exit_status = cmd->wait();
|
auto exit_status = cmd->wait();
|
||||||
|
|
||||||
if (exit_status == 0) {
|
if (exit_status == 0) {
|
||||||
return m_interval;
|
return m_interval;
|
||||||
|
@ -25,7 +25,12 @@ namespace modules {
|
|||||||
// Setup formatting
|
// Setup formatting
|
||||||
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL});
|
m_formatter->add(DEFAULT_FORMAT, TAG_LABEL, {TAG_LABEL});
|
||||||
if (m_formatter->has(TAG_LABEL)) {
|
if (m_formatter->has(TAG_LABEL)) {
|
||||||
m_label = load_optional_label(m_conf, name(), "label", "%output%");
|
m_label = load_optional_label(m_conf, name(), TAG_LABEL, "%output%");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_formatter->add_optional(FORMAT_FAIL, {TAG_LABEL_FAIL});
|
||||||
|
if (m_formatter->has(TAG_LABEL_FAIL)) {
|
||||||
|
m_label_fail = load_optional_label(m_conf, name(), TAG_LABEL_FAIL, "%output%");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +75,13 @@ namespace modules {
|
|||||||
/**
|
/**
|
||||||
* Generate module output
|
* Generate module output
|
||||||
*/
|
*/
|
||||||
|
string script_module::get_format() const {
|
||||||
|
if (m_runner.get_exit_status() != 0 && m_conf.has(name(), FORMAT_FAIL)) {
|
||||||
|
return FORMAT_FAIL;
|
||||||
|
}
|
||||||
|
return DEFAULT_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
string script_module::get_output() {
|
string script_module::get_output() {
|
||||||
auto script_output = m_runner.get_output();
|
auto script_output = m_runner.get_output();
|
||||||
if (script_output.empty()) {
|
if (script_output.empty()) {
|
||||||
@ -81,6 +93,11 @@ namespace modules {
|
|||||||
m_label->replace_token("%output%", script_output);
|
m_label->replace_token("%output%", script_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_label_fail) {
|
||||||
|
m_label_fail->reset_tokens();
|
||||||
|
m_label_fail->replace_token("%output%", script_output);
|
||||||
|
}
|
||||||
|
|
||||||
string cnt{to_string(m_runner.get_counter())};
|
string cnt{to_string(m_runner.get_counter())};
|
||||||
string output{module::get_output()};
|
string output{module::get_output()};
|
||||||
|
|
||||||
@ -114,6 +131,8 @@ namespace modules {
|
|||||||
bool script_module::build(builder* builder, const string& tag) const {
|
bool script_module::build(builder* builder, const string& tag) const {
|
||||||
if (tag == TAG_LABEL) {
|
if (tag == TAG_LABEL) {
|
||||||
builder->node(m_label);
|
builder->node(m_label);
|
||||||
|
} else if (tag == TAG_LABEL_FAIL) {
|
||||||
|
builder->node(m_label_fail);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user