Bring scripts to shell sessions

This commit is contained in:
crschnick 2023-10-22 10:09:08 +00:00
parent 1bc650d7ac
commit d87f74fffc
5 changed files with 90 additions and 8 deletions

View file

@ -62,6 +62,8 @@ public interface ShellDialect {
String prepareProperTerminalCommands();
String appendToPathVariableCommand(String entry);
default String applyRcFileCommand() {
return null;
}

View file

@ -27,12 +27,20 @@ public class ScriptGroupStoreProvider implements DataStoreProvider {
@Override
public Comp<?> customEntryComp(StoreSection sec, boolean preferLarge) {
ScriptGroupStore s = sec.getWrapper().getEntry().getStore().asNeeded();
var def = new StoreToggleComp("base.isDefaultGroup", sec, s.getState().isDefault(), aBoolean -> {
var state = s.getState();
state.setDefault(aBoolean);
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);
}

View file

@ -6,8 +6,10 @@ import io.xpipe.app.util.Validators;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.store.DataStore;
import io.xpipe.core.store.DataStoreState;
import io.xpipe.core.store.FileNames;
import io.xpipe.core.store.StatefulDataStore;
import io.xpipe.core.util.JacksonizedValue;
import io.xpipe.core.util.XPipeInstallation;
import lombok.*;
import lombok.experimental.FieldDefaults;
import lombok.experimental.SuperBuilder;
@ -15,6 +17,7 @@ import lombok.extern.jackson.Jacksonized;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
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 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 -> {
var flattened = flatten(refs);
var scripts = flattened.stream()
var initFlattened = flatten(initScripts);
var scripts = initFlattened.stream()
.map(simpleScriptStore -> simpleScriptStore.prepareDumbScript(shellControl))
.filter(Objects::nonNull)
.collect(Collectors.joining("\n"));
@ -38,7 +41,7 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore,
shellControl.executeSimpleBooleanCommand(scripts);
}
var terminalCommands = flattened.stream()
var terminalCommands = initFlattened.stream()
.map(simpleScriptStore -> simpleScriptStore.prepareTerminalScript(shellControl))
.filter(Objects::nonNull)
.collect(Collectors.joining("\n"));
@ -46,10 +49,55 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore,
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;
}
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()
.filter(dataStoreEntry -> dataStoreEntry.getStore() instanceof ScriptStore scriptStore
&& scriptStore.getState().isDefault())
@ -57,6 +105,14 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore,
.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) {
var seen = new LinkedHashSet<SimpleScriptStore>();
scripts.forEach(scriptStoreDataStoreEntryRef ->
@ -78,6 +134,7 @@ public abstract class ScriptStore extends JacksonizedValue implements DataStore,
@Jacksonized
public static class State extends DataStoreState {
boolean isDefault;
boolean bringToShell;
}
@Override

View file

@ -44,18 +44,32 @@ public class SimpleScriptStoreProvider implements DataStoreProvider {
public Comp<?> customEntryComp(StoreSection sec, boolean preferLarge) {
SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded();
var groupWrapper = StoreViewState.get().getEntryWrapper(s.getGroup().getEntry());
var def = new StoreToggleComp("base.isDefault", sec, s.getState().isDefault(), aBoolean -> {
var state = s.getState();
state.setDefault(aBoolean);
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
def.disable(BindingsHelper.map(groupWrapper.getPersistentState(), o -> {
ScriptStore.State state = (ScriptStore.State) o;
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);
}

View file

@ -73,6 +73,7 @@ snippets=Script dependencies
snippetsDescription=Other scripts to run first
snippetsDependenciesDescription=All possible scripts that should be run if applicable
isDefault=Enable in all compatible shells
bringToShells=Bring to all compatible shells
isDefaultGroup=Enable all group scripts
executionType=Execution type
executionTypeDescription=When to run this snippet