Skip to content

Commit 3f5cc84

Browse files
authored
Added the ability to load env variables from a .env file (#426)
* Added the ability to load env variables from a .env file * Can now load .env files from multi-root projects * Can now load .env files from multi-root projects * Can now load .env files from multi-root projects * Review improvements
1 parent dab20c0 commit 3f5cc84

File tree

7 files changed

+64
-10
lines changed

7 files changed

+64
-10
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ GraphQL language support for WebStorm, IntelliJ IDEA and other IDEs based on the
1515
- Syntax highlighting, code-formatting, folding, commenter, and brace-matching
1616
- 'Find Usages' and 'Go to Declaration' for schema types, fields, and fragments
1717
- 'Structure view' to navigate GraphQL files
18+
- Load variables from .env files
1819

1920
## Documentation
2021

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ dependencies {
2828
implementation 'com.atlassian.commonmark:commonmark:0.12.1'
2929
implementation group: 'org.yaml', name: 'snakeyaml', version: '1.21'
3030
implementation 'fr.opensagres.js:minimatch.java:1.1.0'
31+
implementation 'io.github.cdimascio:dotenv-kotlin:6.2.2'
3132

3233
testImplementation group: 'junit', name: 'junit', version: '4.12'
3334
}

src/main/com/intellij/lang/jsgraphql/ide/editor/GraphQLIntrospectEndpointUrlLineMarkerProvider.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.intellij.openapi.util.Ref;
3030
import com.intellij.openapi.util.text.StringUtil;
3131
import com.intellij.openapi.vfs.VirtualFile;
32+
import com.intellij.psi.PsiDirectory;
3233
import com.intellij.psi.PsiElement;
3334
import com.intellij.psi.PsiErrorElement;
3435
import com.intellij.psi.PsiFile;
@@ -48,6 +49,8 @@
4849
* Line marker for running an introspection against a configured endpoint url in a .graphqlconfig file
4950
*/
5051
public class GraphQLIntrospectEndpointUrlLineMarkerProvider implements LineMarkerProvider {
52+
private String pathOfConfigFileParent;
53+
5154
@Nullable
5255
@Override
5356
public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
@@ -60,13 +63,14 @@ public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
6063
if (isEndpointUrl(jsonProperty, urlRef) && !hasErrors(jsonProperty.getContainingFile())) {
6164
return new LineMarkerInfo<>(jsonProperty, jsonProperty.getTextRange(), AllIcons.RunConfigurations.TestState.Run, Pass.UPDATE_ALL, o -> "Run introspection query to generate GraphQL SDL schema file", (evt, jsonUrl) -> {
6265

63-
String introspectionUtl;
66+
String introspectionUrl;
6467
if (jsonUrl.getValue() instanceof JsonStringLiteral) {
65-
introspectionUtl = ((JsonStringLiteral) jsonUrl.getValue()).getValue();
68+
introspectionUrl = ((JsonStringLiteral) jsonUrl.getValue()).getValue();
6669
} else {
6770
return;
6871
}
69-
final GraphQLConfigVariableAwareEndpoint endpoint = getEndpoint(introspectionUtl, jsonProperty);
72+
73+
final GraphQLConfigVariableAwareEndpoint endpoint = getEndpoint(introspectionUrl, jsonProperty, element.getContainingFile().getVirtualFile());
7074
if (endpoint == null) {
7175
return;
7276
}
@@ -159,7 +163,7 @@ private String getSchemaPath(@NotNull JsonProperty urlElement, boolean showNotif
159163
return null;
160164
}
161165

162-
private GraphQLConfigVariableAwareEndpoint getEndpoint(String url, JsonProperty urlJsonProperty) {
166+
private GraphQLConfigVariableAwareEndpoint getEndpoint(String url, JsonProperty urlJsonProperty, VirtualFile configFile) {
163167
try {
164168
// if the endpoint is just the url string, headers are not supported
165169
final JsonProperty parent = PsiTreeUtil.getParentOfType(urlJsonProperty, JsonProperty.class);
@@ -181,7 +185,7 @@ private GraphQLConfigVariableAwareEndpoint getEndpoint(String url, JsonProperty
181185
}
182186

183187

184-
return new GraphQLConfigVariableAwareEndpoint(endpointConfig, urlJsonProperty.getProject());
188+
return new GraphQLConfigVariableAwareEndpoint(endpointConfig, urlJsonProperty.getProject(), configFile);
185189

186190
} catch (Exception e) {
187191
Notifications.Bus.notify(new Notification("GraphQL", "GraphQL Configuration Error", e.getMessage(), NotificationType.ERROR), urlJsonProperty.getProject());

src/main/com/intellij/lang/jsgraphql/ide/editor/GraphQLIntrospectionService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public void performIntrospectionQueryAndUpdateSchemaPathFile(Project project, Gr
107107
return;
108108
}
109109

110-
performIntrospectionQueryAndUpdateSchemaPathFile(new GraphQLConfigVariableAwareEndpoint(endpoint, project), schemaPath, configFile);
110+
performIntrospectionQueryAndUpdateSchemaPathFile(new GraphQLConfigVariableAwareEndpoint(endpoint, project, configFile), schemaPath, configFile);
111111
}
112112

113113
}

src/main/com/intellij/lang/jsgraphql/ide/project/graphqlconfig/model/GraphQLConfigVariableAwareEndpoint.java

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
import com.intellij.notification.Notifications;
1414
import com.intellij.openapi.project.Project;
1515
import com.intellij.openapi.ui.DialogWrapper;
16+
import com.intellij.openapi.vfs.VirtualFile;
1617
import com.intellij.ui.components.JBLabel;
1718
import com.intellij.ui.components.JBTextField;
1819
import com.intellij.util.ui.FormBuilder;
20+
import io.github.cdimascio.dotenv.Dotenv;
1921
import org.jetbrains.annotations.NotNull;
2022
import org.jetbrains.annotations.Nullable;
2123

@@ -36,10 +38,12 @@ public class GraphQLConfigVariableAwareEndpoint {
3638

3739
private final GraphQLConfigEndpoint endpoint;
3840
private final Project project;
41+
private final VirtualFile configFile;
3942

40-
public GraphQLConfigVariableAwareEndpoint(GraphQLConfigEndpoint endpoint, Project project) {
43+
public GraphQLConfigVariableAwareEndpoint(GraphQLConfigEndpoint endpoint, Project project, VirtualFile configFile) {
4144
this.endpoint = endpoint;
4245
this.project = project;
46+
this.configFile = configFile;
4347
}
4448

4549
public String getName() {
@@ -95,7 +99,16 @@ public String expandVariables(String rawValue) {
9599
Notifications.Bus.notify(new Notification("GraphQL", "Unsupported variable source", "Supported variables sources are 'env', but got: " + varSource, NotificationType.ERROR));
96100
continue;
97101
}
102+
103+
// Try to load the variable from the system
98104
String varValue = GET_ENV_VAR.apply(varName);
105+
106+
// If the variable wasn't found in the system try to see if the user has a .env file with the variable
107+
if (varValue == null || varValue.trim().isEmpty()) {
108+
varValue = tryToGetVariableFromDotEnvFile(varName, varValue);
109+
}
110+
111+
// If it still wasn't found present the user with a dialog to enter the variable
99112
if (varValue == null || varValue.trim().isEmpty()) {
100113
final VariableDialog dialog = new VariableDialog(project, varName);
101114
if (dialog.showAndGet()) {
@@ -104,12 +117,47 @@ public String expandVariables(String rawValue) {
104117
continue;
105118
}
106119
}
120+
107121
matcher.appendReplacement(sb, varValue);
108122
}
109123
matcher.appendTail(sb);
110124
return sb.toString();
111125
}
112126

127+
@Nullable
128+
private String tryToGetVariableFromDotEnvFile(String varName, String varValue) {
129+
Dotenv dotenv;
130+
131+
// Let's try to load the env file closest to the config file first
132+
if (configFile != null) {
133+
VirtualFile parentDir = configFile.getParent();
134+
if (parentDir != null) {
135+
dotenv = Dotenv
136+
.configure()
137+
.directory(parentDir.getPath())
138+
.ignoreIfMalformed()
139+
.ignoreIfMissing()
140+
.load();
141+
142+
varValue = dotenv.get(varName);
143+
}
144+
}
145+
146+
// If that didn't resolve try to load the env file from the root of the project
147+
String projectBasePath = project.getBasePath();
148+
if (varValue == null && projectBasePath != null) {
149+
dotenv = Dotenv
150+
.configure()
151+
.directory(projectBasePath)
152+
.ignoreIfMalformed()
153+
.ignoreIfMissing()
154+
.load();
155+
156+
varValue = dotenv.get(varName);
157+
}
158+
return varValue;
159+
}
160+
113161
static class VariableDialog extends DialogWrapper {
114162

115163
private static Map<String, String> previousVariables = Maps.newHashMap();

src/main/com/intellij/lang/jsgraphql/v1/ide/project/JSGraphQLLanguageUIProjectService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ public void executeGraphQL(Editor editor, VirtualFile virtualFile) {
340340
if (endpointsModel != null) {
341341
final GraphQLConfigEndpoint selectedEndpoint = endpointsModel.getSelectedItem();
342342
if (selectedEndpoint != null && selectedEndpoint.url != null) {
343-
final GraphQLConfigVariableAwareEndpoint endpoint = new GraphQLConfigVariableAwareEndpoint(selectedEndpoint, myProject);
343+
final GraphQLConfigVariableAwareEndpoint endpoint = new GraphQLConfigVariableAwareEndpoint(selectedEndpoint, myProject, virtualFile);
344344
final JSGraphQLQueryContext context = JSGraphQLQueryContextHighlightVisitor.getQueryContextBufferAndHighlightUnused(editor);
345345

346346
Map<String, Object> requestData = new HashMap<>();

src/test/com/intellij/lang/jsgraphql/ide/project/graphqlconfig/model/GraphQLConfigVariableAwareEndpointTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public class GraphQLConfigVariableAwareEndpointTest {
2626
public void getExpandedVariables() {
2727

2828
GraphQLConfigEndpoint endpoint = new GraphQLConfigEndpoint(null, "", "http://localhost/");
29-
GraphQLConfigVariableAwareEndpoint variableAwareEndpoint = new GraphQLConfigVariableAwareEndpoint(endpoint, PROJECT);
29+
GraphQLConfigVariableAwareEndpoint variableAwareEndpoint = new GraphQLConfigVariableAwareEndpoint(endpoint, PROJECT, null);
3030

3131
// setup env var resolver
3232
variableAwareEndpoint.GET_ENV_VAR = name -> name + "-value";
@@ -62,4 +62,4 @@ public void getExpandedVariables() {
6262

6363
}
6464

65-
}
65+
}

0 commit comments

Comments
 (0)