Rework
@@ -43,6 +43,20 @@ public class IntegratedTextAreaComp extends Comp<IntegratedTextAreaComp.Structur
|
||||
|
||||
public static IntegratedTextAreaComp script(
|
||||
ObservableValue<DataStoreEntryRef<ShellStore>> host, Property<ShellScript> value) {
|
||||
var type = Bindings.createStringBinding(
|
||||
() -> {
|
||||
return host.getValue() != null
|
||||
&& host.getValue().getStore() instanceof StatefulDataStore<?> sd
|
||||
&& sd.getState() instanceof SystemState ss
|
||||
&& ss.getShellDialect() != null
|
||||
? ss.getShellDialect().getScriptFileEnding()
|
||||
: "sh";
|
||||
},
|
||||
host);
|
||||
return script(value, type);
|
||||
}
|
||||
|
||||
public static IntegratedTextAreaComp script(Property<ShellScript> value, ObservableValue<String> fileType) {
|
||||
var string = new SimpleStringProperty();
|
||||
value.subscribe(shellScript -> {
|
||||
string.set(shellScript != null ? shellScript.getValue() : null);
|
||||
@@ -54,16 +68,7 @@ public class IntegratedTextAreaComp extends Comp<IntegratedTextAreaComp.Structur
|
||||
string,
|
||||
false,
|
||||
"script",
|
||||
Bindings.createStringBinding(
|
||||
() -> {
|
||||
return host.getValue() != null
|
||||
&& host.getValue().getStore() instanceof StatefulDataStore<?> sd
|
||||
&& sd.getState() instanceof SystemState ss
|
||||
&& ss.getShellDialect() != null
|
||||
? ss.getShellDialect().getScriptFileEnding()
|
||||
: "sh";
|
||||
},
|
||||
host));
|
||||
fileType);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ public class AppImages {
|
||||
var exts = AppExtensionManager.getInstance().getContentModules();
|
||||
for (Module ext : exts) {
|
||||
AppResources.with(ext.getName(), "img/", basePath -> {
|
||||
if (!Files.exists(basePath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var skipLarge = AppDisplayScale.hasDefaultDisplayScale();
|
||||
Files.walkFileTree(basePath, new SimpleFileVisitor<>() {
|
||||
@Override
|
||||
|
||||
@@ -23,6 +23,15 @@ public class ShellScript {
|
||||
return new ShellScript(lines.stream().collect(Collectors.joining("\n")));
|
||||
}
|
||||
|
||||
public String withoutShebang() {
|
||||
var shebang = value.startsWith("#!");
|
||||
if (shebang) {
|
||||
return value.lines().skip(1).collect(Collectors.joining("\n"));
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
|
||||
@@ -2,7 +2,9 @@ package io.xpipe.ext.base.script;
|
||||
|
||||
import io.xpipe.app.core.AppNames;
|
||||
import io.xpipe.app.core.AppResources;
|
||||
import io.xpipe.app.process.ShellDialect;
|
||||
import io.xpipe.app.process.ShellDialects;
|
||||
import io.xpipe.app.process.ShellScript;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
|
||||
import lombok.Getter;
|
||||
@@ -18,34 +20,29 @@ import java.util.function.Supplier;
|
||||
public enum PredefinedScriptStore {
|
||||
APT_UPDATE("Apt upgrade", () -> SimpleScriptStore.builder()
|
||||
.group(PredefinedScriptGroup.MANAGEMENT.getEntry())
|
||||
.minimumDialect(ShellDialects.SH)
|
||||
.commands(file(("apt_upgrade.sh")))
|
||||
.textSource(ScriptTextSource.InPlace.builder().dialect(ShellDialects.SH).text(file("apt_upgrade.sh")).build())
|
||||
.shellScript(true)
|
||||
.runnableScript(true)
|
||||
.build()),
|
||||
REMOVE_CR("CRLF to LF", () -> SimpleScriptStore.builder()
|
||||
.group(PredefinedScriptGroup.FILES.getEntry())
|
||||
.minimumDialect(ShellDialects.SH)
|
||||
.commands(file(("crlf_to_lf.sh")))
|
||||
.textSource(ScriptTextSource.InPlace.builder().dialect(ShellDialects.SH).text(file("crlf_to_lf.sh")).build())
|
||||
.fileScript(true)
|
||||
.shellScript(true)
|
||||
.build()),
|
||||
DIFF("Diff", () -> SimpleScriptStore.builder()
|
||||
.group(PredefinedScriptGroup.FILES.getEntry())
|
||||
.minimumDialect(ShellDialects.SH)
|
||||
.commands(file(("diff.sh")))
|
||||
.textSource(ScriptTextSource.InPlace.builder().dialect(ShellDialects.SH).text(file("diff.sh")).build())
|
||||
.fileScript(true)
|
||||
.build()),
|
||||
GIT_CONFIG("Git Config", () -> SimpleScriptStore.builder()
|
||||
.group(PredefinedScriptGroup.MANAGEMENT.getEntry())
|
||||
.minimumDialect(null)
|
||||
.commands(file(("git_config.sh")))
|
||||
.textSource(ScriptTextSource.InPlace.builder().text(file("git_config.sh")).build())
|
||||
.runnableScript(true)
|
||||
.build()),
|
||||
SYSTEM_HEALTH_STATUS("System health status", () -> SimpleScriptStore.builder()
|
||||
.group(PredefinedScriptGroup.MANAGEMENT.getEntry())
|
||||
.minimumDialect(ShellDialects.SH)
|
||||
.commands(file(("system_health.sh")))
|
||||
.textSource(ScriptTextSource.InPlace.builder().text(file("system_health.sh")).build())
|
||||
.initScript(true)
|
||||
.build());
|
||||
|
||||
@@ -62,11 +59,11 @@ public enum PredefinedScriptStore {
|
||||
this.uuid = UUID.nameUUIDFromBytes(name.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public static String file(String name) {
|
||||
public static ShellScript file(String name) {
|
||||
AtomicReference<String> string = new AtomicReference<>();
|
||||
AppResources.with(AppNames.extModuleName("base"), "scripts/" + name, var1 -> {
|
||||
string.set(Files.readString(var1));
|
||||
});
|
||||
return string.get();
|
||||
return ShellScript.of(string.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,9 @@ import io.xpipe.app.comp.base.ContextualFileReferenceChoiceComp;
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.ext.ShellDialectChoiceComp;
|
||||
import io.xpipe.app.ext.ValidationException;
|
||||
import io.xpipe.app.icon.SystemIconSource;
|
||||
import io.xpipe.app.issue.ErrorEventFactory;
|
||||
import io.xpipe.app.platform.OptionsBuilder;
|
||||
import io.xpipe.app.process.ShellDialects;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.util.Validators;
|
||||
import io.xpipe.core.FilePath;
|
||||
@@ -32,16 +29,16 @@ import java.util.List;
|
||||
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = ScriptSource.Directory.class),
|
||||
@JsonSubTypes.Type(value = ScriptSource.GitRepository.class)
|
||||
@JsonSubTypes.Type(value = ScriptCollectionSource.Directory.class),
|
||||
@JsonSubTypes.Type(value = ScriptCollectionSource.GitRepository.class)
|
||||
})
|
||||
public interface ScriptSource {
|
||||
public interface ScriptCollectionSource {
|
||||
|
||||
@JsonTypeName("directory")
|
||||
@Value
|
||||
@Jacksonized
|
||||
@Builder
|
||||
class Directory implements ScriptSource {
|
||||
class Directory implements ScriptCollectionSource {
|
||||
|
||||
Path path;
|
||||
|
||||
@@ -92,7 +89,7 @@ public interface ScriptSource {
|
||||
@Value
|
||||
@Jacksonized
|
||||
@Builder
|
||||
class GitRepository implements ScriptSource {
|
||||
class GitRepository implements ScriptCollectionSource {
|
||||
|
||||
String url;
|
||||
|
||||
@@ -157,16 +154,9 @@ public interface ScriptSource {
|
||||
|
||||
String toName();
|
||||
|
||||
default List<ScriptSourceEntry> listScripts() throws Exception {
|
||||
var availableDialects = List.of(
|
||||
ShellDialects.SH,
|
||||
ShellDialects.BASH,
|
||||
ShellDialects.ZSH,
|
||||
ShellDialects.FISH,
|
||||
ShellDialects.CMD,
|
||||
ShellDialects.POWERSHELL,
|
||||
ShellDialects.POWERSHELL_CORE);
|
||||
var l = new ArrayList<ScriptSourceEntry>();
|
||||
default List<ScriptCollectionSourceEntry> listScripts() throws Exception {
|
||||
var availableDialects = ScriptDialects.getSupported();
|
||||
var l = new ArrayList<ScriptCollectionSourceEntry>();
|
||||
Files.walkFileTree(getLocalPath(), new SimpleFileVisitor<>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
|
||||
@@ -178,9 +168,9 @@ public interface ScriptSource {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
var entry = ScriptSourceEntry.builder()
|
||||
var entry = ScriptCollectionSourceEntry.builder()
|
||||
.name(name)
|
||||
.source(ScriptSource.this)
|
||||
.source(ScriptCollectionSource.this)
|
||||
.dialect(dialect.get())
|
||||
.localFile(file)
|
||||
.build();
|
||||
@@ -1,24 +1,20 @@
|
||||
package io.xpipe.ext.base.script;
|
||||
|
||||
import io.xpipe.app.action.AbstractAction;
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.FileSystemStore;
|
||||
import io.xpipe.app.hub.action.HubLeafProvider;
|
||||
import io.xpipe.app.hub.action.StoreAction;
|
||||
import io.xpipe.app.platform.LabelGraphic;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.DesktopHelper;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
public class ScriptSourceBrowseActionProvider implements HubLeafProvider<ScriptSourceStore> {
|
||||
public class ScriptCollectionSourceBrowseActionProvider implements HubLeafProvider<ScriptCollectionSourceStore> {
|
||||
|
||||
@Override
|
||||
public AbstractAction createAction(DataStoreEntryRef<ScriptSourceStore> ref) {
|
||||
public AbstractAction createAction(DataStoreEntryRef<ScriptCollectionSourceStore> ref) {
|
||||
return Action.builder().ref(ref).build();
|
||||
}
|
||||
|
||||
@@ -28,28 +24,28 @@ public class ScriptSourceBrowseActionProvider implements HubLeafProvider<ScriptS
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(DataStoreEntryRef<ScriptSourceStore> store) {
|
||||
public ObservableValue<String> getName(DataStoreEntryRef<ScriptCollectionSourceStore> store) {
|
||||
return AppI18n.observable("browse");
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelGraphic getIcon(DataStoreEntryRef<ScriptSourceStore> store) {
|
||||
public LabelGraphic getIcon(DataStoreEntryRef<ScriptCollectionSourceStore> store) {
|
||||
return new LabelGraphic.IconGraphic("mdi2f-folder-search-outline");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<ScriptSourceStore> getApplicableClass() {
|
||||
return ScriptSourceStore.class;
|
||||
public Class<ScriptCollectionSourceStore> getApplicableClass() {
|
||||
return ScriptCollectionSourceStore.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "browseScriptSource";
|
||||
return "browseScriptCollectionSource";
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@SuperBuilder
|
||||
public static class Action extends StoreAction<ScriptSourceStore> {
|
||||
public static class Action extends StoreAction<ScriptCollectionSourceStore> {
|
||||
|
||||
@Override
|
||||
public void executeImpl() {
|
||||
@@ -10,10 +10,10 @@ import java.nio.file.Path;
|
||||
@Value
|
||||
@Builder
|
||||
@Jacksonized
|
||||
public class ScriptSourceEntry {
|
||||
public class ScriptCollectionSourceEntry {
|
||||
|
||||
String name;
|
||||
ShellDialect dialect;
|
||||
ScriptSource source;
|
||||
ScriptCollectionSource source;
|
||||
Path localFile;
|
||||
}
|
||||
@@ -1,20 +1,16 @@
|
||||
package io.xpipe.ext.base.script;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.FixedHierarchyStore;
|
||||
import io.xpipe.app.hub.action.BatchHubProvider;
|
||||
import io.xpipe.app.hub.action.HubLeafProvider;
|
||||
import io.xpipe.app.hub.action.StoreAction;
|
||||
import io.xpipe.app.hub.action.StoreActionCategory;
|
||||
import io.xpipe.app.platform.LabelGraphic;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.ext.base.service.FixedServiceGroupStore;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
public class ScriptSourceRefreshHubProvider implements HubLeafProvider<ScriptSourceStore> {
|
||||
public class ScriptCollectionSourceRefreshHubProvider implements HubLeafProvider<ScriptCollectionSourceStore> {
|
||||
|
||||
@Override
|
||||
public StoreActionCategory getCategory() {
|
||||
@@ -27,28 +23,28 @@ public class ScriptSourceRefreshHubProvider implements HubLeafProvider<ScriptSou
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(DataStoreEntryRef<ScriptSourceStore> store) {
|
||||
public ObservableValue<String> getName(DataStoreEntryRef<ScriptCollectionSourceStore> store) {
|
||||
return AppI18n.observable("refreshSource");
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelGraphic getIcon(DataStoreEntryRef<ScriptSourceStore> store) {
|
||||
public LabelGraphic getIcon(DataStoreEntryRef<ScriptCollectionSourceStore> store) {
|
||||
return new LabelGraphic.IconGraphic("mdi2r-refresh");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getApplicableClass() {
|
||||
return ScriptSourceStore.class;
|
||||
return ScriptCollectionSourceStore.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "refreshSource";
|
||||
return "refreshScriptCollection";
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@SuperBuilder
|
||||
public static class Action extends StoreAction<ScriptSourceStore> {
|
||||
public static class Action extends StoreAction<ScriptCollectionSourceStore> {
|
||||
|
||||
@Override
|
||||
public void executeImpl() throws Exception {
|
||||
@@ -1,17 +1,8 @@
|
||||
package io.xpipe.ext.base.script;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeId;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.ext.*;
|
||||
import io.xpipe.app.process.ShellStoreState;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.HostHelper;
|
||||
import io.xpipe.app.util.LicenseProvider;
|
||||
import io.xpipe.app.util.Validators;
|
||||
import io.xpipe.ext.base.host.HostAddressGatewayStore;
|
||||
import io.xpipe.ext.base.service.ServiceAddressRotation;
|
||||
import io.xpipe.ext.base.service.ServiceProtocolType;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
@@ -22,10 +13,10 @@ import java.util.List;
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@Value
|
||||
@Jacksonized
|
||||
@JsonTypeName("scriptSource")
|
||||
public class ScriptSourceStore implements DataStore, StatefulDataStore<ScriptSourceStore.State> {
|
||||
@JsonTypeName("scriptCollectionSource")
|
||||
public class ScriptCollectionSourceStore implements DataStore, StatefulDataStore<ScriptCollectionSourceStore.State> {
|
||||
|
||||
ScriptSource source;
|
||||
ScriptCollectionSource source;
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws Throwable {
|
||||
@@ -46,7 +37,7 @@ public class ScriptSourceStore implements DataStore, StatefulDataStore<ScriptSou
|
||||
@Jacksonized
|
||||
public static class State extends DataStoreState {
|
||||
|
||||
List<ScriptSourceEntry> entries;
|
||||
List<ScriptCollectionSourceEntry> entries;
|
||||
|
||||
@Override
|
||||
public DataStoreState mergeCopy(DataStoreState newer) {
|
||||
@@ -1,40 +1,24 @@
|
||||
package io.xpipe.ext.base.script;
|
||||
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.base.IntegratedTextAreaComp;
|
||||
import io.xpipe.app.comp.base.ListSelectorComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.*;
|
||||
import io.xpipe.app.hub.comp.*;
|
||||
import io.xpipe.app.platform.OptionsBuilder;
|
||||
import io.xpipe.app.platform.OptionsChoiceBuilder;
|
||||
import io.xpipe.app.platform.Validator;
|
||||
import io.xpipe.app.process.OsFileSystem;
|
||||
import io.xpipe.app.process.ShellDialect;
|
||||
import io.xpipe.app.process.ShellDialects;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreCategory;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.util.DataStoreFormatter;
|
||||
import io.xpipe.app.util.DocumentationLink;
|
||||
import io.xpipe.core.OsType;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleListProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ScriptSourceStoreProvider implements DataStoreProvider {
|
||||
public class ScriptCollectionSourceStoreProvider implements DataStoreProvider {
|
||||
|
||||
@Override
|
||||
public UUID getTargetCategory(DataStore store, UUID target) {
|
||||
@@ -69,18 +53,18 @@ public class ScriptSourceStoreProvider implements DataStoreProvider {
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public GuiDialog guiDialog(DataStoreEntry entry, Property<DataStore> store) {
|
||||
ScriptSourceStore st = store.getValue().asNeeded();
|
||||
ScriptCollectionSourceStore st = store.getValue().asNeeded();
|
||||
|
||||
var source = new SimpleObjectProperty<>(st.getSource());
|
||||
|
||||
var sourceChoice = OptionsChoiceBuilder.builder().property(source).available(ScriptSource.getClasses()).build();
|
||||
var sourceChoice = OptionsChoiceBuilder.builder().property(source).available(ScriptCollectionSource.getClasses()).build();
|
||||
|
||||
return new OptionsBuilder()
|
||||
.nameAndDescription("scriptSourceType")
|
||||
.nameAndDescription("scriptCollectionSourceType")
|
||||
.sub(sourceChoice.build(), source)
|
||||
.bind(
|
||||
() -> {
|
||||
return ScriptSourceStore.builder().source(source.get()).build();
|
||||
return ScriptCollectionSourceStore.builder().source(source.get()).build();
|
||||
},
|
||||
store)
|
||||
.buildDialog();
|
||||
@@ -88,13 +72,13 @@ public class ScriptSourceStoreProvider implements DataStoreProvider {
|
||||
|
||||
@Override
|
||||
public String summaryString(StoreEntryWrapper wrapper) {
|
||||
ScriptSourceStore st = wrapper.getEntry().getStore().asNeeded();
|
||||
ScriptCollectionSourceStore st = wrapper.getEntry().getStore().asNeeded();
|
||||
return st.getSource().toName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> informationString(StoreSection section) {
|
||||
ScriptSourceStore st = section.getWrapper().getEntry().getStore().asNeeded();
|
||||
ScriptCollectionSourceStore st = section.getWrapper().getEntry().getStore().asNeeded();
|
||||
return Bindings.createStringBinding(() -> {
|
||||
var s = st.getState();
|
||||
var summary = st.getSource().toSummary();
|
||||
@@ -104,16 +88,16 @@ public class ScriptSourceStoreProvider implements DataStoreProvider {
|
||||
|
||||
@Override
|
||||
public DataStore defaultStore(DataStoreCategory category) {
|
||||
return ScriptSourceStore.builder().build();
|
||||
return ScriptCollectionSourceStore.builder().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "scriptSource";
|
||||
return "scriptCollectionSource";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getStoreClasses() {
|
||||
return List.of(ScriptSourceStore.class);
|
||||
return List.of(ScriptCollectionSourceStore.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.xpipe.ext.base.script;
|
||||
|
||||
import io.xpipe.app.process.ShellDialect;
|
||||
import io.xpipe.app.process.ShellDialects;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ScriptDialects {
|
||||
|
||||
public static List<ShellDialect> getSupported() {
|
||||
var availableDialects = List.of(
|
||||
ShellDialects.SH,
|
||||
ShellDialects.BASH,
|
||||
ShellDialects.ZSH,
|
||||
ShellDialects.FISH,
|
||||
ShellDialects.CMD,
|
||||
ShellDialects.POWERSHELL,
|
||||
ShellDialects.POWERSHELL_CORE);
|
||||
return availableDialects;
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public class ScriptStoreSetup {
|
||||
pc.withInitSnippet(
|
||||
new ShellTerminalInitCommand() {
|
||||
|
||||
String dir;
|
||||
FilePath dir;
|
||||
|
||||
@Override
|
||||
public Optional<String> terminalContent(ShellControl shellControl) throws Exception {
|
||||
@@ -84,7 +84,7 @@ public class ScriptStoreSetup {
|
||||
}
|
||||
|
||||
return Optional.ofNullable(
|
||||
shellControl.getShellDialect().addToPathVariableCommand(List.of(dir), true));
|
||||
shellControl.getShellDialect().addToPathVariableCommand(List.of(dir.toString()), true));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,14 +102,14 @@ public class ScriptStoreSetup {
|
||||
}
|
||||
}
|
||||
|
||||
private static String initScriptsDirectory(ShellControl proc, List<DataStoreEntryRef<SimpleScriptStore>> refs)
|
||||
private static FilePath initScriptsDirectory(ShellControl sc, List<DataStoreEntryRef<SimpleScriptStore>> refs)
|
||||
throws Exception {
|
||||
if (refs.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var applicable = refs.stream()
|
||||
.filter(simpleScriptStore -> simpleScriptStore.getStore().isCompatible(proc.getShellDialect()))
|
||||
.filter(simpleScriptStore -> simpleScriptStore.getStore().isCompatible(sc.getShellDialect()))
|
||||
.toList();
|
||||
if (applicable.isEmpty()) {
|
||||
return null;
|
||||
@@ -119,13 +119,11 @@ public class ScriptStoreSetup {
|
||||
.mapToInt(value ->
|
||||
value.get().getName().hashCode() + value.getStore().hashCode())
|
||||
.sum();
|
||||
var targetDir = ShellTemp.createUserSpecificTempDataDirectory(proc, "scripts")
|
||||
.join(proc.getShellDialect().getId())
|
||||
.toString();
|
||||
var hashFile = FilePath.of(targetDir, "hash");
|
||||
var d = proc.getShellDialect();
|
||||
if (d.createFileExistsCommand(proc, hashFile.toString()).executeAndCheck()) {
|
||||
var read = d.getFileReadCommand(proc, hashFile.toString()).readStdoutOrThrow();
|
||||
var targetDir = ShellTemp.createUserSpecificTempDataDirectory(sc, "scripts")
|
||||
.join(sc.getShellDialect().getId());
|
||||
var hashFile = targetDir.join("hash");
|
||||
if (sc.view().fileExists(hashFile)) {
|
||||
var read = sc.view().readTextFile(hashFile);
|
||||
try {
|
||||
var readHash = Integer.parseInt(read);
|
||||
if (hash == readHash) {
|
||||
@@ -136,21 +134,23 @@ public class ScriptStoreSetup {
|
||||
}
|
||||
}
|
||||
|
||||
if (d.directoryExists(proc, targetDir).executeAndCheck()) {
|
||||
d.deleteFileOrDirectory(proc, targetDir).execute();
|
||||
if (sc.view().directoryExists(targetDir)) {
|
||||
sc.view().deleteDirectory(targetDir);
|
||||
}
|
||||
proc.executeSimpleCommand(d.getMkdirsCommand(targetDir));
|
||||
sc.view().mkdir(targetDir);
|
||||
|
||||
var d = sc.getShellDialect();
|
||||
for (DataStoreEntryRef<SimpleScriptStore> scriptStore : refs) {
|
||||
var content = d.prepareScriptContent(proc, scriptStore.getStore().getCommands());
|
||||
var fileName = OsFileSystem.of(proc.getOsType())
|
||||
var src = scriptStore.getStore().getTextSource();
|
||||
var content = src.getText();
|
||||
var fileName = OsFileSystem.of(sc.getOsType())
|
||||
.makeFileSystemCompatible(
|
||||
scriptStore.get().getName().toLowerCase(Locale.ROOT).replaceAll(" ", "_"));
|
||||
var scriptFile = FilePath.of(targetDir, fileName + "." + d.getScriptFileEnding());
|
||||
proc.view().writeScriptFile(scriptFile, content);
|
||||
var scriptFile = targetDir.join(fileName + "." + d.getScriptFileEnding());
|
||||
sc.view().writeScriptFile(scriptFile, content.getValue());
|
||||
}
|
||||
|
||||
proc.view().writeTextFile(hashFile, String.valueOf(hash));
|
||||
sc.view().writeTextFile(hashFile, String.valueOf(hash));
|
||||
return targetDir;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
package io.xpipe.ext.base.script;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.base.ContextualFileReferenceChoiceComp;
|
||||
import io.xpipe.app.comp.base.IntegratedTextAreaComp;
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.ext.ShellDialectChoiceComp;
|
||||
import io.xpipe.app.ext.ValidationException;
|
||||
import io.xpipe.app.issue.ErrorEventFactory;
|
||||
import io.xpipe.app.platform.OptionsBuilder;
|
||||
import io.xpipe.app.process.ShellDialect;
|
||||
import io.xpipe.app.process.ShellScript;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.util.DocumentationLink;
|
||||
import io.xpipe.app.util.HttpHelper;
|
||||
import io.xpipe.app.util.Validators;
|
||||
import io.xpipe.core.FilePath;
|
||||
import io.xpipe.core.UuidHelper;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import lombok.Builder;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = ScriptTextSource.InPlace.class),
|
||||
@JsonSubTypes.Type(value = ScriptTextSource.Url.class),
|
||||
@JsonSubTypes.Type(value = ScriptTextSource.SourceReference.class)
|
||||
})
|
||||
public interface ScriptTextSource {
|
||||
|
||||
@JsonTypeName("inPlace")
|
||||
@Value
|
||||
@Jacksonized
|
||||
@Builder
|
||||
class InPlace implements ScriptTextSource {
|
||||
|
||||
ShellDialect dialect;
|
||||
ShellScript text;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static String getOptionsNameKey() {
|
||||
return "scriptSourceTypeInPlace";
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static OptionsBuilder createOptions(Property<InPlace> property) {
|
||||
var dialect = new SimpleObjectProperty<>(property.getValue().getDialect());
|
||||
var text = new SimpleObjectProperty<>(property.getValue().getText());
|
||||
|
||||
var availableDialects = ScriptDialects.getSupported();
|
||||
var choice = new ShellDialectChoiceComp(availableDialects, dialect, ShellDialectChoiceComp.NullHandling.NULL_IS_ALL);
|
||||
|
||||
return new OptionsBuilder()
|
||||
.name("minimumShellDialect")
|
||||
.description("minimumShellDialectDescription")
|
||||
.documentationLink(DocumentationLink.SCRIPTING_COMPATIBILITY)
|
||||
.addComp(choice, dialect)
|
||||
.name("scriptContents")
|
||||
.description("scriptContentsDescription")
|
||||
.documentationLink(DocumentationLink.SCRIPTING_EDITING)
|
||||
.addComp(IntegratedTextAreaComp.script(text, Bindings.createStringBinding(() -> {
|
||||
return dialect.getValue() != null
|
||||
? dialect.getValue().getScriptFileEnding()
|
||||
: "sh";
|
||||
}, dialect)))
|
||||
.bind(() -> InPlace.builder().dialect(dialect.get()).text(text.get()).build(),
|
||||
property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws ValidationException {
|
||||
Validators.nonNull(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSummary() {
|
||||
return dialect.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
@JsonTypeName("url")
|
||||
@Value
|
||||
@Jacksonized
|
||||
@Builder
|
||||
class Url implements ScriptTextSource {
|
||||
|
||||
ShellDialect dialect;
|
||||
String url;
|
||||
ShellScript lastText;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static String getOptionsNameKey() {
|
||||
return "scriptSourceTypeUrl";
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static OptionsBuilder createOptions(Property<Url> property) {
|
||||
var dialect = new SimpleObjectProperty<>(property.getValue().getDialect());
|
||||
var url = new SimpleStringProperty(property.getValue().getUrl());
|
||||
|
||||
var availableDialects = ScriptDialects.getSupported();
|
||||
var choice = new ShellDialectChoiceComp(availableDialects, dialect, ShellDialectChoiceComp.NullHandling.NULL_IS_ALL);
|
||||
|
||||
return new OptionsBuilder()
|
||||
.name("minimumShellDialect")
|
||||
.description("minimumShellDialectDescription")
|
||||
.documentationLink(DocumentationLink.SCRIPTING_COMPATIBILITY)
|
||||
.addComp(choice, dialect)
|
||||
.nameAndDescription("scriptTextSourceUrl").addString(url).nonNull().bind(
|
||||
() -> Url.builder().dialect(dialect.get()).url(url.get()).build(), property);
|
||||
}
|
||||
|
||||
private void prepare() throws Exception {
|
||||
var path = getLocalPath();
|
||||
if (Files.exists(path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var req = HttpRequest.newBuilder().GET().uri(URI.create(url)).build();
|
||||
var r = HttpHelper.client().send(req, HttpResponse.BodyHandlers.ofString());
|
||||
if (r.statusCode() >= 400) {
|
||||
throw ErrorEventFactory.expected(new IOException(r.body()));
|
||||
}
|
||||
|
||||
Files.writeString(path, r.body());
|
||||
}
|
||||
|
||||
private Path getLocalPath() {
|
||||
return AppCache.getBasePath().resolve("scripts").resolve(getName());
|
||||
}
|
||||
|
||||
private String getName() {
|
||||
var name = FilePath.of(url).getFileName();
|
||||
if (!name.isEmpty()) {
|
||||
return name;
|
||||
}
|
||||
|
||||
return UuidHelper.generateFromObject(url).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws ValidationException {
|
||||
Validators.nonNull(url);
|
||||
Validators.nonNull(lastText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSummary() {
|
||||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public ShellScript getText() {
|
||||
return lastText;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonTypeName("source")
|
||||
@Value
|
||||
@Jacksonized
|
||||
@Builder
|
||||
class SourceReference implements ScriptTextSource {
|
||||
|
||||
ScriptCollectionSourceEntry entry;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static String getOptionsNameKey() {
|
||||
return "scriptSourceTypeSource";
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static OptionsBuilder createOptions(Property<SourceReference> property) {
|
||||
var entry = new SimpleObjectProperty<>(property.getValue().getEntry());
|
||||
|
||||
return new OptionsBuilder().bind(
|
||||
() -> SourceReference.builder().entry(entry.get()).build(), property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws ValidationException {
|
||||
Validators.nonNull(entry);
|
||||
entry.getSource().checkComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSummary() {
|
||||
return entry.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellDialect getDialect() {
|
||||
return entry.getDialect();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public ShellScript getText() {
|
||||
var r = Files.readString(entry.getLocalFile());
|
||||
return ShellScript.of(r);
|
||||
}
|
||||
}
|
||||
|
||||
void checkComplete() throws ValidationException;
|
||||
|
||||
String toSummary();
|
||||
|
||||
ShellDialect getDialect();
|
||||
|
||||
ShellScript getText();
|
||||
|
||||
static List<Class<?>> getClasses() {
|
||||
var l = new ArrayList<Class<?>>();
|
||||
l.add(InPlace.class);
|
||||
l.add(Url.class);
|
||||
l.add(SourceReference.class);
|
||||
return l;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package io.xpipe.ext.base.script;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer;
|
||||
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.databind.node.TextNode;
|
||||
import com.fasterxml.jackson.databind.node.TreeTraversingParser;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SimpleScriptMigrationDeserializer extends DelegatingDeserializer {
|
||||
|
||||
public SimpleScriptMigrationDeserializer(JsonDeserializer<?> d) {
|
||||
super(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonDeserializer<?> newDelegatingInstance(JsonDeserializer<?> newDelegatee) {
|
||||
return new SimpleScriptMigrationDeserializer(newDelegatee);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
return super.deserialize(restructure(p), ctxt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object deserialize(JsonParser p, DeserializationContext ctxt, Object intoValue) throws IOException {
|
||||
return super.deserialize(restructure(p), ctxt, intoValue);
|
||||
}
|
||||
|
||||
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer)
|
||||
throws IOException {
|
||||
return super.deserializeWithType(restructure(jp), ctxt, typeDeserializer);
|
||||
}
|
||||
|
||||
public JsonParser restructure(JsonParser p) throws IOException {
|
||||
var node = p.readValueAsTree();
|
||||
if (node == null || !node.isObject()) {
|
||||
return p;
|
||||
}
|
||||
|
||||
migrate((ObjectNode) node);
|
||||
var newJsonParser = new TreeTraversingParser(((ObjectNode) node), p.getCodec());
|
||||
newJsonParser.nextToken();
|
||||
return newJsonParser;
|
||||
}
|
||||
|
||||
private void migrate(ObjectNode n) {
|
||||
var commandsNode = n.remove("commands");
|
||||
var dialectNode = n.remove("minimumDialect");
|
||||
|
||||
var obj = JsonNodeFactory.instance.objectNode();
|
||||
obj.put("type", "inPlace");
|
||||
obj.put("text", commandsNode.textValue());
|
||||
if (!dialectNode.isNull()) {
|
||||
obj.put("dialect", dialectNode.textValue());
|
||||
} else {
|
||||
obj.putNull("dialect");
|
||||
}
|
||||
|
||||
n.set("textSource", obj);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import io.xpipe.app.hub.action.StoreActionCategory;
|
||||
import io.xpipe.app.hub.comp.StoreCreationDialog;
|
||||
import io.xpipe.app.platform.LabelGraphic;
|
||||
import io.xpipe.app.process.OsFileSystem;
|
||||
import io.xpipe.app.process.ShellScript;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.FileOpener;
|
||||
@@ -75,14 +76,20 @@ public class SimpleScriptQuickEditHubLeafProvider implements HubLeafProvider<Sim
|
||||
return;
|
||||
}
|
||||
|
||||
var inPlace = ref.getStore().getTextSource() instanceof ScriptTextSource.InPlace;
|
||||
if (!inPlace) {
|
||||
StoreCreationDialog.showEdit(ref.get());
|
||||
return;
|
||||
}
|
||||
|
||||
var script = ref.getStore();
|
||||
var dialect = script.getMinimumDialect();
|
||||
var ext = dialect != null ? dialect.getScriptFileEnding() : "sh";
|
||||
var name = OsFileSystem.ofLocal().makeFileSystemCompatible(ref.get().getName());
|
||||
FileOpener.openString(name + "." + ext, this, script.getCommands(), (s) -> {
|
||||
FileOpener.openString(name + "." + ext, this, script.getTextSource().getText().getValue(), (s) -> {
|
||||
DataStorage.get()
|
||||
.updateEntryStore(
|
||||
ref.get(), script.toBuilder().commands(s).build());
|
||||
ref.get(), script.toBuilder().textSource(ScriptTextSource.InPlace.builder().dialect(dialect).text(ShellScript.of(s)).build()).build());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,37 +29,30 @@ import java.util.stream.Collectors;
|
||||
@ToString(callSuper = true)
|
||||
public class SimpleScriptStore extends ScriptStore implements SelfReferentialStore {
|
||||
|
||||
ShellDialect minimumDialect;
|
||||
String commands;
|
||||
ScriptTextSource textSource;
|
||||
boolean initScript;
|
||||
boolean shellScript;
|
||||
boolean fileScript;
|
||||
boolean runnableScript;
|
||||
|
||||
public String getCommands() {
|
||||
return commands != null ? commands : "";
|
||||
public ShellDialect getMinimumDialect() {
|
||||
return textSource != null ? textSource.getDialect() : null;
|
||||
}
|
||||
|
||||
public boolean isCompatible(ShellControl shellControl) {
|
||||
var targetType = shellControl.getOriginalShellDialect();
|
||||
return minimumDialect == null || minimumDialect.isCompatibleTo(targetType);
|
||||
return getMinimumDialect() == null || getMinimumDialect().isCompatibleTo(targetType);
|
||||
}
|
||||
|
||||
public boolean isCompatible(ShellDialect dialect) {
|
||||
return minimumDialect == null || minimumDialect.isCompatibleTo(dialect);
|
||||
return getMinimumDialect() == null || getMinimumDialect().isCompatibleTo(dialect);
|
||||
}
|
||||
|
||||
private String assembleScript(ShellControl shellControl, boolean args) {
|
||||
if (isCompatible(shellControl)) {
|
||||
var shebang = getCommands().startsWith("#");
|
||||
// Fix new lines and shebang
|
||||
var fixedCommands = getCommands()
|
||||
.lines()
|
||||
.skip(shebang ? 1 : 0)
|
||||
.collect(Collectors.joining(
|
||||
shellControl.getShellDialect().getNewLine().getNewLineString()));
|
||||
var raw = getTextSource().getText().withoutShebang();
|
||||
var targetType = shellControl.getOriginalShellDialect();
|
||||
var script = ScriptHelper.createExecScript(targetType, shellControl, fixedCommands);
|
||||
var script = ScriptHelper.createExecScript(targetType, shellControl, raw);
|
||||
return targetType.sourceScriptCommand(shellControl, script.toString()) + (args ? " "
|
||||
+ targetType.getCatchAllVariable() : "");
|
||||
}
|
||||
@@ -82,6 +75,7 @@ public class SimpleScriptStore extends ScriptStore implements SelfReferentialSto
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws Throwable {
|
||||
Validators.nonNull(textSource);
|
||||
Validators.nonNull(group);
|
||||
super.checkComplete();
|
||||
if (!initScript && !shellScript && !fileScript && !runnableScript) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.*;
|
||||
import io.xpipe.app.hub.comp.*;
|
||||
import io.xpipe.app.platform.OptionsBuilder;
|
||||
import io.xpipe.app.platform.OptionsChoiceBuilder;
|
||||
import io.xpipe.app.platform.Validator;
|
||||
import io.xpipe.app.process.OsFileSystem;
|
||||
import io.xpipe.app.process.ShellDialect;
|
||||
@@ -75,22 +76,11 @@ public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, Da
|
||||
public GuiDialog guiDialog(DataStoreEntry entry, Property<DataStore> store) {
|
||||
SimpleScriptStore st = store.getValue().asNeeded();
|
||||
|
||||
var textSource = new SimpleObjectProperty<>(st.getTextSource());
|
||||
var group = new SimpleObjectProperty<>(st.getGroup());
|
||||
Property<ShellDialect> dialect = new SimpleObjectProperty<>(st.getMinimumDialect());
|
||||
var others =
|
||||
new SimpleListProperty<>(FXCollections.observableArrayList(new ArrayList<>(st.getEffectiveScripts())));
|
||||
Property<String> commandProp = new SimpleObjectProperty<>(st.getCommands());
|
||||
var others = new SimpleListProperty<>(FXCollections.observableArrayList(new ArrayList<>(st.getEffectiveScripts())));
|
||||
|
||||
var availableDialects = List.of(
|
||||
ShellDialects.SH,
|
||||
ShellDialects.BASH,
|
||||
ShellDialects.ZSH,
|
||||
ShellDialects.FISH,
|
||||
ShellDialects.CMD,
|
||||
ShellDialects.POWERSHELL,
|
||||
ShellDialects.POWERSHELL_CORE);
|
||||
Comp<?> choice =
|
||||
new ShellDialectChoiceComp(availableDialects, dialect, ShellDialectChoiceComp.NullHandling.NULL_IS_ALL);
|
||||
var textSourceChoice = OptionsChoiceBuilder.builder().property(textSource).available(ScriptTextSource.getClasses()).build();
|
||||
|
||||
var vals = List.of(0, 1, 2, 3);
|
||||
var selectedStart = new ArrayList<Integer>();
|
||||
@@ -134,20 +124,9 @@ public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, Da
|
||||
FXCollections.observableList(vals), name, selectedExecTypes, v -> false, () -> false);
|
||||
|
||||
return new OptionsBuilder()
|
||||
.name("minimumShellDialect")
|
||||
.description("minimumShellDialectDescription")
|
||||
.documentationLink(DocumentationLink.SCRIPTING_COMPATIBILITY)
|
||||
.addComp(choice, dialect)
|
||||
.name("scriptContents")
|
||||
.description("scriptContentsDescription")
|
||||
.documentationLink(DocumentationLink.SCRIPTING_EDITING)
|
||||
.addComp(
|
||||
new IntegratedTextAreaComp(commandProp, false, "commands", Bindings.createStringBinding(() -> {
|
||||
return dialect.getValue() != null
|
||||
? dialect.getValue().getScriptFileEnding()
|
||||
: "sh";
|
||||
})),
|
||||
commandProp)
|
||||
.nameAndDescription("scriptSourceType")
|
||||
.sub(textSourceChoice.build(), textSource)
|
||||
.nonNull()
|
||||
.nameAndDescription("executionType")
|
||||
.documentationLink(DocumentationLink.SCRIPTING_TYPES)
|
||||
.addComp(selectorComp, selectedExecTypes)
|
||||
@@ -178,11 +157,10 @@ public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, Da
|
||||
.bind(
|
||||
() -> {
|
||||
return SimpleScriptStore.builder()
|
||||
.textSource(textSource.get())
|
||||
.group(group.get())
|
||||
.minimumDialect(dialect.getValue())
|
||||
.scripts(new ArrayList<>(others.get()))
|
||||
.description(st.getDescription())
|
||||
.commands(commandProp.getValue())
|
||||
.initScript(selectedExecTypes.contains(0))
|
||||
.runnableScript(selectedExecTypes.contains(1))
|
||||
.fileScript(selectedExecTypes.contains(2))
|
||||
|
||||
@@ -42,9 +42,7 @@ open module io.xpipe.ext.base {
|
||||
RunBackgroundScriptActionProvider,
|
||||
RunHubBatchScriptActionProvider,
|
||||
RunHubScriptActionProvider,
|
||||
RunTerminalScriptActionProvider,
|
||||
ScriptSourceRefreshHubProvider,
|
||||
ScriptSourceBrowseActionProvider,
|
||||
RunTerminalScriptActionProvider, ScriptCollectionSourceRefreshHubProvider, ScriptCollectionSourceBrowseActionProvider,
|
||||
SimpleScriptQuickEditHubLeafProvider,
|
||||
StoreStartActionProvider,
|
||||
StoreStopActionProvider,
|
||||
@@ -60,8 +58,7 @@ open module io.xpipe.ext.base {
|
||||
CustomServiceStoreProvider,
|
||||
MappedServiceStoreProvider,
|
||||
FixedServiceStoreProvider,
|
||||
SimpleScriptStoreProvider,
|
||||
ScriptSourceStoreProvider,
|
||||
SimpleScriptStoreProvider, ScriptCollectionSourceStoreProvider,
|
||||
DesktopApplicationStoreProvider,
|
||||
LocalIdentityStoreProvider,
|
||||
SyncedIdentityStoreProvider,
|
||||
|
||||
|
Before Width: | Height: | Size: 558 B After Width: | Height: | Size: 558 B |
|
Before Width: | Height: | Size: 580 B After Width: | Height: | Size: 580 B |
|
Before Width: | Height: | Size: 752 B After Width: | Height: | Size: 752 B |
|
Before Width: | Height: | Size: 776 B After Width: | Height: | Size: 776 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
15
lang/strings/translations_en.properties
generated
@@ -1905,11 +1905,18 @@ scriptDirectory=Directory location
|
||||
scriptDirectoryDescription=The local directory containing shell script files
|
||||
scriptSourceUrl=Repository URL
|
||||
scriptSourceUrlDescription=The URL to a remote git repository containing shell script files
|
||||
scriptSourceType=Source type
|
||||
scriptSourceTypeDescription=The type of source from where shell scripts should be loaded
|
||||
scriptCollectionSourceType=Source type
|
||||
scriptCollectionSourceTypeDescription=The type of source from where shell scripts should be loaded
|
||||
gitRepository=Git repository
|
||||
scriptSource.displayName=Script source
|
||||
scriptSource.displayDescription=Automatically import shell script files from an existing source
|
||||
scriptCollectionSource.displayName=Script source
|
||||
scriptCollectionSource.displayDescription=Automatically import shell script files from an existing source
|
||||
directorySource=Directory source
|
||||
gitRepositorySource=Git repository source
|
||||
refreshSource=Refresh source
|
||||
scriptTextSourceUrl=Script URL
|
||||
scriptTextSourceUrlDescription=The URL to retrieve the script file from
|
||||
scriptSourceType=Script source
|
||||
scriptSourceTypeDescription=From where to source the script
|
||||
scriptSourceTypeInPlace=In-place
|
||||
scriptSourceTypeUrl=URL
|
||||
scriptSourceTypeSource=Source
|
||||
|
||||