Skip to content

Commit d3ec8a8

Browse files
Merge pull request #9949 from github/edoardo/trap-cache-config
JS: Change how TRAP cache is configured
2 parents aa36556 + 5c3d395 commit d3ec8a8

File tree

5 files changed

+55
-56
lines changed

5 files changed

+55
-56
lines changed

javascript/extractor/src/com/semmle/js/extractor/AutoBuild.java

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@
8686
* <code>XML</code> is also supported
8787
* <li><code>LGTM_INDEX_XML_MODE</code>: whether to extract XML files
8888
* <li><code>LGTM_THREADS</code>: the maximum number of files to extract in parallel
89-
* <li><code>LGTM_TRAP_CACHE</code>: the path of a directory to use for trap caching
90-
* <li><code>LGTM_TRAP_CACHE_BOUND</code>: the size to bound the trap cache to
9189
* </ul>
9290
*
9391
* <p>It extracts the following:
@@ -220,7 +218,7 @@ public AutoBuild() {
220218
this.LGTM_SRC = toRealPath(getPathFromEnvVar("LGTM_SRC"));
221219
this.SEMMLE_DIST = Paths.get(EnvironmentVariables.getExtractorRoot());
222220
this.outputConfig = new ExtractorOutputConfig(LegacyLanguage.JAVASCRIPT);
223-
this.trapCache = mkTrapCache();
221+
this.trapCache = ITrapCache.fromExtractorOptions();
224222
this.typeScriptMode =
225223
getEnumFromEnvVar("LGTM_INDEX_TYPESCRIPT", TypeScriptMode.class, TypeScriptMode.FULL);
226224
this.defaultEncoding = getEnvVar("LGTM_INDEX_DEFAULT_ENCODING");
@@ -281,28 +279,6 @@ private Path toRealPath(Path p) {
281279
}
282280
}
283281

