• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

git-commit-id / git-commit-id-maven-plugin / #219

04 Dec 2023 07:24PM CUT coverage: 71.134%. Remained the same
#219

push

web-flow
Merge pull request #676 from git-commit-id/dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.6.3

Bump org.apache.maven.plugins:maven-javadoc-plugin from 3.6.2 to 3.6.3

276 of 388 relevant lines covered (71.13%)

0.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

53.33
/src/main/java/pl/project13/maven/git/GitDirLocator.java
1
/*
2
 * This file is part of git-commit-id-maven-plugin by Konrad 'ktoso' Malawski <konrad.malawski@java.pl>
3
 *
4
 * git-commit-id-maven-plugin is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * git-commit-id-maven-plugin is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with git-commit-id-maven-plugin.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17

18
package pl.project13.maven.git;
19

20
import org.apache.maven.project.MavenProject;
21
import org.eclipse.jgit.lib.Constants;
22

23
import javax.annotation.Nonnull;
24
import javax.annotation.Nullable;
25
import java.io.*;
26
import java.nio.file.Path;
27
import java.util.List;
28

29
/**
30
 * This class encapsulates logic to locate a valid .git directory of the currently used project.
31
 * If it's not already specified, this logic will try to find it.
32
 */
33
public class GitDirLocator {
34
  final MavenProject mavenProject;
35
  final List<MavenProject> reactorProjects;
36

37
  /**
38
   * Constructor to encapsulates all references required to locate a valid .git directory
39
   * @param mavenProject The currently used (maven) project.
40
   * @param reactorProjects The list of reactor projects (sub-projects) of the current (maven) project.
41
   */
42
  public GitDirLocator(MavenProject mavenProject, List<MavenProject> reactorProjects) {
1✔
43
    this.mavenProject = mavenProject;
1✔
44
    this.reactorProjects = reactorProjects;
1✔
45
  }
1✔
46

47
  /**
48
   * Attempts to lookup a valid .git directory of the currently used project.
49
   * @param manuallyConfiguredDir A user has the ability to configure a git-directory with the {@code dotGitDirectory}
50
   *                              configuration setting. By default it should be simply {@code ${project.basedir}/.git}
51
   * @return A valid .git directory, or {@code null} if none could be found under the user specified location or within
52
   * the project or it's reactor projects.
53
   */
54
  @Nullable
55
  public File lookupGitDirectory(@Nonnull File manuallyConfiguredDir) {
56
    if (manuallyConfiguredDir.exists()) {
1✔
57

58
      // If manuallyConfiguredDir is a directory then we can use it as the git path.
59
      if (manuallyConfiguredDir.isDirectory()) {
1✔
60
        return manuallyConfiguredDir;
1✔
61
      }
62

63
      // If the path exists but is not a directory it might be a git submodule "gitdir" link.
64
      File gitDirLinkPath = processGitDirFile(manuallyConfiguredDir);
×
65

66
      // If the linkPath was found from the file and it exists then use it.
67
      if (isExistingDirectory(gitDirLinkPath)) {
×
68
        return gitDirLinkPath;
×
69
      }
70

71
      /*
72
       * FIXME: I think we should fail here because a manual path was set and it was not found
73
       * but I'm leaving it falling back to searching for the git path because that is the current
74
       * behaviour - Unluckypixie.
75
       */
76
    }
77

78
    return findProjectGitDirectory();
1✔
79
  }
80

81
  /**
82
   * Search up all the maven parent project hierarchy until a .git directory is found.
83
   *
84
   * @return File which represents the location of the .git directory or NULL if none found.
85
   */
86
  @Nullable
87
  private File findProjectGitDirectory() {
88
    if (this.mavenProject == null) {
1✔
89
      return null;
×
90
    }
91

92
    File basedir = mavenProject.getBasedir();
1✔
93
    while (basedir != null) {
1✔
94
      File gitdir = new File(basedir, Constants.DOT_GIT);
1✔
95
      if (gitdir.exists()) {
1✔
96
        if (gitdir.isDirectory()) {
1✔
97
          return gitdir;
1✔
98
        } else if (gitdir.isFile()) {
×
99
          return processGitDirFile(gitdir);
×
100
        } else {
101
          return null;
×
102
        }
103
      }
104
      basedir = basedir.getParentFile();
1✔
105
    }
1✔
106
    return null;
1✔
107
  }
108

109
  /**
110
   * Load a ".git" git submodule file and read the gitdir path from it.
111
   *
112
   * @return File object with path loaded or null
113
   */
114
  private File processGitDirFile(@Nonnull File file) {
115
    try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
×
116
      // There should be just one line in the file, e.g.
117
      // "gitdir: /usr/local/src/parentproject/.git/modules/submodule"
118
      String line = reader.readLine();
×
119
      if (line == null) {
×
120
        return null;
×
121
      }
122
      // Separate the key and the value in the string.
123
      String[] parts = line.split(": ");
×
124

125
      // If we don't have 2 parts or if the key is not gitdir then give up.
126
      if (parts.length != 2 || !parts[0].equals("gitdir")) {
×
127
        return null;
×
128
      }
129

130
      // All seems ok so return the "gitdir" value read from the file.
131
      File gitDir = resolveWorktree(new File(parts[1]));
×
132
      if (gitDir.isAbsolute()) {
×
133
        // gitdir value is an absolute path. Return as-is
134
        return gitDir;
×
135
      } else {
136
        // gitdir value is relative.
137
        return new File(file.getParentFile(), parts[1]);
×
138
      }
139
    } catch (IOException e) {
×
140
      return null;
×
141
    }
142
  }
143

144
  /**
145
   * If the file looks like the location of a worktree, return the .git folder of the git repository of the worktree.
146
   * If not, return the file as is.
147
   */
148
  static File resolveWorktree(File fileLocation) {
149
    Path parent = fileLocation.toPath().getParent();
1✔
150
    if (parent == null) {
1✔
151
      return fileLocation;
1✔
152
    }
153
    if (parent.endsWith(Path.of(".git", "worktrees"))) {
1✔
154
      return parent.getParent().toFile();
1✔
155
    }
156
    return fileLocation;
1✔
157
  }
158

159
  /**
160
   * Helper method to validate that the specified {@code File} is an existing directory.
161
   * @param fileLocation The  {@code File} that should be checked if it's actually an existing directory.
162
   * @return {@code true} if the specified {@code File} is an existing directory, {@false} otherwise.
163
   */
164
  private static boolean isExistingDirectory(@Nullable File fileLocation) {
165
    return fileLocation != null && fileLocation.exists() && fileLocation.isDirectory();
×
166
  }
167
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc