Skip to content

Commit 38b9d2d

Browse files
committed
Fix handling of symlinked projects
- HistoryGuru etc. will operate correctly and no longer throw exceptions. - index.jsp will show symlinked projects. - Fix macOS regression in Oracle PR #1846.
1 parent c790eb7 commit 38b9d2d

20 files changed

+481
-99
lines changed

src/org/opensolaris/opengrok/configuration/RuntimeEnvironment.java

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
101101
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
102102
import static org.opensolaris.opengrok.configuration.Configuration.makeXMLStringAsConfiguration;
103+
import org.opensolaris.opengrok.util.PathUtils;
103104

104105
/**
105106
* The RuntimeEnvironment class is used as a placeholder for the current
@@ -135,7 +136,7 @@ public final class RuntimeEnvironment {
135136

136137
private Statistics statistics = new Statistics();
137138

138-
private static IndexTimestamp indexTime = new IndexTimestamp();
139+
private static final IndexTimestamp indexTime = new IndexTimestamp();
139140

140141
/**
141142
* Instance of authorization framework.
@@ -390,24 +391,24 @@ public String getPathRelativeToSourceRoot(File file) throws IOException {
390391
* @return Path relative to source root
391392
*/
392393
public String getPathRelativeToSourceRoot(File file, int stripCount) throws IOException {
393-
String canonicalPath = file.getCanonicalPath();
394394
String sourceRoot = getSourceRootPath();
395-
396-
if(sourceRoot == null){
395+
if (sourceRoot == null) {
397396
throw new FileNotFoundException("Source Root Not Found");
398397
}
399-
400-
if (canonicalPath.startsWith(sourceRoot)) {
401-
return canonicalPath.substring(sourceRoot.length() + stripCount);
402-
}
403-
for (String allowedSymlink : getAllowedSymlinks()) {
404-
String allowedTarget = new File(allowedSymlink).getCanonicalPath();
405-
if (canonicalPath.startsWith(allowedTarget)) {
406-
return canonicalPath.substring(allowedTarget.length()
407-
+ stripCount);
408-
}
398+
399+
String maybeRelPath = PathUtils.getRelativeToCanonical(file.getPath(),
400+
sourceRoot, getAllowedSymlinks());
401+
File maybeRelFile = new File(maybeRelPath);
402+
if (!maybeRelFile.isAbsolute()) {
403+
// N.b. OpenGrok has a weird convention that
404+
// source-root "relative" paths must start with a '/' as they are
405+
// elsewhere directly appended to env.getSourceRootPath() and also
406+
// stored as such.
407+
maybeRelPath = File.separator + maybeRelPath;
408+
return maybeRelPath.substring(stripCount);
409409
}
410-
throw new FileNotFoundException("Failed to resolve [" + canonicalPath
410+
411+
throw new FileNotFoundException("Failed to resolve [" + file.getPath()
411412
+ "] relative to source root [" + sourceRoot + "]");
412413
}
413414

@@ -1717,7 +1718,7 @@ public void applyConfig(Message m, boolean reindex) {
17171718
try {
17181719
config = makeXMLStringAsConfiguration(m.getText());
17191720
} catch (IOException ex) {
1720-
LOGGER.log(Level.WARNING, "Configuration decoding failed" + ex);
1721+
LOGGER.log(Level.WARNING, "Configuration decoding failed", ex);
17211722
return;
17221723
}
17231724

src/org/opensolaris/opengrok/history/BazaarRepository.java

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

2020
/*
2121
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.history;
2425

@@ -80,11 +81,7 @@ public BazaarRepository() {
8081
*/
8182
Executor getHistoryLogExecutor(final File file, final String sinceRevision)
8283
throws IOException {
83-
String abs = file.getCanonicalPath();
84-
String filename = "";
85-
if (abs.length() > getDirectoryName().length()) {
86-
filename = abs.substring(getDirectoryName().length() + 1);
87-
}
84+
String filename = getRepoRelativePath(file);
8885

8986
List<String> cmd = new ArrayList<String>();
9087
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);

src/org/opensolaris/opengrok/history/CVSRepository.java

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

2020
/*
2121
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.history;
2425

@@ -96,8 +97,8 @@ public boolean isWorking() {
9697
}
9798

9899
@Override
99-
public void setDirectoryName(String directoryName) {
100-
super.setDirectoryName(directoryName);
100+
public void setDirectoryName(File directory) {
101+
super.setDirectoryName(directory);
101102

102103
if (isWorking()) {
103104
File rootFile = new File(getDirectoryName() + File.separatorChar
@@ -195,11 +196,7 @@ String determineBranch() throws IOException {
195196
* @return An Executor ready to be started
196197
*/
197198
Executor getHistoryLogExecutor(final File file) throws IOException {
198-
String abs = file.getCanonicalPath();
199-
String filename = "";
200-
if (abs.length() > getDirectoryName().length()) {
201-
filename = abs.substring(getDirectoryName().length() + 1);
202-
}
199+
String filename = getRepoRelativePath(file);
203200

204201
List<String> cmd = new ArrayList<>();
205202
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);

src/org/opensolaris/opengrok/history/ClearCaseRepository.java

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

2020
/*
2121
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.history;
2425

@@ -93,11 +94,7 @@ public void setVerbose(boolean verbose) {
9394
* @return An Executor ready to be started
9495
*/
9596
Executor getHistoryLogExecutor(final File file) throws IOException {
96-
String abs = file.getCanonicalPath();
97-
String filename = "";
98-
if (abs.length() > getDirectoryName().length()) {
99-
filename = abs.substring(getDirectoryName().length() + 1);
100-
}
97+
String filename = getRepoRelativePath(file);
10198

10299
List<String> cmd = new ArrayList<>();
103100
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);

src/org/opensolaris/opengrok/history/GitRepository.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
* CDDL HEADER END
1818
*/
1919

20-
/*
20+
/*
2121
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.history;
2425

@@ -31,7 +32,6 @@
3132
import java.io.InputStreamReader;
3233
import java.io.Reader;
3334
import java.text.ParseException;
34-
import java.text.SimpleDateFormat;
3535
import java.util.ArrayList;
3636
import java.util.Date;
3737
import java.util.LinkedList;
@@ -116,11 +116,7 @@ public GitRepository() {
116116
Executor getHistoryLogExecutor(final File file, String sinceRevision)
117117
throws IOException {
118118

119-
String abs = file.getCanonicalPath();
120-
String filename = "";
121-
if (abs.length() > getDirectoryName().length()) {
122-
filename = abs.substring(getDirectoryName().length() + 1);
123-
}
119+
String filename = getRepoRelativePath(file);
124120

125121
List<String> cmd = new ArrayList<>();
126122
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);

src/org/opensolaris/opengrok/history/HistoryGuru.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.history;
2425

@@ -27,6 +28,7 @@
2728
import java.io.InputStream;
2829
import java.lang.reflect.InvocationTargetException;
2930
import java.nio.file.Path;
31+
import java.nio.file.Paths;
3032
import java.util.ArrayList;
3133
import java.util.Collection;
3234
import java.util.Collections;
@@ -39,7 +41,6 @@
3941
import java.util.concurrent.CountDownLatch;
4042
import java.util.concurrent.ExecutorService;
4143
import java.util.concurrent.Executors;
42-
import java.util.concurrent.Semaphore;
4344
import java.util.concurrent.ThreadFactory;
4445
import java.util.concurrent.TimeUnit;
4546
import java.util.logging.Level;
@@ -49,6 +50,7 @@
4950
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
5051
import org.opensolaris.opengrok.index.IgnoredNames;
5152
import org.opensolaris.opengrok.logger.LoggerFactory;
53+
import org.opensolaris.opengrok.util.PathUtils;
5254
import org.opensolaris.opengrok.util.Statistics;
5355

5456
/**
@@ -76,6 +78,12 @@ public final class HistoryGuru {
7678
*/
7779
private Map<String, Repository> repositories = new ConcurrentHashMap<>();
7880

81+
/**
82+
* set of repository roots (using ConcurrentHashMap but a throwaway value)
83+
* with parent of {@code DirectoryName} as key
84+
*/
85+
private Map<String, String> repositoryRoots = new ConcurrentHashMap<>();
86+
7987
private final int scanningDepth;
8088

8189
/**
@@ -415,7 +423,11 @@ private Collection<RepositoryInfo> addRepositories(File[] files,
415423
}
416424

417425
repoList.add(new RepositoryInfo(repository));
418-
repositories.put(repository.getDirectoryName(), repository);
426+
String repoDirectoryName = repository.getDirectoryName();
427+
File repoDirectoryFile = new File(repoDirectoryName);
428+
String repoDirParent = repoDirectoryFile.getParent();
429+
repositoryRoots.put(repoDirParent, "");
430+
repositories.put(repoDirectoryName, repository);
419431

420432
// @TODO: Search only for one type of repository - the one found here
421433
if (recursiveSearch && repository.supportsSubRepositories()) {
@@ -829,12 +841,27 @@ public void ensureHistoryCacheExists(File file) throws HistoryException {
829841

830842
protected Repository getRepository(File path) {
831843
File file = path;
844+
Set<String> rootKeys = repositoryRoots.keySet();
832845

833846
while (file != null) {
834-
Repository r = repositories.get(file.getAbsolutePath());
835-
if (r != null) {
836-
return r;
847+
String nextPath = file.getPath();
848+
for (String rootKey : rootKeys) {
849+
String rel;
850+
try {
851+
rel = PathUtils.getRelativeToCanonical(nextPath, rootKey);
852+
} catch (IOException e) {
853+
LOGGER.log(Level.WARNING,
854+
"Failed to get relative to canonical for " + nextPath,
855+
e);
856+
return null;
857+
}
858+
String inRootPath = Paths.get(rootKey, rel).toString();
859+
Repository r = repositories.get(inRootPath);
860+
if (r != null) {
861+
return r;
862+
}
837863
}
864+
838865
file = file.getParentFile();
839866
}
840867

src/org/opensolaris/opengrok/history/MercurialRepository.java

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

2020
/*
2121
* Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.history;
2425

@@ -152,14 +153,9 @@ String determineBranch() throws IOException {
152153
*/
153154
Executor getHistoryLogExecutor(File file, String sinceRevision)
154155
throws HistoryException, IOException {
155-
String abs = file.getCanonicalPath();
156-
String filename = "";
156+
String filename = getRepoRelativePath(file);
157157
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
158158

159-
if (abs.length() > getDirectoryName().length()) {
160-
filename = abs.substring(getDirectoryName().length() + 1);
161-
}
162-
163159
List<String> cmd = new ArrayList<>();
164160
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);
165161
cmd.add(RepoCommand);

src/org/opensolaris/opengrok/history/MonotoneRepository.java

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

2020
/*
2121
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
package org.opensolaris.opengrok.history;
2425

@@ -124,11 +125,7 @@ public InputStream getHistoryGet(String parent, String basename, String rev) {
124125
*/
125126
Executor getHistoryLogExecutor(File file, String sinceRevision)
126127
throws IOException {
127-
String abs = file.getCanonicalPath();
128-
String filename = "";
129-
if (abs.length() > getDirectoryName().length()) {
130-
filename = abs.substring(getDirectoryName().length() + 1);
131-
}
128+
String filename = getRepoRelativePath(file);
132129

133130
List<String> cmd = new ArrayList<>();
134131
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);

src/org/opensolaris/opengrok/history/RazorRepository.java

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

2020
/*
2121
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
22+
* Portions Copyright (c) 2017, Chris Fraire <[email protected]>.
2223
*/
2324
/* Portions Copyright 2008 Peter Bray */
2425
package org.opensolaris.opengrok.history;
@@ -157,13 +158,12 @@ public RazorRepository() {
157158
}
158159

159160
@Override
160-
public void setDirectoryName(String directoryName) {
161-
super.setDirectoryName(directoryName);
162-
File opengrokBaseDirectory = new File(directoryName);
161+
public void setDirectoryName(File directory) {
162+
super.setDirectoryName(directory);
163163
opengrokSourceRootDirectoryPath
164-
= opengrokBaseDirectory.getParentFile().getAbsolutePath();
164+
= directory.getParentFile().getAbsolutePath();
165165
razorGroupBaseDirectoryPath
166-
= new File(directoryName, RAZOR_DIR).getAbsolutePath();
166+
= new File(directory, RAZOR_DIR).getAbsolutePath();
167167
}
168168

169169
public String getOpengrokSourceRootDirectoryPath() {

src/org/opensolaris/opengrok/history/Repository.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,4 +526,25 @@ protected String ensureCommand(String propertyKey, String fallbackCommand) {
526526
}
527527
return RepoCommand;
528528
}
529+
530+
protected String getRepoRelativePath(final File file)
531+
throws IOException {
532+
533+
String filename = file.getPath();
534+
String repoDirName = getDirectoryName();
535+
536+
String abs = file.getCanonicalPath();
537+
if (abs.startsWith(repoDirName)) {
538+
if (abs.length() > repoDirName.length()) {
539+
filename = abs.substring(repoDirName.length() + 1);
540+
}
541+
} else {
542+
abs = file.getAbsolutePath();
543+
if (abs.startsWith(repoDirName) && abs.length() >
544+
repoDirName.length()) {
545+
filename = abs.substring(repoDirName.length() + 1);
546+
}
547+
}
548+
return filename;
549+
}
529550
}

0 commit comments

Comments
 (0)