mirror of
https://github.com/zoriya/astal.git
synced 2026-06-02 02:05:09 +00:00
feat: async Process.exec
the exec_async function was not truly async but a signal based one
This commit is contained in:
+22
-7
@@ -1,4 +1,4 @@
|
||||
import { Astal, GLib } from "./imports.js"
|
||||
import { Astal } from "./imports.js"
|
||||
|
||||
type Args<Out = void, Err = void> = {
|
||||
cmd: string | string[]
|
||||
@@ -24,7 +24,7 @@ export function subprocess(
|
||||
export function subprocess(
|
||||
argsOrCmd: Args | string | string[],
|
||||
onOut: (stdout: string) => void = print,
|
||||
onErr: (stderr: string) => void = console.log,
|
||||
onErr: (stderr: string) => void = printerr,
|
||||
) {
|
||||
const { cmd, err, out } = args(argsOrCmd, onOut, onErr)
|
||||
const proc = Array.isArray(cmd)
|
||||
@@ -44,11 +44,26 @@ export function exec(cmd: string | string[]) {
|
||||
}
|
||||
|
||||
export function execAsync(cmd: string | string[]): Promise<string> {
|
||||
const proc = Array.isArray(cmd)
|
||||
? Astal.Process.exec_asyncv(cmd)
|
||||
: Astal.Process.exec_async(cmd)
|
||||
return new Promise((resolve, reject) => {
|
||||
proc.connect("stdout", (_, out: string) => resolve(out))
|
||||
proc.connect("stderr", (_, err: string) => reject(err))
|
||||
if (Array.isArray(cmd)) {
|
||||
Astal.Process.exec_asyncv(cmd, (_, res) => {
|
||||
try {
|
||||
resolve(Astal.Process.exec_asyncv_finish(res))
|
||||
}
|
||||
catch (error) {
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
Astal.Process.exec_async(cmd, (_, res) => {
|
||||
try {
|
||||
resolve(Astal.Process.exec_finish(res))
|
||||
}
|
||||
catch (error) {
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+16
-15
@@ -68,26 +68,27 @@ end
|
||||
---@param commandline string | string[]
|
||||
---@param on_stdout? fun(out: string): nil
|
||||
---@param on_stderr? fun(err: string): nil
|
||||
---@return { kill: function } | nil proc
|
||||
function M.exec_async(commandline, on_stdout, on_stderr)
|
||||
local out, err = defualt_proc_args(on_stdout, on_stderr)
|
||||
local proc, fail
|
||||
if type(commandline) == "table" then
|
||||
proc, fail = Astal.Process.exec_asyncv(commandline)
|
||||
Astal.Process.exec_asyncv(commandline, function(_, res)
|
||||
local stdout, fail = Astal.exec_asyncv_finish(res)
|
||||
if fail ~= nil then
|
||||
err(fail)
|
||||
else
|
||||
out(stdout)
|
||||
end
|
||||
end)
|
||||
else
|
||||
proc, fail = Astal.Process.exec_async(commandline)
|
||||
Astal.Process.exec_async(commandline, function(_, res)
|
||||
local stdout, fail = Astal.exec_finish(res)
|
||||
if fail ~= nil then
|
||||
err(fail)
|
||||
else
|
||||
out(stdout)
|
||||
end
|
||||
end)
|
||||
end
|
||||
if fail ~= nil then
|
||||
err(fail)
|
||||
return nil
|
||||
end
|
||||
proc.on_stdout = function(_, str)
|
||||
out(str)
|
||||
end
|
||||
proc.on_stderr = function(_, str)
|
||||
err(str)
|
||||
end
|
||||
return proc
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
+13
-19
@@ -94,32 +94,26 @@ public class Astal.Process : Object {
|
||||
return Process.execv(argv);
|
||||
}
|
||||
|
||||
public Process.exec_asyncv(string[] cmd) throws Error {
|
||||
Object(argv: cmd);
|
||||
process = new Subprocess.newv(cmd,
|
||||
public static async string exec_asyncv(string[] cmd) throws Error {
|
||||
var process = new Subprocess.newv(
|
||||
cmd,
|
||||
SubprocessFlags.STDERR_PIPE |
|
||||
SubprocessFlags.STDOUT_PIPE
|
||||
);
|
||||
|
||||
process.communicate_utf8_async.begin(null, null, (_, res) => {
|
||||
string err_str, out_str;
|
||||
try {
|
||||
process.communicate_utf8_async.end(res, out out_str, out err_str);
|
||||
if (process.get_successful())
|
||||
stdout(out_str.strip());
|
||||
else
|
||||
stderr(err_str.strip());
|
||||
} catch (Error err) {
|
||||
printerr("%s\n", err.message);
|
||||
} finally {
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
string err_str, out_str;
|
||||
yield process.communicate_utf8_async(null, null, out out_str, out err_str);
|
||||
var success = process.get_successful();
|
||||
process.dispose();
|
||||
if (success)
|
||||
return out_str.strip();
|
||||
else
|
||||
throw new IOError.FAILED(err_str.strip());
|
||||
}
|
||||
|
||||
public static Process exec_async(string cmd) throws Error {
|
||||
public static async string exec_async(string cmd) throws Error {
|
||||
string[] argv;
|
||||
Shell.parse_argv(cmd, out argv);
|
||||
return new Process.exec_asyncv(argv);
|
||||
return yield exec_asyncv(argv);
|
||||
}
|
||||
}
|
||||
|
||||
+17
-11
@@ -141,20 +141,26 @@ public class Variable : VariableBase {
|
||||
}, Priority.DEFAULT);
|
||||
}
|
||||
if (poll_exec != null) {
|
||||
var proc = new Process.exec_asyncv(poll_exec);
|
||||
proc.stdout.connect((str) => set_closure(str, poll_transform));
|
||||
proc.stderr.connect((str) => this.error(str));
|
||||
poll_id = Timeout.add(poll_interval, () => {
|
||||
Process.exec_asyncv.begin(poll_exec, (_, res) => {
|
||||
try {
|
||||
proc = new Process.exec_asyncv(poll_exec);
|
||||
proc.stdout.connect((str) => set_closure(str, poll_transform));
|
||||
proc.stderr.connect((str) => this.error(str));
|
||||
return Source.CONTINUE;
|
||||
var str = Process.exec_asyncv.end(res);
|
||||
set_closure(str, poll_transform);
|
||||
} catch (Error err) {
|
||||
printerr("%s\n", err.message);
|
||||
poll_id = 0;
|
||||
return Source.REMOVE;
|
||||
this.error(err.message);
|
||||
}
|
||||
});
|
||||
poll_id = Timeout.add(poll_interval, () => {
|
||||
Process.exec_asyncv.begin(poll_exec, (_, res) => {
|
||||
try {
|
||||
var str = Process.exec_asyncv.end(res);
|
||||
set_closure(str, poll_transform);
|
||||
} catch (Error err) {
|
||||
this.error(err.message);
|
||||
Source.remove(poll_id);
|
||||
poll_id = 0;
|
||||
}
|
||||
});
|
||||
return Source.CONTINUE;
|
||||
}, Priority.DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user