284-
/**
285-
* Set up TRAP cache based on environment variables <code>LGTM_TRAP_CACHE</code> and <code>
286-
* LGTM_TRAP_CACHE_BOUND</code>.
287-
*/
288-
private ITrapCache mkTrapCache() {
289-
ITrapCache trapCache;
290-
String trapCachePath = getEnvVar("LGTM_TRAP_CACHE");
291-
if (trapCachePath != null) {
292-
Long sizeBound = null;
293-
String trapCacheBound = getEnvVar("LGTM_TRAP_CACHE_BOUND");
294-
if (trapCacheBound != null) {
295-
sizeBound = DefaultTrapCache.asFileSize(trapCacheBound);
296-
if (sizeBound == null)
297-
throw new UserError("Invalid TRAP cache size bound: " + trapCacheBound);
298-
}
299-
trapCache = new DefaultTrapCache(trapCachePath, sizeBound, Main.EXTRACTOR_VERSION);
300-
} else {
301-
trapCache = new DummyTrapCache();
302-
}
303-
return trapCache;
304-
}
305-
306282
private void setupFileTypes() {
307283
for (String spec : Main.NEWLINE.split(getEnvVar("LGTM_INDEX_FILETYPES", ""))) {
308284
spec = spec.trim();
@@ -513,14 +489,13 @@ private void extractExterns() throws IOException {
513489
SEMMLE_DIST.resolve(".cache").resolve("trap-cache").resolve("javascript");
514490
if (Files.isDirectory(trapCachePath)) {
515491
trapCache =
516-
new DefaultTrapCache(trapCachePath.toString(), null, Main.EXTRACTOR_VERSION) {
492+
new DefaultTrapCache(trapCachePath.toString(), null, Main.EXTRACTOR_VERSION, false) {
517493
boolean warnedAboutCacheMiss = false;
518494

519495
@Override
520496
public File lookup(String source, ExtractorConfig config, FileType type) {
521497
File f = super.lookup(source, config, type);
522-
// only return `f` if it exists; this has the effect of making the cache read-only
523-
if (f.exists()) return f;
498+
if (f != null) return f;
524499
// warn on first failed lookup
525500
if (!warnedAboutCacheMiss) {
526501
warn("Trap cache lookup for externs failed.");
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.semmle.js.extractor;
2+
3+
import com.semmle.util.process.Env;
4+
5+
public class ExtractorOptionsUtil {
6+
public static String readExtractorOption(String... option) {
7+
StringBuilder name = new StringBuilder("CODEQL_EXTRACTOR_JAVASCRIPT_OPTION");
8+
for (String segment : option)
9+
name.append("_").append(segment.toUpperCase());
10+
return Env.systemEnv().getNonEmpty(name.toString());
11+
}
12+
}

javascript/extractor/src/com/semmle/js/extractor/Main.java

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
import com.semmle.js.extractor.ExtractorConfig.Platform;
1616
import com.semmle.js.extractor.ExtractorConfig.SourceType;
1717
import com.semmle.js.extractor.FileExtractor.FileType;
18-
import com.semmle.js.extractor.trapcache.DefaultTrapCache;
19-
import com.semmle.js.extractor.trapcache.DummyTrapCache;
2018
import com.semmle.js.extractor.trapcache.ITrapCache;
2119
import com.semmle.js.parser.ParsedProject;
2220
import com.semmle.ts.extractor.TypeExtractor;
@@ -61,8 +59,6 @@ public class Main {
6159
private static final String P_PLATFORM = "--platform";
6260
private static final String P_QUIET = "--quiet";
6361
private static final String P_SOURCE_TYPE = "--source-type";
64-
private static final String P_TRAP_CACHE = "--trap-cache";
65-
private static final String P_TRAP_CACHE_BOUND = "--trap-cache-bound";
6662
private static final String P_TYPESCRIPT = "--typescript";
6763
private static final String P_TYPESCRIPT_FULL = "--typescript-full";
6864
private static final String P_TYPESCRIPT_RAM = "--typescript-ram";
@@ -112,22 +108,7 @@ public void run(String[] args) {
112108
ap.parse();
113109

114110
extractorConfig = parseJSOptions(ap);
115-
ITrapCache trapCache;
116-
if (ap.has(P_TRAP_CACHE)) {
117-
Long sizeBound = null;
118-
if (ap.has(P_TRAP_CACHE_BOUND)) {
119-
String tcb = ap.getString(P_TRAP_CACHE_BOUND);
120-
sizeBound = DefaultTrapCache.asFileSize(tcb);
121-
if (sizeBound == null) ap.error("Invalid TRAP cache size bound: " + tcb);
122-
}
123-
trapCache = new DefaultTrapCache(ap.getString(P_TRAP_CACHE), sizeBound, EXTRACTOR_VERSION);
124-
} else {
125-
if (ap.has(P_TRAP_CACHE_BOUND))
126-
ap.error(
127-
P_TRAP_CACHE_BOUND + " should only be specified together with " + P_TRAP_CACHE + ".");
128-
trapCache = new DummyTrapCache();
129-
}
130-
fileExtractor = new FileExtractor(extractorConfig, extractorOutputConfig, trapCache);
111+
fileExtractor = new FileExtractor(extractorConfig, extractorOutputConfig, ITrapCache.fromExtractorOptions());
131112

132113
setupMatchers(ap);
133114

@@ -432,12 +413,6 @@ private ArgsParser addArgs(ArgsParser argsParser) {
432413
argsParser.addToleratedFlag(P_TOLERATE_PARSE_ERRORS, 0);
433414
argsParser.addFlag(
434415
P_ABORT_ON_PARSE_ERRORS, 0, "Abort extraction if a parse error is encountered.");
435-
argsParser.addFlag(P_TRAP_CACHE, 1, "Use the given directory as the TRAP cache.");
436-
argsParser.addFlag(
437-
P_TRAP_CACHE_BOUND,
438-
1,
439-
"A (soft) upper limit on the size of the TRAP cache, "
440-
+ "in standard size units (e.g., 'g' for gigabytes).");
441416
argsParser.addFlag(P_DEFAULT_ENCODING, 1, "The encoding to use; default is UTF-8.");
442417
argsParser.addFlag(P_TYPESCRIPT, 0, "Enable basic TypesScript support.");
443418
argsParser.addFlag(

javascript/extractor/src/com/semmle/js/extractor/trapcache/DefaultTrapCache.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,15 @@ public class DefaultTrapCache implements ITrapCache {
2626
*/
2727
private final String extractorVersion;
2828

29-
public DefaultTrapCache(String trapCache, Long sizeBound, String extractorVersion) {
29+
/**
30+
* Whether this cache supports write operations.
31+
*/
32+
private final boolean writeable;
33+
34+
public DefaultTrapCache(String trapCache, Long sizeBound, String extractorVersion, boolean writeable) {
3035
this.trapCache = new File(trapCache);
3136
this.extractorVersion = extractorVersion;
37+
this.writeable = writeable;
3238
try {
3339
initCache(sizeBound);
3440
} catch (ResourceError | SecurityException e) {
@@ -135,6 +141,8 @@ public File lookup(String source, ExtractorConfig config, FileType type) {
135141
digestor.write(type.toString());
136142
digestor.write(config);
137143
digestor.write(source);
138-
return new File(trapCache, digestor.getDigest() + ".trap.gz");
144+
File result = new File(trapCache, digestor.getDigest() + ".trap.gz");
145+
if (!writeable && !result.exists()) return null; // If the cache isn't writable, only return the file if it exists
146+
return result;
139147
}
140148
}

javascript/extractor/src/com/semmle/js/extractor/trapcache/ITrapCache.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package com.semmle.js.extractor.trapcache;
22

3+
import static com.semmle.js.extractor.ExtractorOptionsUtil.readExtractorOption;
4+
35
import com.semmle.js.extractor.ExtractorConfig;
46
import com.semmle.js.extractor.FileExtractor;
7+
import com.semmle.js.extractor.Main;
8+
import com.semmle.util.exception.UserError;
59
import java.io.File;
610

711
/** Generic TRAP cache interface. */
@@ -18,4 +22,29 @@ public interface ITrapCache {
1822
* cached information), or does not yet exist (and should be populated by the extractor)
1923
*/
2024
public File lookup(String source, ExtractorConfig config, FileExtractor.FileType type);
25+
26+
/**
27+
* Build a TRAP cache as defined by the extractor options, which are read from the corresponding
28+
* environment variables as defined in
29+
* https://github.com/github/codeql-core/blob/main/design/spec/codeql-extractors.md
30+
*
31+
* @return a TRAP cache
32+
*/
33+
public static ITrapCache fromExtractorOptions() {
34+
String trapCachePath = readExtractorOption("trap", "cache", "dir");
35+
if (trapCachePath != null) {
36+
Long sizeBound = null;
37+
String trapCacheBound = readExtractorOption("trap", "cache", "bound");
38+
if (trapCacheBound != null) {
39+
sizeBound = DefaultTrapCache.asFileSize(trapCacheBound);
40+
if (sizeBound == null)
41+
throw new UserError("Invalid TRAP cache size bound: " + trapCacheBound);
42+
}
43+
boolean writeable = true;
44+
String trapCacheWrite = readExtractorOption("trap", "cache", "write");
45+
if (trapCacheWrite != null) writeable = trapCacheWrite.equalsIgnoreCase("TRUE");
46+
return new DefaultTrapCache(trapCachePath, sizeBound, Main.EXTRACTOR_VERSION, writeable);
47+
}
48+
return new DummyTrapCache();
49+
}
2150
}

0 commit comments

Comments
 (0)