/* * Copyright 2015-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.facebook.buck.intellij.ideabuck.build; import com.facebook.buck.intellij.ideabuck.file.BuckFileUtil; import com.facebook.buck.intellij.ideabuck.lang.BuckFile; import com.facebook.buck.intellij.ideabuck.lang.psi.BuckExpression; import com.facebook.buck.intellij.ideabuck.lang.psi.BuckPsiUtils; import com.facebook.buck.intellij.ideabuck.lang.psi.BuckRuleBody; import com.facebook.buck.intellij.ideabuck.lang.psi.BuckTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; public final class BuckBuildUtil { public static final String BUCK_CONFIG_FILE = ".buckconfig"; public static final String BUCK_FILE_NAME = BuckFileUtil.getBuildFileName(); // TODO(#7908675): Use Buck's classes and get rid of these. public static final String PROJECT_CONFIG_RULE_NAME = "project_config"; public static final String SRC_TARGET_PROPERTY_NAME = "src_target"; private BuckBuildUtil() {} public static boolean isValidAbsoluteTarget(String target) { return target.matches("^//[\\s\\S]*:[\\s\\S]*$"); } /** * @param target The absolute target in "//apps/myapp:app" pattern. * @return The absolute path of the target, for example "apps/myapp". */ public static String extractAbsoluteTarget(String target) { return target.substring(2, target.lastIndexOf(":")); } /** * Return the virtual file of the BUCK file of the given target. TODO(#7908675): Use Buck's * BuildTargetFactory and deprecate this class. */ public static VirtualFile getBuckFileFromAbsoluteTarget(Project project, String target) { if (!isValidAbsoluteTarget(target)) { return null; } VirtualFile buckDir = project.getBaseDir().findFileByRelativePath(extractAbsoluteTarget(target)); return buckDir != null ? buckDir.findChild(BuckFileUtil.getBuildFileName()) : null; } /** * Get the buck target from a buck file. TODO(#7908675): We should use Buck's own classes for it. */ public static String extractBuckTarget(Project project, VirtualFile file) { BuckFile buckFile = (BuckFile) PsiManager.getInstance(project).findFile(file); if (buckFile == null) { return null; } PsiElement[] children = buckFile.getChildren(); for (PsiElement child : children) { if (child.getNode().getElementType() == BuckTypes.RULE_BLOCK) { PsiElement ruleName = child.getFirstChild(); // Find rule "project_config" if (ruleName != null && BuckPsiUtils.testType(ruleName, BuckTypes.RULE_NAME) && ruleName.getText().equals(PROJECT_CONFIG_RULE_NAME)) { // Find property "src_target" PsiElement bodyElement = BuckPsiUtils.findChildWithType(child, BuckTypes.RULE_BODY); return getPropertyValue((BuckRuleBody) bodyElement, SRC_TARGET_PROPERTY_NAME); } } } return null; } /** * Get the value of a property in a specific buck rule body. TODO(#7908675): We should use Buck's * own classes for it. */ public static String getPropertyValue(BuckRuleBody body, String name) { if (body == null) { return null; } PsiElement[] children = body.getChildren(); for (PsiElement child : children) { if (BuckPsiUtils.testType(child, BuckTypes.PROPERTY)) { PsiElement lvalue = child.getFirstChild(); PsiElement propertyName = lvalue.getFirstChild(); if (propertyName != null && propertyName.getText().equals(name)) { BuckExpression expression = (BuckExpression) BuckPsiUtils.findChildWithType(child, BuckTypes.EXPRESSION); return expression != null ? BuckPsiUtils.getStringValueFromExpression(expression) : null; } } } return null; } /** * Find the buck file from a directory. TODO(#7908675): We should use Buck's own classes for it. */ public static VirtualFile getBuckFileFromDirectory(VirtualFile file) { if (file == null) { return null; } VirtualFile buckFile = file.findChild(BUCK_FILE_NAME); while (buckFile == null && file != null) { buckFile = file.findChild(BUCK_FILE_NAME); file = file.getParent(); } return buckFile; } }