Skip to content

Commit 0ad4423

Browse files
idodeclareVladimir Kotal
authored andcommitted
Fixes #2900 : Add Repository isNestable() property
- Set new property to true for Git and Mercurial. - Do not limit nested repos only to same type as parent.
1 parent 1cbb059 commit 0ad4423

File tree

7 files changed

+76
-49
lines changed

7 files changed

+76
-49
lines changed

opengrok-indexer/src/main/java/org/opengrok/indexer/history/GitRepository.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,15 @@ boolean supportsSubRepositories() {
536536
return true;
537537
}
538538

539+
/**
540+
* Gets a value indicating the instance is nestable.
541+
* @return {@code true}
542+
*/
543+
@Override
544+
boolean isNestable() {
545+
return true;
546+
}
547+
539548
@Override
540549
public boolean isWorking() {
541550
if (working == null) {

opengrok-indexer/src/main/java/org/opengrok/indexer/history/HistoryGuru.java

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

2020
/*
2121
* Copyright (c) 2005, 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
package org.opengrok.indexer.history;
2525

@@ -387,13 +387,15 @@ public Map<String, Date> getLastModifiedTimes(File directory)
387387
* @param files list of files to check if they contain a repository
388388
* @param ignoredNames what files to ignore
389389
* @param recursiveSearch whether to use recursive search
390-
* @param type type of the repository to search for or {@code null}
391390
* @param depth current depth - using global scanningDepth - one can limit
392391
* this to improve scanning performance
392+
* @param isNested a value indicating if a parent {@link Repository} was
393+
* already found above the {@code files}
393394
* @return collection of added repositories
394395
*/
395396
private Collection<RepositoryInfo> addRepositories(File[] files,
396-
IgnoredNames ignoredNames, boolean recursiveSearch, String type, int depth) {
397+
IgnoredNames ignoredNames, boolean recursiveSearch, int depth,
398+
boolean isNested) {
397399

398400
List<RepositoryInfo> repoList = new ArrayList<>();
399401

@@ -408,7 +410,7 @@ private Collection<RepositoryInfo> addRepositories(File[] files,
408410

409411
Repository repository = null;
410412
try {
411-
repository = RepositoryFactory.getRepository(file, type);
413+
repository = RepositoryFactory.getRepository(file, false, isNested);
412414
} catch (InstantiationException | NoSuchMethodException | InvocationTargetException e) {
413415
LOGGER.log(Level.WARNING, "Could not create repository for '"
414416
+ file + "', could not instantiate the repository.", e);
@@ -429,8 +431,8 @@ private Collection<RepositoryInfo> addRepositories(File[] files,
429431
"check access permissions.",
430432
file.getAbsolutePath());
431433
} else if (depth <= scanningDepth) {
432-
repoList.addAll(HistoryGuru.this.addRepositories(subFiles, ignoredNames,
433-
recursiveSearch, type, depth + 1));
434+
repoList.addAll(addRepositories(subFiles, ignoredNames,
435+
recursiveSearch, depth + 1, isNested));
434436
}
435437
}
436438
} else {
@@ -447,9 +449,10 @@ private Collection<RepositoryInfo> addRepositories(File[] files,
447449
"Failed to get sub directories for ''{0}'', check access permissions.",
448450
file.getAbsolutePath());
449451
} else if (depth <= scanningDepth) {
450-
// Search only for one type of repository - the one found here.
451-
repoList.addAll(HistoryGuru.this.addRepositories(subFiles, ignoredNames,
452-
false, repository.getType(), depth + 1));
452+
// Search only one level down - if not: too much
453+
// stat'ing for huge Mercurial repositories
454+
repoList.addAll(addRepositories(subFiles, ignoredNames,
455+
false, depth + 1, true));
453456
}
454457
}
455458
}
@@ -464,13 +467,6 @@ private Collection<RepositoryInfo> addRepositories(File[] files,
464467
return repoList;
465468
}
466469

