Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions aesh/src/main/java/org/aesh/command/settings/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ public interface Settings<CI extends CommandInvocation>
*/
AeshContext aeshContext();

/**
* Indicates whether {@link #aeshContext()} was explicitly configured (e.g., via
* {@code SettingsBuilder.aeshContext(...)}) rather than lazily defaulted. Components that build their own runtime from
* these settings use this to decide whether the provided context should take precedence over console-managed defaults.
*/
default boolean hasExplicitAeshContext() {
return true;
}

/**
* Get the export file
* Defaults to ~/.aesh_export
Expand Down
16 changes: 15 additions & 1 deletion aesh/src/main/java/org/aesh/command/settings/SettingsImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ public class SettingsImpl<CI extends CommandInvocation>
private boolean manEnabled = true;
private PipelineConfig pipelineConfig = PipelineConfig.DEFAULT;
private AeshContext aeshContext;
/** True when the context above was set explicitly, not lazily defaulted. */
private boolean explicitAeshContext = false;
private boolean exportEnabled = true;
private File exportFile;
private boolean persistExport = true;
Expand Down Expand Up @@ -148,7 +150,8 @@ protected SettingsImpl(Settings<CI> baseSettings) {
enableOperatorParser(baseSettings.operatorParserEnabled());
setPipelineConfig(baseSettings.pipelineConfig());
setManEnabled(baseSettings.manEnabled());
setAeshContext(baseSettings.aeshContext());
// Only carry over an explicitly configured context; otherwise this instance keeps its own lazily-created default.
setAeshContext(baseSettings.hasExplicitAeshContext() ? baseSettings.aeshContext() : null);
setExportEnabled(baseSettings.exportEnabled());
setExportFile(baseSettings.exportFile());
setPersistExport(baseSettings.persistExport());
Expand Down Expand Up @@ -600,7 +603,18 @@ public AeshContext aeshContext() {
return aeshContext;
}

/**
* True only when {@link #setAeshContext(AeshContext)} was called with a non-null value.
* A lazily-created default does not count as explicit, so console components can fall back to their own managed context
* (e.g., one wired to the export manager).
*/
@Override
public boolean hasExplicitAeshContext() {
return explicitAeshContext;
}

public void setAeshContext(AeshContext aeshContext) {
this.explicitAeshContext = aeshContext != null;
this.aeshContext = aeshContext;
}

Expand Down
6 changes: 5 additions & 1 deletion aesh/src/main/java/org/aesh/console/ReadlineConsole.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,11 @@ public ReadlineConsole(Settings<? extends CommandInvocation> givenSettings) {
readlineFlags.put(ReadlineFlag.NO_PROMPT_REDRAW_ON_INTR, Integer.MAX_VALUE);
}

context = new DefaultAeshContext(exportManager);
// Respect an explicitly configured context (e.g., a CLI-provided AeshContext via SettingsBuilder.aeshContext(...));
if (settings.hasExplicitAeshContext() && settings.aeshContext() != null)
context = settings.aeshContext();
else
context = new DefaultAeshContext(exportManager);

processManager = new ProcessManager(this);
CommandExecutionListener userListener = settings.commandExecutionListener();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.aesh.console;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.util.Collections;
import java.util.Set;

import org.aesh.command.settings.Settings;
import org.aesh.command.settings.SettingsBuilder;
import org.aesh.io.Resource;
import org.junit.Test;

/**
* Tests that ReadlineConsole propagates an explicitly configured AeshContext to its own runtime,
* instead of always creating a fresh default context. Commands executed through the interactive
* console must observe exactly the instance provided via SettingsBuilder.aeshContext(...).
*/
public class ReadlineConsoleContextTest {

private static AeshContext customContext() {
return new AeshContext() {
@Override
public Resource getCurrentWorkingDirectory() {
return null;
}

@Override
public void setCurrentWorkingDirectory(Resource cwd) {
}

@Override
public Set<String> exportedVariableNames() {
return Collections.emptySet();
}

@Override
public String exportedVariable(String key) {
return null;
}
};
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void explicitSettingsContextIsUsedByConsole() {
AeshContext custom = customContext();
Settings settings = SettingsBuilder.builder().aeshContext(custom).build();
ReadlineConsole console = new ReadlineConsole(settings);

assertSame("console must use the explicitly configured context, not a fresh default",
custom, console.context());
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void unsetSettingsFallBackToDefaultContext() {
Settings settings = SettingsBuilder.builder().build();
ReadlineConsole console = new ReadlineConsole(settings);

assertNotNull(console.context());
assertTrue("without an explicit context the console keeps its managed default",
console.context() instanceof DefaultAeshContext);
}
}
Loading