blob: 66faba901f3f3cfd7fc279180b2e2b57dbccd787 [file]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* 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.android.idegen;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
/**
* Build Intellij projects.
*/
public class IntellijProject {
public static final String FRAMEWORK_MODULE_DIR = "frameworks/base";
public static final Charset CHARSET = Charset.forName("UTF-8");
private static final Logger logger = Logger.getLogger(IntellijProject.class.getName());
private static final String MODULES_TEMPLATE_FILE_NAME = "modules.xml";
private static final String VCS_TEMPLATE_FILE_NAME = "vcs.xml";
ModuleCache cache = ModuleCache.getInstance();
boolean buildFramework;
File indexFile;
File projectPath;
ArrayList<String> moduleDirs;
public IntellijProject(String indexFile, String projectPath, ArrayList<String> moduleDirs,
boolean buildFramework) {
this.indexFile = new File(Preconditions.checkNotNull(indexFile));
this.projectPath = new File(Preconditions.checkNotNull(projectPath));
this.moduleDirs = Preconditions.checkNotNull(moduleDirs);
this.buildFramework = buildFramework;
DirectorySearch.findAndInitRepoRoot(this.indexFile);
}
public void build() throws IOException {
cache.init(indexFile);
File repoRoot = DirectorySearch.getRepoRoot();
if (buildFramework) {
File frameworkDir = new File(repoRoot, FRAMEWORK_MODULE_DIR);
// Some unbundled apps/branches do not include the framework.
if (frameworkDir.exists()) {
buildFrameWorkModule(new File(repoRoot, FRAMEWORK_MODULE_DIR));
}
}
for (String moduleDir : moduleDirs) {
// First pass, find all dependencies and cache them.
File dir = new File(repoRoot, moduleDir);
if (!dir.exists()) {
logger.info("Directory " + moduleDir + " does not exist in " + repoRoot +
". Are you sure the directory is correct?");
return;
}
Module module = cache.getAndCacheByDir(dir);
if (module == null) {
logger.info("Module '" + dir.getPath() + "' not found." +
" Module names are case senstive.");
return;
}
}
// Finally create iml files for dependencies
Iterable<Module> modules = cache.getModules();
for (Module mod : modules) {
mod.buildImlFile();
}
createProjectFiles();
}
private void createProjectFiles() throws IOException {
File ideaDir = new File(projectPath, ".idea");
ideaDir.mkdirs();
copyTemplates(ideaDir);
createModulesFile(ideaDir, cache.getModules());
createVcsFile(ideaDir, cache.getModules());
createNameFile(ideaDir, projectPath.getName());
}
/**
* Framework module needs special handling due to one off resource path:
* frameworks/base/Android.mk
*/
private void buildFrameWorkModule(File frameworkModuleDir) throws IOException {
FrameworkModule frameworkModule = new FrameworkModule(frameworkModuleDir);
frameworkModule.build();
cache.put(frameworkModule);
}
private void createModulesFile(File ideaDir, Iterable<Module> modules) throws IOException {
String modulesContent = Files.toString(new File(DirectorySearch.findTemplateDir(),
"idea" + File.separator + MODULES_TEMPLATE_FILE_NAME), CHARSET);
StringBuilder sb = new StringBuilder();
for (Module mod : modules) {
File iml = mod.getImlFile();
sb.append(" <module fileurl=\"file://").append(iml.getCanonicalPath()).append(
"\" filepath=\"").append(iml.getCanonicalPath()).append("\" />\n");
}
modulesContent = modulesContent.replace("@MODULES@", sb.toString());
File out = new File(ideaDir, "modules.xml");
logger.info("Creating " + out.getCanonicalPath());
Files.write(modulesContent, out, CHARSET);
}
private void createVcsFile(File ideaDir, Iterable<Module> modules) throws IOException {
String vcsTemplate = Files.toString(new File(DirectorySearch.findTemplateDir(),
"idea" + File.separator + VCS_TEMPLATE_FILE_NAME), CHARSET);
Set<String> gitRoots = new HashSet<>();
for (Module mod : modules) {
File dir = mod.getDir();
// Look for git root in the module directory and its parents.
while (dir != null) {
File gitRoot = new File(dir, ".git");
if (gitRoot.exists()) {
gitRoots.add(dir.getCanonicalPath());
break;
} else {
dir = dir.getParentFile();
}
}
}
StringBuilder sb = new StringBuilder();
for (String root : gitRoots) {
sb.append(" <mapping directory=\"").append(root).append("\" vcs=\"Git\" />\n");
}
vcsTemplate = vcsTemplate.replace("@VCS@", sb.toString());
Files.write(vcsTemplate, new File(ideaDir, "vcs.xml"), CHARSET);
}
private void createNameFile(File ideaDir, String name) throws IOException {
File out = new File(ideaDir, ".name");
Files.write(name, out, CHARSET);
}
private void copyTemplates(File ideaDir) throws IOException {
File templateDir = DirectorySearch.findTemplateDir();
copyTemplates(new File(templateDir, "idea"), ideaDir);
}
private void copyTemplates(File fromDir, File toDir) throws IOException {
toDir.mkdir();
File[] files = fromDir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
File destDir = new File(toDir, file.getName());
if (!destDir.exists()) {
destDir.mkdirs();
}
copyTemplates(file, destDir);
} else {
File toFile = new File(toDir, file.getName());
logger.info("copying " + file.getCanonicalPath() + " to " +
toFile.getCanonicalPath());
Files.copy(file, toFile);
}
}
}
public static void main(String[] args) {
logger.info("Args: " + Arrays.toString(args));
if (args.length < 3) {
logger.severe("Not enough input arguments. Aborting");
return;
}
boolean buildFramework = true;
int argIndex = 0;
String arg = args[argIndex];
while (arg.startsWith("--")) {
if (arg.equals("--no-framework")) {
buildFramework = false;
}
argIndex++;
arg = args[argIndex];
}
String indexFile = args[argIndex++];
String projectPath = args[argIndex++];
// Remaining args are module directories
ArrayList<String> moduleDirs = Lists.newArrayList();
for (int i = argIndex; i < args.length; i++) {
moduleDirs.add(args[i]);
}
IntellijProject intellij = new IntellijProject(indexFile, projectPath, moduleDirs,
buildFramework);
try {
intellij.build();
} catch (IOException e) {
e.printStackTrace();
}
}
}