Skip to content

Commit fab40a2

Browse files
committed
Improved "projects" support in .graphqlconfig (#164)
- Fixed entry file for project schemas not being recognized by schema scopes - The Schemas Tree View root node no longer attempts schema discovery when projects have been configured as this would potentially create an invalid "root" schema with duplicate types intended to only be part of separate schemas
1 parent 83908ca commit fab40a2

File tree

2 files changed

+51
-20
lines changed

2 files changed

+51
-20
lines changed

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,9 @@ public void buildConfigurationModel(@Nullable List<VirtualFile> changedConfigura
411411
projectConfig.extensions = baseConfig.extensions;
412412
} else if (baseConfig.extensions != null) {
413413
for (Map.Entry<String, Object> extension : baseConfig.extensions.entrySet()) {
414-
projectConfig.extensions.put(extension.getKey(), extension.getValue());
414+
if (!projectConfig.extensions.containsKey(extension.getKey())) {
415+
projectConfig.extensions.put(extension.getKey(), extension.getValue());
416+
}
415417
}
416418
}
417419
});
@@ -501,10 +503,24 @@ public GraphQLNamedScope getSchemaScope(VirtualFile virtualFile) {
501503
// handle entry files
502504
configBaseDir = null;
503505
for (Map.Entry<VirtualFile, GraphQLConfigData> entry : configPathToConfigurations.entrySet()) {
504-
GraphQLFile entryFile = getConfigurationEntryFile(entry.getValue());
506+
final GraphQLConfigData configData = entry.getValue();
507+
GraphQLFile entryFile = getConfigurationEntryFile(configData);
508+
boolean found = false;
505509
if (entryFile.getVirtualFile().equals(virtualFile)) {
506510
// the virtual file is an entry file for the specific config base (either the root schema or one of the nested graphql-config project schemas)
507511
configBaseDir = entry.getKey();
512+
found = true;
513+
} else if(configData.projects != null) {
514+
for (Map.Entry<String, GraphQLResolvedConfigData> projectEntry : configData.projects.entrySet()) {
515+
entryFile = getConfigurationEntryFile(projectEntry.getValue());
516+
if (entryFile.getVirtualFile().equals(virtualFile)) {
517+
configBaseDir = entry.getKey();
518+
found = true;
519+
break;
520+
}
521+
}
522+
}
523+
if (found) {
508524
break;
509525
}
510526
}

src/main/com/intellij/lang/jsgraphql/ide/project/schemastatus/GraphQLConfigSchemaNode.java

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public class GraphQLConfigSchemaNode extends SimpleNode {
4545
private final GraphQLFile configurationEntryFile;
4646

4747
private Map<String, GraphQLResolvedConfigData> projectsConfigData;
48+
private boolean performSchemaDiscovery = true;
4849

4950
protected GraphQLConfigSchemaNode(Project project, GraphQLConfigManager configManager, GraphQLResolvedConfigData configData, VirtualFile configBaseDir) {
5051
super(project);
@@ -58,33 +59,44 @@ protected GraphQLConfigSchemaNode(Project project, GraphQLConfigManager configMa
5859
// use the last part of the folder as name
5960
myName = StringUtils.substringAfterLast(configBaseDir.getPath(), "/");
6061
}
61-
getPresentation().setLocationString(configBaseDir.getPresentableUrl());
62-
getPresentation().setIcon(JSGraphQLIcons.Files.GraphQLSchema);
63-
64-
final GraphQLTypeDefinitionRegistryServiceImpl registry = GraphQLTypeDefinitionRegistryServiceImpl.getService(myProject);
6562

66-
configurationEntryFile = configManager.getConfigurationEntryFile(configData);
67-
endpoints = configManager.getEndpoints(configurationEntryFile.getVirtualFile());
68-
schemaWithErrors = registry.getSchemaWithErrors(configurationEntryFile);
63+
getPresentation().setIcon(JSGraphQLIcons.Files.GraphQLSchema);
6964

7065
if (configData instanceof GraphQLConfigData) {
66+
getPresentation().setLocationString(configBaseDir.getPresentableUrl());
7167
projectsConfigData = ((GraphQLConfigData) configData).projects;
68+
// this node is only considered a "real" schema that should be discovered if the config file doesn't use projects
69+
// if the config uses projects we can't do discovery at the root level as that's likely to consider multiple distinct schemas
70+
// as one with resulting re-declaration errors during validation
71+
performSchemaDiscovery = projectsConfigData == null || projectsConfigData.isEmpty();
7272
}
7373

74+
if (performSchemaDiscovery) {
75+
final GraphQLTypeDefinitionRegistryServiceImpl registry = GraphQLTypeDefinitionRegistryServiceImpl.getService(myProject);
76+
configurationEntryFile = configManager.getConfigurationEntryFile(configData);
77+
endpoints = configManager.getEndpoints(configurationEntryFile.getVirtualFile());
78+
schemaWithErrors = registry.getSchemaWithErrors(configurationEntryFile);
79+
} else {
80+
schemaWithErrors = null;
81+
endpoints = null;
82+
configurationEntryFile = null;
83+
}
7484
}
7585

7686
/**
7787
* Gets whether this node contains a schema that includes the specified file
7888
*/
7989
public boolean representsFile(VirtualFile virtualFile) {
8090
if (virtualFile != null) {
81-
if(virtualFile.equals(configFile)) {
91+
if (virtualFile.equals(configFile)) {
8292
return true;
8393
}
84-
final GraphQLNamedScope schemaScope = configManager.getSchemaScope(configurationEntryFile.getVirtualFile());
85-
if (schemaScope != null) {
86-
if (schemaScope.getPackageSet().includesVirtualFile(virtualFile)) {
87-
return true;
94+
if (performSchemaDiscovery) {
95+
final GraphQLNamedScope schemaScope = configManager.getSchemaScope(configurationEntryFile.getVirtualFile());
96+
if (schemaScope != null) {
97+
if (schemaScope.getPackageSet().includesVirtualFile(virtualFile)) {
98+
return true;
99+
}
88100
}
89101
}
90102
}
@@ -104,20 +116,23 @@ protected void update(PresentationData presentation) {
104116

105117
@Override
106118
public SimpleNode[] getChildren() {
107-
final List<SimpleNode> children = Lists.newArrayList(
108-
new GraphQLSchemaContentNode( this, schemaWithErrors),
109-
new GraphQLSchemaErrorsListNode(this, schemaWithErrors)
110-
);
119+
final List<SimpleNode> children = Lists.newArrayList();
120+
if (performSchemaDiscovery) {
121+
children.add(new GraphQLSchemaContentNode(this, schemaWithErrors));
122+
children.add(new GraphQLSchemaErrorsListNode(this, schemaWithErrors));
123+
}
111124
if (projectsConfigData != null && !projectsConfigData.isEmpty()) {
112125
children.add(new GraphQLConfigProjectsNode(this));
113126
}
114-
children.add(new GraphQLSchemaEndpointsListNode(this, endpoints));
127+
if (endpoints != null) {
128+
children.add(new GraphQLSchemaEndpointsListNode(this, endpoints));
129+
}
115130
return children.toArray(SimpleNode.NO_CHILDREN);
116131
}
117132

118133
@Override
119134
public boolean isAutoExpandNode() {
120-
return representsCurrentFile();
135+
return representsCurrentFile() || !performSchemaDiscovery;
121136
}
122137

123138
@NotNull

0 commit comments

Comments
 (0)