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
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@

## [Unreleased]

## [1.0.0] - 2025-07-16
## [1.0.1] - 2025-07-17
- Support for adding new environment variables from the Panel
- Support for deleting environment variables from the Panel
- Support for renaming environment variables from the Panel
- Improved error handling and safety checks

## [1.0.0] - 2025-07-16
- First release

[Unreleased]: https://github.com/ringlesoft/visual-env/compare/v1.0.0...HEAD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public String getName() {
}

public String getValue() {
return isSecret ? "********" : value;
return isSecret ? "*".repeat(value.length()) : value;
}

public String getRawValue() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.ringlesoft.visualenv.model;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

Expand Down
38 changes: 23 additions & 15 deletions src/main/java/com/ringlesoft/visualenv/profile/LaravelProfile.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.ringlesoft.visualenv.profile;

import com.ringlesoft.visualenv.model.CliActionDefinition;
import com.ringlesoft.visualenv.model.CliParameterDefinition;
import com.ringlesoft.visualenv.model.EnvFileDefinition;
import com.ringlesoft.visualenv.model.EnvVariableDefinition;

Expand All @@ -24,7 +23,7 @@ public class LaravelProfile implements EnvProfile {
public static final String GROUP_MAIL = "mail";
public static final String GROUP_PUSHER = "pusher";
public static final String GROUP_AWS = "aws";
public static final String GROUP_REDIS = "redis";
public static final String GROUP_DEBUG = "redis";
public static final String GROUP_VITE_PUSHER = "vite_pusher";

private static final Map<String, EnvVariableDefinition> REGISTRY = new HashMap<>();
Expand Down Expand Up @@ -374,6 +373,15 @@ public class LaravelProfile implements EnvProfile {
false
);

register(
"DEBUGBAR_ENABLED",
"Enable or Disable Laravel Debug-bar",
null,
EnvVariableDefinition.VariableType.BOOLEAN,
GROUP_DEBUG,
false
);


EnvVariableDefinition appKey = REGISTRY.get("APP_KEY");
if (appKey != null) {
Expand Down Expand Up @@ -467,19 +475,19 @@ public List<CliActionDefinition> getAvailableCliActions() {
"Generate a new application key and store it in the .env file"
).addEnvironmentVariable("ENV_FILE", "{selectedEnvFile}"),

new CliActionDefinition(
"artisan_env_encrypt",
"Encrypt Environment File",
"php artisan env:encrypt",
"Encrypts an environment file variable using the Laravel framework"
).addParameter(
new CliParameterDefinition(
"name",
"Variable Name",
"Name of the environment variable to retrieve",
true
)
),
// new CliActionDefinition(
// "artisan_env_encrypt",
// "Encrypt Environment File",
// "php artisan env:encrypt",
// "Encrypts an environment file variable using the Laravel framework"
// ).addParameter(
// new CliParameterDefinition(
// "name",
// "Variable Name",
// "Name of the environment variable to retrieve",
// true
// )
// ),
};
return Arrays.asList(definitions);
}
Expand Down
54 changes: 44 additions & 10 deletions src/main/java/com/ringlesoft/visualenv/services/EnvFileService.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,6 @@ public boolean updateEnvVariable(String name, String value) {
}

try {
if (value.contains(" ")) {
value = "\"" + value + "\"";
}
// Use EnvFileManager to update the variable
EnvFileManager.setEnvVariable(project, activeEnvFile, name, value);
// Update cache
Expand Down Expand Up @@ -206,11 +203,11 @@ public boolean createEnvFromTemplate(VirtualFile templateFile) {
EnvVariableDefinition definition = variableRegistry.getVariableDefinition(key);
if (definition != null && definition.isSecret()) {
// Generate a random string for secret values
value = generateRandomString(32);
value = generateRandomString();
} else if (value.isEmpty() || value.equals("null") ||
(key.toLowerCase().contains("key") && !key.toLowerCase().contains("keyboard"))) {
// Heuristic: if it has "key" in the name but no value, randomize it
value = generateRandomString(32);
value = generateRandomString();
}

newContent.append(key).append('=').append(value).append('\n');
Expand Down Expand Up @@ -276,15 +273,14 @@ public VirtualFile findTemplateFile() {
/**
* Generate a random string for use as a secret key
*
* @param length Length of the string
* @return Random string
*/
private String generateRandomString(int length) {
private String generateRandomString() {
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()";
StringBuilder result = new StringBuilder();
Random random = new Random();

for (int i = 0; i < length; i++) {
for (int i = 0; i < 32; i++) {
result.append(characters.charAt(random.nextInt(characters.length())));
}

Expand Down Expand Up @@ -358,8 +354,7 @@ public String executeArtisanCommand(String command) {
}

CommandRunner commandRunner = new CommandRunner(project);
String output = commandRunner.runCommandWithOutput(command);
return output;
return commandRunner.runCommandWithOutput(command);
} catch (Exception e) {
LOG.error("Error executing Artisan command", e);
return "Error: " + e.getMessage();
Expand Down Expand Up @@ -601,4 +596,43 @@ private void refreshVariables() {
public String getLastUpdatedVariable() {
return lastUpdatedVariable;
}

/**
* Create a new environment variable to the currently active file
* @param key Name of the variable
* @param value Value of the variable
*/
public boolean addVariable(String key, String value) {
try {
key = key.trim()
.replaceAll("\\s+", "_") // Replace spaces with underscores
.replaceAll("[^a-zA-Z0-9_]", "_") // Remove non-alphanumeric characters
.toUpperCase();
EnvFileManager.setEnvVariable(project, activeEnvFile, key, value);
return true;
} catch (Exception e) {
return false;
}
}

public boolean deleteEnvVariable(String variableName) {
try {
EnvFileManager.removeEnvVariable(project, activeEnvFile, variableName);
return true;
} catch (Exception e) {
return false;
}
}

public boolean renameVariable(String variableName, String newName) {
try {
newName = newName.trim()
.replaceAll("\\s+", "_") // Replace spaces with underscores
.replaceAll("[^a-zA-Z0-9_]", "_") // Remove non-alphanumeric characters
.toUpperCase();
return EnvFileManager.renameEnvVariable(project, activeEnvFile, variableName, newName);
} catch (Exception e) {
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
}

List<EnvFileDefinition> envFileDefinitions = profile.getEnvFileDefinitions(); // Add null check>
List<VirtualFile> foundFiles = new java.util.ArrayList<>();

Check warning on line 91 in src/main/java/com/ringlesoft/visualenv/services/ProjectService.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Mismatched query and update of collection

Contents of collection `foundFiles` are updated, but never queried

for (EnvFileDefinition envFileDefinition : envFileDefinitions) {
VirtualFile envFile = LocalFileSystem.getInstance().findFileByPath(Path.of(basePath, envFileDefinition.getName()).toString());
Expand All @@ -104,10 +104,6 @@
foundFiles.add(envFile);
}
}

if (foundFiles.isEmpty()) {
// TODO show
}
}

public CommandRunner getCommandRunner() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class CliActionsTab extends JPanel {
private final EnvFileService envService;
private final EnvProfile profile;
private JTextArea resultArea; // Added field for displaying results

/**
* Create a new Artisan tab
*
Expand Down Expand Up @@ -147,8 +147,7 @@ private void addProfileCommands(JPanel panel) {
*/
private void executeCliAction(CliActionDefinition action) {
String command = action.getCommand();
String result = "";


if (action.isRequiresUserInput()) {
// Get parameters
List<CliParameterDefinition> parameters = action.getParameters();
Expand All @@ -173,7 +172,7 @@ private void executeCliAction(CliActionDefinition action) {
}

// Execute the command
result = envService.executeArtisanCommand(command);
String result = envService.executeArtisanCommand(command);
displayCommandResult(result, action.getName() + " Result");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class EnvEditorTab extends JPanel implements AutoCloseable {
private final Map<String, EnvGroupPanel> groupPanels = new HashMap<>();
private VirtualFile selectedEnvFile;
private final Map<String, String> fileBasenameToPath = new HashMap<>();
private FileSaveListener fileSaveListener;
private final FileSaveListener fileSaveListener;

/**
* Create a new Environment editor tab
Expand Down Expand Up @@ -367,7 +367,7 @@ public void reloadCurrentEnvFile() {
}

@Override
public void close() throws Exception {
public void close() {
fileSaveListener.dispose();
}

Expand Down
Loading
Loading