package com.google.jstestdriver.idea.execution; import com.google.common.collect.Lists; import com.google.jstestdriver.idea.config.JstdConfigFileType; import com.google.jstestdriver.idea.execution.settings.JstdRunSettings; import com.google.jstestdriver.idea.execution.settings.TestType; import com.intellij.lang.javascript.library.JSLibraryUtil; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.FileTypeIndex; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.GlobalSearchScopesCore; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.Collection; import java.util.Collections; import java.util.List; public class JstdSettingsUtil { private static final Key<Boolean> JSTD_CONFIG_FILES_IN_PROJECT = new Key<>("JSTD_CONFIG_FILES_IN_PROJECT"); private JstdSettingsUtil() {} @NotNull public static List<VirtualFile> collectJstdConfigs(@NotNull Project project, @NotNull JstdRunSettings runSettings) { TestType testType = runSettings.getTestType(); List<VirtualFile> res = Collections.emptyList(); if (testType == TestType.ALL_CONFIGS_IN_DIRECTORY) { VirtualFile virtualFile = VfsUtil.findFileByIoFile(new File(runSettings.getDirectory()), true); if (virtualFile != null) { res = collectJstdConfigFilesInDirectory(project, virtualFile); } } else { File configFile = new File(runSettings.getConfigFile()); VirtualFile configVirtualFile = VfsUtil.findFileByIoFile(configFile, false); if (configVirtualFile != null) { res = Collections.singletonList(configVirtualFile); } } return res; } @NotNull public static List<VirtualFile> collectJstdConfigFilesInDirectory(@NotNull Project project, @NotNull VirtualFile directory) { GlobalSearchScope directorySearchScope = buildDirectorySearchScope(project, directory); if (directorySearchScope == null) { return Collections.emptyList(); } Collection<VirtualFile> configs = FileTypeIndex.getFiles(JstdConfigFileType.INSTANCE, directorySearchScope); return Lists.newArrayList(configs); } public static boolean areJstdConfigFilesInProjectCached(@NotNull Project project) { Boolean value = project.getUserData(JSTD_CONFIG_FILES_IN_PROJECT); if (value != null) { return value; } value = areJstdConfigFilesInScope(GlobalSearchScope.projectScope(project)); if (value == null) { return false; } project.putUserData(JSTD_CONFIG_FILES_IN_PROJECT, value); return value; } public static boolean areJstdConfigFilesInProject(@NotNull Project project) { GlobalSearchScope projectScope = GlobalSearchScope.projectScope(project); Boolean found = areJstdConfigFilesInScope(projectScope); return found != null ? found : false; } public static boolean areJstdConfigFilesInDirectory(@NotNull Project project, @NotNull VirtualFile directory) { GlobalSearchScope directorySearchScope = buildDirectorySearchScope(project, directory); if (directorySearchScope == null) { return false; } Boolean found = areJstdConfigFilesInScope(directorySearchScope); return found != null ? found : false; } @Nullable private static Boolean areJstdConfigFilesInScope(GlobalSearchScope scope) { try { Ref<Boolean> foundRef = Ref.create(false); FileTypeIndex.processFiles(JstdConfigFileType.INSTANCE, file -> { if (JSLibraryUtil.isProbableLibraryFile(file)) { return true; } foundRef.set(true); return false; }, scope); return foundRef.get(); } catch (IndexNotReadyException e) { return null; } } @Nullable private static GlobalSearchScope buildDirectorySearchScope(@NotNull Project project, @NotNull VirtualFile directory) { final Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(directory); if (module == null) { return null; } GlobalSearchScope directorySearchScope = GlobalSearchScopesCore.directoryScope(project, directory, true); return module.getModuleContentWithDependenciesScope().intersectWith(directorySearchScope); } }