1 package org.robolectric.internal;
2 
3 import static java.nio.charset.StandardCharsets.UTF_8;
4 
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.IOException;
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.Collections;
11 import java.util.List;
12 import javax.annotation.Nonnull;
13 import org.robolectric.annotation.Config;
14 import org.robolectric.res.Fs;
15 import org.robolectric.res.FsFile;
16 import org.robolectric.util.Util;
17 
18 public class BuckManifestFactory implements ManifestFactory {
19 
20   private static final String BUCK_ROBOLECTRIC_RES_DIRECTORIES = "buck.robolectric_res_directories";
21   private static final String BUCK_ROBOLECTRIC_ASSETS_DIRECTORIES = "buck.robolectric_assets_directories";
22   private static final String BUCK_ROBOLECTRIC_MANIFEST = "buck.robolectric_manifest";
23 
24   @Override
identify(Config config)25   public ManifestIdentifier identify(Config config) {
26     String buckManifest = System.getProperty(BUCK_ROBOLECTRIC_MANIFEST);
27     FsFile manifestFile = Fs.fileFromPath(buckManifest);
28 
29     String buckResDirs = System.getProperty(BUCK_ROBOLECTRIC_RES_DIRECTORIES);
30     String buckAssetsDirs = System.getProperty(BUCK_ROBOLECTRIC_ASSETS_DIRECTORIES);
31     String packageName = config.packageName();
32 
33     final List<FsFile> buckResources = getDirectoriesFromProperty(buckResDirs);
34     final List<FsFile> buckAssets = getDirectoriesFromProperty(buckAssetsDirs);
35     final FsFile resDir = buckResources.size() == 0 ? null : buckResources.get(buckResources.size() - 1);
36     final FsFile assetsDir = buckAssets.size() == 0 ? null : buckAssets.get(buckAssets.size() - 1);
37     final List<ManifestIdentifier> libraries;
38 
39     if (resDir == null && assetsDir == null) {
40       libraries = null;
41     } else {
42       libraries = new ArrayList<>();
43 
44       for (int i = 0; i < buckResources.size() - 1; i++) {
45         libraries.add(new ManifestIdentifier((String) null, null, buckResources.get(i), null, null));
46       }
47 
48       for (int i = 0; i < buckAssets.size() - 1; i++) {
49         libraries.add(new ManifestIdentifier(null, null, null, buckAssets.get(i), null));
50       }
51     }
52 
53     return new ManifestIdentifier(packageName, manifestFile, resDir, assetsDir, libraries);
54   }
55 
isBuck()56   public static boolean isBuck() {
57     return System.getProperty(BUCK_ROBOLECTRIC_MANIFEST) != null;
58   }
59 
60   @Nonnull
getDirectoriesFromProperty(String property)61   private List<FsFile> getDirectoriesFromProperty(String property) {
62     if (property == null) {
63       return Collections.emptyList();
64     }
65 
66     List<String> dirs;
67     if (property.startsWith("@")) {
68       String filename = property.substring(1);
69       try {
70         dirs = Arrays.asList(
71             new String(Util.readBytes(new FileInputStream(filename)), UTF_8).split("\\n"));
72       } catch (IOException e) {
73         throw new RuntimeException("Cannot read file " + filename);
74       }
75     } else {
76       dirs = Arrays.asList(property.split(File.pathSeparator));
77     }
78 
79     List<FsFile> files = new ArrayList<>();
80     for (String dir : dirs) {
81       files.add(Fs.fileFromPath(dir));
82     }
83     return files;
84   }
85 }
86