Skip to content

Commit 9c92ca9

Browse files
committed
Also get --list-languages. getCtags() is always defined
1 parent 2d875dd commit 9c92ca9

File tree

13 files changed

+134
-62
lines changed

13 files changed

+134
-62
lines changed

opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/Ctags.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public class Ctags implements Resettable {
5959

6060
private static final Logger LOGGER = LoggerFactory.getLogger(Ctags.class);
6161

62+
private final RuntimeEnvironment env;
6263
private volatile boolean closing;
6364
private final LangTreeMap defaultLangMap = new LangTreeMap();
6465
private LangMap langMap;
@@ -67,13 +68,16 @@ public class Ctags implements Resettable {
6768
private OutputStreamWriter ctagsIn;
6869
private BufferedReader ctagsOut;
6970
private static final String CTAGS_FILTER_TERMINATOR = "__ctags_done_with_file__";
70-
private String binary;
7171
private String CTagsExtraOptionsFile = null;
7272
private int tabSize;
7373
private Duration timeout = Duration.ofSeconds(10);
7474

7575
private boolean junit_testing = false;
7676

77+
public Ctags() {
78+
env = RuntimeEnvironment.getInstance();
79+
}
80+
7781
/**
7882
* Gets a value indicating if a subprocess of ctags was started and it is
7983
* not alive.
@@ -84,14 +88,6 @@ public boolean isClosed() {
8488
return ctags != null && !ctags.isAlive();
8589
}
8690

87-
public String getBinary() {
88-
return binary;
89-
}
90-
91-
public void setBinary(String binary) {
92-
this.binary = binary;
93-
}
94-
9591
public void setLangMap(LangMap langMap) {
9692
this.langMap = langMap;
9793
}
@@ -150,7 +146,7 @@ public List<String> getArgv() {
150146
private void initialize() {
151147
command = new ArrayList<>();
152148

153-
command.add(binary);
149+
command.add(env.getCtags());
154150
command.add("--c-kinds=+l");
155151

156152
// Workaround for bug #14924: Don't get local variables in Java
@@ -442,7 +438,7 @@ public Definitions doCtags(String file) throws IOException,
442438
* the ctags process completes so that the indexer can
443439
* make progress instead of hanging the whole operation.
444440
*/
445-
IndexerParallelizer parallelizer = RuntimeEnvironment.getInstance().getIndexerParallelizer();
441+
IndexerParallelizer parallelizer = env.getIndexerParallelizer();
446442
ExecutorService executor = parallelizer.getCtagsWatcherExecutor();
447443
Future<Definitions> future = executor.submit(() -> {
448444
readTags(rdr);

opengrok-indexer/src/main/java/org/opengrok/indexer/configuration/RuntimeEnvironment.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.util.ArrayList;
3535
import java.util.Collections;
3636
import java.util.Date;
37+
import java.util.HashSet;
3738
import java.util.List;
3839
import java.util.Map;
3940
import java.util.Set;
@@ -121,6 +122,11 @@ public final class RuntimeEnvironment {
121122

122123
private transient File dtagsEftar = null;
123124

125+
private transient volatile Boolean ctagsFound;
126+
private final transient Set<String> ctagsLanguages = new HashSet<>();
127+
128+
public WatchDogService watchDog;
129+
124130
/**
125131
* Creates a new instance of RuntimeEnvironment. Private to ensure a
126132
* singleton anti-pattern.
@@ -180,8 +186,6 @@ public static RuntimeEnvironment getInstance() {
180186
return instance;
181187
}
182188

183-
public WatchDogService watchDog;
184-
185189
public IndexerParallelizer getIndexerParallelizer() {
186190
return lzIndexerParallelizer.get();
187191
}
@@ -641,24 +645,42 @@ public void setHitsPerPage(int hitsPerPage) {
641645
setConfigurationValue("hitsPerPage", hitsPerPage);
642646
}
643647

644-
private transient Boolean ctagsFound;
645-
646648
/**
647649
* Validate that there is a Universal ctags program.
648650
*
649651
* @return true if success, false otherwise
650652
*/
651653
public boolean validateUniversalCtags() {
652654
if (ctagsFound == null) {
653-
if (!CtagsUtil.validate(getCtags())) {
654-
ctagsFound = false;
655-
} else {
656-
ctagsFound = true;
655+
String ctagsBinary = getCtags();
656+
configLock.writeLock().lock();
657+
try {
658+
if (ctagsFound == null) {
659+
ctagsFound = CtagsUtil.validate(ctagsBinary);
660+
if (ctagsFound) {
661+
List<String> languages = CtagsUtil.getLanguages(ctagsBinary);
662+
if (languages != null) {
663+
ctagsLanguages.addAll(languages);
664+
}
665+
}
666+
}
667+
} finally {
668+
configLock.writeLock().unlock();
657669
}
658670
}
659671
return ctagsFound;
660672
}
661673

674+
/**
675+
* Gets the base set of supported Ctags languages.
676+
* @return a defined set which may be empty if
677+
* {@link #validateUniversalCtags()} has not yet been called or if the call
678+
* fails
679+
*/
680+
public Set<String> getCtagsLanguages() {
681+
return Collections.unmodifiableSet(ctagsLanguages);
682+
}
683+
662684
/**
663685
* Get the max time a SCM operation may use to avoid being cached.
664686
*

opengrok-indexer/src/main/java/org/opengrok/indexer/index/IndexDatabase.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -742,9 +742,7 @@ private void addFile(File file, String path, Ctags ctags)
742742
if (env.getCtagsTimeout() != 0) {
743743
ctags.setTimeout(env.getCtagsTimeout());
744744
}
745-
if (ctags.getBinary() != null) {
746-
fa.setCtags(ctags);
747-
}
745+
fa.setCtags(ctags);
748746
fa.setProject(Project.getProject(path));
749747
fa.setScopesEnabled(env.isScopesEnabled());
750748
fa.setFoldingEnabled(env.isFoldingEnabled());

opengrok-indexer/src/main/java/org/opengrok/indexer/util/CtagsUtil.java

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import org.opengrok.indexer.configuration.RuntimeEnvironment;
3030
import org.opengrok.indexer.logger.LoggerFactory;
3131

32+
import java.util.ArrayList;
33+
import java.util.List;
3234
import java.util.logging.Level;
3335
import java.util.logging.Logger;
3436

@@ -58,26 +60,44 @@ public static boolean validate(String ctagsBinary) {
5860
return true;
5961
}
6062

63+
/**
64+
* Gets the base set of languages by executing {@code --list-languages} for
65+
* the specified binary.
66+
* @return {@code null} on failure to run, or a defined list
67+
*/
68+
public static List<String> getLanguages(String ctagsBinary) {
69+
Executor executor = new Executor(new String[]{ctagsBinary, "--list-languages"});
70+
int rc = executor.exec(false);
71+
String output = executor.getOutputString();
72+
if (output == null || rc != 0) {
73+
LOGGER.log(Level.WARNING, "Failed to get Ctags languages");
74+
return null;
75+
}
76+
77+
output = output.replaceAll("\\s+\\[disabled]", "");
78+
String[] split = output.split("(?m)$");
79+
List<String> result = new ArrayList<>();
80+
for (String lang : split) {
81+
lang = lang.trim();
82+
if (lang.length() > 0) {
83+
result.add(lang);
84+
}
85+
}
86+
return result;
87+
}
88+
6189
/**
6290
* Creates a new instance, and attempts to configure it from the
6391
* environment.
64-
* @return a defined instance, possibly with a {@code null} ctags binary
65-
* setting if a value was not available from {@link RuntimeEnvironment}.
92+
* @return a defined instance
6693
*/
6794
public static Ctags newInstance(RuntimeEnvironment env) {
6895
Ctags ctags = new Ctags();
96+
ctags.setLangMap(AnalyzerGuru.getLangMap());
6997

70-
String ctagsBinary = env.getCtags();
71-
if (ctagsBinary == null) {
72-
LOGGER.severe("Unable to run ctags! Searching definitions will not work!");
73-
} else {
74-
ctags.setBinary(ctagsBinary);
75-
ctags.setLangMap(AnalyzerGuru.getLangMap());
76-
77-
String filename = env.getCTagsExtraOptionsFile();
78-
if (filename != null) {
79-
ctags.setCTagsExtraOptionsFile(filename);
80-
}
98+
String filename = env.getCTagsExtraOptionsFile();
99+
if (filename != null) {
100+
ctags.setCTagsExtraOptionsFile(filename);
81101
}
82102
return ctags;
83103
}

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/CtagsTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
22-
* Portions Copyright (c) 2017-2018, Chris Fraire <[email protected]>.
22+
* Portions Copyright (c) 2017-2019, Chris Fraire <[email protected]>.
2323
*/
2424

2525
package org.opengrok.indexer.analysis;
@@ -34,7 +34,6 @@
3434
import org.opengrok.indexer.condition.ConditionalRun;
3535
import org.opengrok.indexer.condition.ConditionalRunRule;
3636
import org.opengrok.indexer.condition.CtagsInstalled;
37-
import org.opengrok.indexer.configuration.RuntimeEnvironment;
3837
import org.opengrok.indexer.util.TestRepository;
3938

4039
/**
@@ -53,7 +52,6 @@ public class CtagsTest {
5352
@BeforeClass
5453
public static void setUpClass() throws Exception {
5554
ctags = new Ctags();
56-
ctags.setBinary(RuntimeEnvironment.getInstance().getCtags());
5755

5856
repository = new TestRepository();
5957
repository.create(CtagsTest.class.getResourceAsStream(
@@ -71,7 +69,7 @@ public static void setUpClass() throws Exception {
7169
}
7270

7371
@AfterClass
74-
public static void tearDownClass() throws Exception {
72+
public static void tearDownClass() {
7573
ctags.close();
7674
ctags = null;
7775
repository.destroy();

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/JFlexXrefTest.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
22-
* Portions Copyright (c) 2017-2018, Chris Fraire <[email protected]>.
22+
* Portions Copyright (c) 2017-2019, Chris Fraire <[email protected]>.
2323
*/
2424

2525
package org.opengrok.indexer.analysis;
@@ -61,7 +61,6 @@
6161
import org.opengrok.indexer.condition.ConditionalRun;
6262
import org.opengrok.indexer.condition.ConditionalRunRule;
6363
import org.opengrok.indexer.condition.CtagsInstalled;
64-
import org.opengrok.indexer.configuration.RuntimeEnvironment;
6564
import static org.opengrok.indexer.util.CustomAssertions.assertLinesEqual;
6665
import org.opengrok.indexer.util.TestRepository;
6766
import org.xml.sax.InputSource;
@@ -87,14 +86,13 @@ public class JFlexXrefTest {
8786
@BeforeClass
8887
public static void setUpClass() throws Exception {
8988
ctags = new Ctags();
90-
ctags.setBinary(RuntimeEnvironment.getInstance().getCtags());
9189
repository = new TestRepository();
9290
repository.create(JFlexXrefTest.class.getResourceAsStream(
9391
"/org/opengrok/indexer/index/source.zip"));
9492
}
9593

9694
@AfterClass
97-
public static void tearDownClass() throws Exception {
95+
public static void tearDownClass() {
9896
ctags.close();
9997
ctags = null;
10098
repository.destroy();

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/c/CAnalyzerFactoryTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
22-
* Portions Copyright (c) 2017-2018, Chris Fraire <[email protected]>.
22+
* Portions Copyright (c) 2017-2019, Chris Fraire <[email protected]>.
2323
*/
2424
package org.opengrok.indexer.analysis.c;
2525

@@ -80,7 +80,6 @@ public InputStream getStream() throws IOException {
8080
@BeforeClass
8181
public static void setUpClass() throws Exception {
8282
ctags = new Ctags();
83-
ctags.setBinary(RuntimeEnvironment.getInstance().getCtags());
8483

8584
repository = new TestRepository();
8685
repository.create(CAnalyzerFactoryTest.class.getResourceAsStream(
@@ -95,7 +94,7 @@ public static void setUpClass() throws Exception {
9594
}
9695

9796
@AfterClass
98-
public static void tearDownClass() throws Exception {
97+
public static void tearDownClass() {
9998
ctags.close();
10099
ctags = null;
101100
}

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/c/CxxAnalyzerFactoryTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
22-
* Portions Copyright (c) 2017-2018, Chris Fraire <[email protected]>.
22+
* Portions Copyright (c) 2017-2019, Chris Fraire <[email protected]>.
2323
*/
2424
package org.opengrok.indexer.analysis.c;
2525

@@ -80,7 +80,6 @@ public InputStream getStream() throws IOException {
8080
@BeforeClass
8181
public static void setUpClass() throws Exception {
8282
ctags = new Ctags();
83-
ctags.setBinary(RuntimeEnvironment.getInstance().getCtags());
8483

8584
repository = new TestRepository();
8685
repository.create(CxxAnalyzerFactoryTest.class.getResourceAsStream(
@@ -95,7 +94,7 @@ public static void setUpClass() throws Exception {
9594
}
9695

9796
@AfterClass
98-
public static void tearDownClass() throws Exception {
97+
public static void tearDownClass() {
9998
ctags.close();
10099
ctags = null;
101100
}

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/clojure/ClojureAnalyzerFactoryTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2016, 2018 Oracle and/or its affiliates. All rights reserved.
22-
* Portions Copyright (c) 2017-2018, Chris Fraire <[email protected]>.
22+
* Portions Copyright (c) 2017-2019, Chris Fraire <[email protected]>.
2323
*/
2424
package org.opengrok.indexer.analysis.clojure;
2525

@@ -77,7 +77,6 @@ public InputStream getStream() throws IOException {
7777
@BeforeClass
7878
public static void setUpClass() throws Exception {
7979
ctags = new Ctags();
80-
ctags.setBinary(RuntimeEnvironment.getInstance().getCtags());
8180

8281
repository = new TestRepository();
8382
repository.create(ClojureAnalyzerFactoryTest.class.getResourceAsStream(

opengrok-indexer/src/test/java/org/opengrok/indexer/analysis/csharp/CSharpAnalyzerFactoryTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
22-
* Portions Copyright (c) 2017-2018, Chris Fraire <[email protected]>.
22+
* Portions Copyright (c) 2017-2019, Chris Fraire <[email protected]>.
2323
*/
2424
package org.opengrok.indexer.analysis.csharp;
2525

@@ -76,7 +76,6 @@ public InputStream getStream() throws IOException {
7676
@BeforeClass
7777
public static void setUpClass() throws Exception {
7878
ctags = new Ctags();
79-
ctags.setBinary(RuntimeEnvironment.getInstance().getCtags());
8079

8180
repository = new TestRepository();
8281
repository.create(CSharpAnalyzerFactoryTest.class.getResourceAsStream(
@@ -91,7 +90,7 @@ public static void setUpClass() throws Exception {
9190
}
9291

9392
@AfterClass
94-
public static void tearDownClass() throws Exception {
93+
public static void tearDownClass() {
9594
ctags.close();
9695
ctags = null;
9796
}

0 commit comments

Comments
 (0)