467-
private Collection<RepositoryInfo>
468-
addRepositories(File[] files, Collection<RepositoryInfo> repos,
469-
IgnoredNames ignoredNames, int depth) {
470-
471-
return HistoryGuru.this.addRepositories(files, ignoredNames, true, null, depth);
472-
}
473-
474470
/**
475471
* Recursively search for repositories in given directories, add those found
476472
* to the internally used repository map.
@@ -482,7 +478,7 @@ private Collection<RepositoryInfo> addRepositories(File[] files,
482478
public Collection<RepositoryInfo> addRepositories(File[] files,
483479
IgnoredNames ignoredNames) {
484480

485-
return HistoryGuru.this.addRepositories(files, ignoredNames, true, null, 0);
481+
return addRepositories(files, ignoredNames, true, 0, false);
486482
}
487483

488484
/**
@@ -496,7 +492,7 @@ public Collection<RepositoryInfo> addRepositories(File[] files,
496492
public Collection<RepositoryInfo> addRepositories(Collection<String> repos,
497493
IgnoredNames ignoredNames) {
498494

499-
return HistoryGuru.this.addRepositories(repos.stream().
495+
return addRepositories(repos.stream().
500496
map(r -> new File(r)).
501497
collect(Collectors.toList()).toArray(new File[0]), ignoredNames);
502498
}

opengrok-indexer/src/main/java/org/opengrok/indexer/history/MercurialRepository.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2006, 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
package org.opengrok.indexer.history;
2525

@@ -493,6 +493,15 @@ boolean supportsSubRepositories() {
493493
: Boolean.parseBoolean(val));
494494
}
495495

496+
/**
497+
* Gets a value indicating the instance is nestable.
498+
* @return {@code true}
499+
*/
500+
@Override
501+
boolean isNestable() {
502+
return true;
503+
}
504+
496505
@Override
497506
public boolean isWorking() {
498507
if (working == null) {

opengrok-indexer/src/main/java/org/opengrok/indexer/history/Repository.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/*
2121
* Copyright (c) 2008, 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.history;
2525

@@ -506,6 +506,14 @@ boolean supportsSubRepositories() {
506506
return false;
507507
}
508508

509+
/**
510+
* Subclasses can override to get a value indicating that a repository implementation is nestable.
511+
* @return {@code false}
512+
*/
513+
boolean isNestable() {
514+
return false;
515+
}
516+
509517
private DateFormat getDateFormat() {
510518
return new RepositoryDateFormat();
511519
}

opengrok-indexer/src/main/java/org/opengrok/indexer/history/RepositoryFactory.java

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

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

@@ -81,18 +81,24 @@ public static List<Class<? extends Repository>> getRepositoryClasses() {
8181
return list;
8282
}
8383

84-
public static Repository getRepository(File file, String type)
84+
/**
85+
* Calls {@link #getRepository(File, boolean)} with {@code file} and {@code false}.
86+
*/
87+
public static Repository getRepository(File file)
8588
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException,
8689
IOException, ForbiddenSymlinkException {
87-
return getRepository(file, false, type);
90+
return getRepository(file, false);
8891
}
8992

90-
public static Repository getRepository(File file)
91-
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException,
92-
IOException, ForbiddenSymlinkException {
93-
return getRepository(file, false, null);
93+
/**
94+
* Calls {@link #getRepository(File, boolean, boolean)} with {@code file}, {@code interactive}, and {@code false}.
95+
*/
96+
public static Repository getRepository(File file, boolean interactive)
97+
throws IllegalAccessException, InvocationTargetException, ForbiddenSymlinkException, InstantiationException,
98+
NoSuchMethodException, IOException {
99+
return getRepository(file, interactive, false);
94100
}
95-
101+
96102
/**
97103
* Returns a repository for the given file, or null if no repository was
98104
* found.
@@ -104,8 +110,8 @@ public static Repository getRepository(File file)
104110
* use interactive command timeout (as specified in {@code Configuration}).
105111
*
106112
* @param file File that might contain a repository
107-
* @param interactive true if running in interactive mode
108-
* @param type type of the repository to search for or {@code null}
113+
* @param interactive a value indicating if running in interactive mode
114+
* @param isNested a value indicating if a nestable {@link Repository} is required
109115
* @return Correct repository for the given file
110116
* @throws InstantiationException in case we cannot create the repository object
111117
* @throws IllegalAccessException in case no permissions to repository file
@@ -114,18 +120,14 @@ public static Repository getRepository(File file)
114120
* @throws IOException when resolving repository path
115121
* @throws ForbiddenSymlinkException when resolving repository path
116122
*/
117-
public static Repository getRepository(File file, boolean interactive, String type)
123+
public static Repository getRepository(File file, boolean interactive, boolean isNested)
118124
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException,
119125
IOException, ForbiddenSymlinkException {
120126
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
121127
Repository repo = null;
122128

123129
for (Repository rep : repositories) {
124-
if (type != null && !type.equals(rep.getType())) {
125-
continue;
126-
}
127-
128-
if (rep.isRepositoryFor(file, interactive)) {
130+
if ((!isNested || rep.isNestable()) && rep.isRepositoryFor(file, interactive)) {
129131
repo = rep.getClass().getDeclaredConstructor().newInstance();
130132

131133
if (env.isProjectsEnabled() && env.getPathRelativeToSourceRoot(file).equals(File.separator)) {
@@ -212,7 +214,7 @@ public static Repository getRepository(File file, boolean interactive, String ty
212214
public static Repository getRepository(RepositoryInfo info, boolean interactive)
213215
throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException,
214216
IOException, ForbiddenSymlinkException {
215-
return getRepository(new File(info.getDirectoryName()), interactive, null);
217+
return getRepository(new File(info.getDirectoryName()), interactive);
216218
}
217219

218220
/**

opengrok-indexer/src/test/java/org/opengrok/indexer/history/CVSRepositoryTest.java

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

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

@@ -102,7 +102,7 @@ public void setUp() {
102102
* @param reposRoot directory of the repository root
103103
* @param args arguments to use for the command
104104
*/
105-
private static void runCvsCommand(File reposRoot, String ... args) {
105+
public static void runCvsCommand(File reposRoot, String ... args) {
106106
List<String> cmdargs = new ArrayList<>();
107107
CVSRepository repo = new CVSRepository();
108108
cmdargs.add(repo.getRepoCommand());

opengrok-indexer/src/test/java/org/opengrok/indexer/history/HistoryGuruTest.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@
1919

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

26+
import static org.junit.Assert.assertEquals;
27+
import static org.junit.Assert.assertNotNull;
28+
import static org.junit.Assert.assertTrue;
29+
2530
import java.io.File;
2631
import java.io.IOException;
2732
import java.io.InputStream;
@@ -43,8 +48,6 @@
4348
import org.opengrok.indexer.util.FileUtilities;
4449
import org.opengrok.indexer.util.TestRepository;
4550

46-
import static org.junit.Assert.*;
47-
4851
/**
4952
* Test the functionality provided by the HistoryGuru (with friends)
5053
*
@@ -174,21 +177,21 @@ public void testAddRemoveRepositories() {
174177
}
175178

176179
@Test
177-
@ConditionalRun(RepositoryInstalled.GitInstalled.class)
180+
@ConditionalRun(RepositoryInstalled.CvsInstalled.class)
178181
@ConditionalRun(RepositoryInstalled.MercurialInstalled.class)
179-
public void testAddSubRepositoryNoTypeMatch() {
182+
public void testAddSubRepositoryNotNestable() {
180183
HistoryGuru instance = HistoryGuru.getInstance();
181184
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
182185

183-
// Clone a Mercurial repository underneath a Git repository.
184-
File hgRoot = new File(repository.getSourceRoot(), "mercurial");
185-
assertTrue(hgRoot.exists());
186-
assertTrue(hgRoot.isDirectory());
186+
// Check out CVS underneath a Git repository.
187+
File cvsRoot = new File(repository.getSourceRoot(), "cvs_test");
188+
assertTrue(cvsRoot.exists());
189+
assertTrue(cvsRoot.isDirectory());
187190
File gitRoot = new File(repository.getSourceRoot(), "git");
188191
assertTrue(gitRoot.exists());
189192
assertTrue(gitRoot.isDirectory());
190-
MercurialRepositoryTest.runHgCommand(gitRoot,
191-
"clone", hgRoot.getAbsolutePath(), "subrepo");
193+
CVSRepositoryTest.runCvsCommand(gitRoot, "-d",
194+
cvsRoot.toPath().resolve("cvsroot").toFile().getAbsolutePath(), "checkout", "cvsrepo");
192195

193196
Collection<RepositoryInfo> addedRepos = instance.
194197
addRepositories(Collections.singleton(Paths.get(repository.getSourceRoot(), "git").toString()),

0 commit comments

Comments
 (0)