mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-01 17:47:30 +13:00
Bring scripts to shell sessions
This commit is contained in:
parent
1bc650d7ac
commit
d87f74fffc
5 changed files with 90 additions and 8 deletions
|
@ -62,6 +62,8 @@ public interface ShellDialect {
|
||||||
|
|
||||||
String prepareProperTerminalCommands();
|
String prepareProperTerminalCommands();
|
||||||
|
|
||||||
|
String appendToPathVariableCommand(String entry);
|
||||||
|
|
||||||
default String applyRcFileCommand() {
|
default String applyRcFileCommand() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,20 @@ public class ScriptGroupStoreProvider implements DataStoreProvider {
|
||||||
@Override
|
@Override
|
||||||
public Comp<?> customEntryComp(StoreSection sec, boolean preferLarge) {
|
public Comp<?> customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||||
ScriptGroupStore s = sec.getWrapper().getEntry().getStore().asNeeded();
|
ScriptGroupStore s = sec.getWrapper().getEntry().getStore().asNeeded();
|
||||||
|
|
||||||
var def = new StoreToggleComp("base.isDefaultGroup", sec, s.getState().isDefault(), aBoolean -> {
|
var def = new StoreToggleComp("base.isDefaultGroup", sec, s.getState().isDefault(), aBoolean -> {
|
||||||
var state = s.getState();
|
var state = s.getState();
|
||||||
state.setDefault(aBoolean);
|
state.setDefault(aBoolean);
|
||||||
s.setState(state);
|
s.setState(state);
|
||||||
});
|
});
|
||||||
var dropdown = new DropdownComp(List.of(def));
|
|
||||||
|
var bring = new StoreToggleComp("base.bringToShells", sec, s.getState().isBringToShell(), aBoolean -> {
|
||||||
|
var state = s.getState();
|
||||||
|
state.setBringToShell(aBoolean);
|
||||||
|
s.setState(state);
|
||||||
|
});
|
||||||
|
|
||||||
|
var dropdown = new DropdownComp(List.of(def, bring));
|
||||||
return new DenseStoreEntryComp(sec.getWrapper(), true, dropdown);
|
return new DenseStoreEntryComp(sec.getWrapper(), true, dropdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,10 @@ import io.xpipe.app.util.Validators;
|
||||||
import io.xpipe.core.process.ShellControl;
|
import io.xpipe.core.process.ShellControl;
|
||||||
import io.xpipe.core.store.DataStore;
|
import io.xpipe.core.store.DataStore;
|
||||||
import io.xpipe.core.store.DataStoreState;
|
import io.xpipe.core.store.DataStoreState;
|
||||||
|
import io.xpipe.core.store.FileNames;
|
||||||
import io.xpipe.core.store.StatefulDataStore;
|
import io.xpipe.core.store.StatefulDataStore;
|
||||||
import io.xpipe.core.util.JacksonizedValue;
|
import io.xpipe.core.util.JacksonizedValue;
|
||||||
|
import io.xpipe.core.util.XPipeInstallation;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.FieldDefaults;
|
import lombok.experimental.FieldDefaults;
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
|
@ -15,6 +17,7 @@ import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -24,13 +27,13 @@ import java.util.stream.Collectors;
|
||||||
public abstract class ScriptStore extends JacksonizedValue implements DataStore, StatefulDataStore<ScriptStore.State> {
|
public abstract class ScriptStore extends JacksonizedValue implements DataStore, StatefulDataStore<ScriptStore.State> {
|
||||||
|
|
||||||
public static ShellControl controlWithDefaultScripts(ShellControl pc) {
|
public static ShellControl controlWithDefaultScripts(ShellControl pc) {
|
||||||
return controlWithScripts(pc, getDefaultScripts());
|
return controlWithScripts(pc, getDefaultInitScripts(), getDefaultBringScripts());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ShellControl controlWithScripts(ShellControl pc, List<DataStoreEntryRef<ScriptStore>> refs) {
|
public static ShellControl controlWithScripts(ShellControl pc, List<DataStoreEntryRef<ScriptStore>> initScripts, List<DataStoreEntryRef<ScriptStore>> bringScripts) {
|
||||||
pc.onInit(shellControl -> {
|
pc.onInit(shellControl -> {
|
||||||
var flattened = flatten(refs);
|
var initFlattened = flatten(initScripts);
|
||||||
var scripts = flattened.stream()
|
var scripts = initFlattened.stream()
|
||||||
.map(simpleScriptStore -> simpleScriptStore.prepareDumbScript(shellControl))
|
.map(simpleScriptStore -> simpleScriptStore.prepareDumbScript(shellControl))
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
|
@ -38,7 +41,7 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore,
|
||||||
shellControl.executeSimpleBooleanCommand(scripts);
|
shellControl.executeSimpleBooleanCommand(scripts);
|
||||||
}
|
}
|
||||||
|
|
||||||
var terminalCommands = flattened.stream()
|
var terminalCommands = initFlattened.stream()
|
||||||
.map(simpleScriptStore -> simpleScriptStore.prepareTerminalScript(shellControl))
|
.map(simpleScriptStore -> simpleScriptStore.prepareTerminalScript(shellControl))
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
|
@ -46,10 +49,55 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore,
|
||||||
shellControl.initWithTerminal(terminalCommands);
|
shellControl.initWithTerminal(terminalCommands);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
pc.onInit(shellControl -> {
|
||||||
|
var bringFlattened = flatten(bringScripts);
|
||||||
|
var dir = initScriptsDirectory(shellControl, bringFlattened);
|
||||||
|
if (dir != null) {
|
||||||
|
shellControl.initWithTerminal(shellControl.getShellDialect().appendToPathVariableCommand(dir));
|
||||||
|
}
|
||||||
|
});
|
||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<DataStoreEntryRef<ScriptStore>> getDefaultScripts() {
|
private static String initScriptsDirectory(ShellControl proc, List<SimpleScriptStore> scriptStores) throws Exception {
|
||||||
|
if (scriptStores.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var refs = scriptStores.stream().map(scriptStore -> {
|
||||||
|
return DataStorage.get().getStoreEntries().stream().filter(dataStoreEntry -> dataStoreEntry.getStore() == scriptStore).findFirst().orElseThrow().<SimpleScriptStore>ref();
|
||||||
|
}).toList();
|
||||||
|
var hash = refs.stream().mapToInt(value -> value.get().getName().hashCode() + value.getStore().hashCode()).sum();
|
||||||
|
var xpipeHome = XPipeInstallation.getDataDir(proc);
|
||||||
|
var targetDir = FileNames.join(xpipeHome, "scripts");
|
||||||
|
var hashFile = FileNames.join(targetDir, "hash");
|
||||||
|
var d = proc.getShellDialect();
|
||||||
|
if (d.createFileExistsCommand(proc, hashFile).executeAndCheck()) {
|
||||||
|
var read = d.getFileReadCommand(proc, hashFile).readStdoutOrThrow();
|
||||||
|
var readHash = Integer.parseInt(read);
|
||||||
|
if (hash == readHash) {
|
||||||
|
return targetDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.deleteFileOrDirectory(proc, targetDir).execute();
|
||||||
|
proc.executeSimpleCommand(d.getMkdirsCommand(targetDir));
|
||||||
|
|
||||||
|
for (DataStoreEntryRef<SimpleScriptStore> scriptStore : refs) {
|
||||||
|
var content = d.prepareScriptContent(scriptStore.getStore().getCommands());
|
||||||
|
var fileName = scriptStore.get().getName().toLowerCase(Locale.ROOT).replaceAll(" ", "_");
|
||||||
|
var scriptFile = FileNames.join(targetDir, fileName + "." + d.getScriptFileEnding());
|
||||||
|
d.createScriptTextFileWriteCommand(proc, content, scriptFile).execute();
|
||||||
|
|
||||||
|
var chmod = d.getScriptPermissionsCommand(scriptFile);
|
||||||
|
proc.executeSimpleBooleanCommand(chmod);
|
||||||
|
}
|
||||||
|
|
||||||
|
d.createTextFileWriteCommand(proc, String.valueOf(hash), hashFile).execute();
|
||||||
|
return targetDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<DataStoreEntryRef<ScriptStore>> getDefaultInitScripts() {
|
||||||
return DataStorage.get().getStoreEntries().stream()
|
return DataStorage.get().getStoreEntries().stream()
|
||||||
.filter(dataStoreEntry -> dataStoreEntry.getStore() instanceof ScriptStore scriptStore
|
.filter(dataStoreEntry -> dataStoreEntry.getStore() instanceof ScriptStore scriptStore
|
||||||
&& scriptStore.getState().isDefault())
|
&& scriptStore.getState().isDefault())
|
||||||
|
@ -57,6 +105,14 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore,
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<DataStoreEntryRef<ScriptStore>> getDefaultBringScripts() {
|
||||||
|
return DataStorage.get().getStoreEntries().stream()
|
||||||
|
.filter(dataStoreEntry -> dataStoreEntry.getStore() instanceof ScriptStore scriptStore
|
||||||
|
&& scriptStore.getState().isBringToShell())
|
||||||
|
.map(e -> e.<ScriptStore>ref())
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
public static List<SimpleScriptStore> flatten(List<DataStoreEntryRef<ScriptStore>> scripts) {
|
public static List<SimpleScriptStore> flatten(List<DataStoreEntryRef<ScriptStore>> scripts) {
|
||||||
var seen = new LinkedHashSet<SimpleScriptStore>();
|
var seen = new LinkedHashSet<SimpleScriptStore>();
|
||||||
scripts.forEach(scriptStoreDataStoreEntryRef ->
|
scripts.forEach(scriptStoreDataStoreEntryRef ->
|
||||||
|
@ -78,6 +134,7 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore,
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
public static class State extends DataStoreState {
|
public static class State extends DataStoreState {
|
||||||
boolean isDefault;
|
boolean isDefault;
|
||||||
|
boolean bringToShell;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -44,18 +44,32 @@ public class SimpleScriptStoreProvider implements DataStoreProvider {
|
||||||
public Comp<?> customEntryComp(StoreSection sec, boolean preferLarge) {
|
public Comp<?> customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||||
SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded();
|
SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded();
|
||||||
var groupWrapper = StoreViewState.get().getEntryWrapper(s.getGroup().getEntry());
|
var groupWrapper = StoreViewState.get().getEntryWrapper(s.getGroup().getEntry());
|
||||||
|
|
||||||
var def = new StoreToggleComp("base.isDefault", sec, s.getState().isDefault(), aBoolean -> {
|
var def = new StoreToggleComp("base.isDefault", sec, s.getState().isDefault(), aBoolean -> {
|
||||||
var state = s.getState();
|
var state = s.getState();
|
||||||
state.setDefault(aBoolean);
|
state.setDefault(aBoolean);
|
||||||
s.setState(state);
|
s.setState(state);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var bring = new StoreToggleComp("base.bringToShells", sec, s.getState().isBringToShell(), aBoolean -> {
|
||||||
|
var state = s.getState();
|
||||||
|
state.setBringToShell(aBoolean);
|
||||||
|
s.setState(state);
|
||||||
|
});
|
||||||
|
|
||||||
// Disable selection if parent group is already made default
|
// Disable selection if parent group is already made default
|
||||||
def.disable(BindingsHelper.map(groupWrapper.getPersistentState(), o -> {
|
def.disable(BindingsHelper.map(groupWrapper.getPersistentState(), o -> {
|
||||||
ScriptStore.State state = (ScriptStore.State) o;
|
ScriptStore.State state = (ScriptStore.State) o;
|
||||||
return state.isDefault();
|
return state.isDefault();
|
||||||
}));
|
}));
|
||||||
var dropdown = new DropdownComp(List.of(def));
|
|
||||||
|
// Disable selection if parent group is already brings
|
||||||
|
bring.disable(BindingsHelper.map(groupWrapper.getPersistentState(), o -> {
|
||||||
|
ScriptStore.State state = (ScriptStore.State) o;
|
||||||
|
return state.isBringToShell();
|
||||||
|
}));
|
||||||
|
|
||||||
|
var dropdown = new DropdownComp(List.of(def, bring));
|
||||||
return new DenseStoreEntryComp(sec.getWrapper(), true, dropdown);
|
return new DenseStoreEntryComp(sec.getWrapper(), true, dropdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ snippets=Script dependencies
|
||||||
snippetsDescription=Other scripts to run first
|
snippetsDescription=Other scripts to run first
|
||||||
snippetsDependenciesDescription=All possible scripts that should be run if applicable
|
snippetsDependenciesDescription=All possible scripts that should be run if applicable
|
||||||
isDefault=Enable in all compatible shells
|
isDefault=Enable in all compatible shells
|
||||||
|
bringToShells=Bring to all compatible shells
|
||||||
isDefaultGroup=Enable all group scripts
|
isDefaultGroup=Enable all group scripts
|
||||||
executionType=Execution type
|
executionType=Execution type
|
||||||
executionTypeDescription=When to run this snippet
|
executionTypeDescription=When to run this snippet
|
||||||
|
|
Loading…
Reference in a new issue