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

devonfw / IDEasy / 24559054027

17 Apr 2026 09:52AM UTC coverage: 70.246% (-0.2%) from 70.455%
24559054027

Pull #1831

github

web-flow
Merge 0caa21ea9 into 2a5e16034
Pull Request #1831: #1688: Remove unnecessary cli message when tool install

4264 of 6718 branches covered (63.47%)

Branch coverage included in aggregate %.

11068 of 15108 relevant lines covered (73.26%)

3.09 hits per line

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

3.23
cli/src/main/java/com/devonfw/tools/ide/tool/pgadmin/PgAdmin.java
1
package com.devonfw.tools.ide.tool.pgadmin;
2

3
import java.nio.file.Files;
4
import java.nio.file.Path;
5
import java.nio.file.Paths;
6
import java.util.ArrayList;
7
import java.util.Arrays;
8
import java.util.List;
9
import java.util.Set;
10

11
import org.slf4j.Logger;
12
import org.slf4j.LoggerFactory;
13

14
import com.devonfw.tools.ide.common.Tag;
15
import com.devonfw.tools.ide.context.IdeContext;
16
import com.devonfw.tools.ide.process.ProcessErrorHandling;
17
import com.devonfw.tools.ide.process.ProcessMode;
18
import com.devonfw.tools.ide.tool.GlobalToolCommandlet;
19
import com.devonfw.tools.ide.tool.NativePackageManager;
20
import com.devonfw.tools.ide.tool.PackageManagerCommand;
21
import com.devonfw.tools.ide.tool.repository.ToolRepository;
22
import com.devonfw.tools.ide.version.VersionIdentifier;
23
import com.fasterxml.jackson.databind.JsonNode;
24
import com.fasterxml.jackson.databind.ObjectMapper;
25

26
/**
27
 * {@link GlobalToolCommandlet} for <a href="https://www.pgadmin.org/">pgadmin</a>
28
 */
29
public class PgAdmin extends GlobalToolCommandlet {
30

31
  private static final Logger LOG = LoggerFactory.getLogger(PgAdmin.class);
4✔
32

33
  private static final String PG_ADMIN = "pgAdmin 4";
34

35
  /**
36
   * The constructor.
37
   *
38
   * @param context the {@link IdeContext}.
39
   */
40
  public PgAdmin(IdeContext context) {
41

42
    super(context, "pgadmin", Set.of(Tag.DB, Tag.ADMIN));
7✔
43
  }
1✔
44

45
  @Override
46
  protected List<PackageManagerCommand> getInstallPackageManagerCommands() {
47

48
    String edition = getConfiguredEdition();
×
49
    ToolRepository toolRepository = getToolRepository();
×
50
    VersionIdentifier configuredVersion = getConfiguredVersion();
×
51
    String resolvedVersion = toolRepository.resolveVersion(this.tool, edition, configuredVersion, this).toString();
×
52

53
    PackageManagerCommand packageManagerCommand = new PackageManagerCommand(NativePackageManager.APT, List.of(
×
54
        "curl -fsS https://www.pgadmin.org/static/packages_pgadmin_org.pub | "
55
            + "sudo gpg --yes --dearmor -o /usr/share/keyrings/packages-pgadmin-org.gpg",
56
        "sudo sh -c 'echo \"deb [signed-by=/usr/share/keyrings/packages-pgadmin-org.gpg] "
57
            + "https://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/$(lsb_release -cs) pgadmin4 main\" "
58
            + "> /etc/apt/sources.list.d/pgadmin4.list && apt update'", String.format(
×
59
            "sudo apt install -y --allow-downgrades pgadmin4=%1$s pgadmin4-server=%1$s pgadmin4-desktop=%1$s pgadmin4-web=%1$s",
60
            resolvedVersion)));
61
    return List.of(packageManagerCommand);
×
62
  }
63

64
  @Override
65
  public VersionIdentifier getInstalledVersion() {
66

67
    if (this.context.getSystemInfo().isWindows()) {
×
68
      Path installationPath = getWindowsInstallationPath();
×
69
      Path sbomPath;
70
      if (installationPath != null) {
×
71
        sbomPath = installationPath.resolve("sbom.json");
×
72
        if (Files.isRegularFile(sbomPath)) {
×
73
          try {
74
            JsonNode root = new ObjectMapper().readTree(sbomPath.toFile());
×
75
            for (JsonNode component : root.path("components")) {
×
76
              if (PG_ADMIN.equals(component.path("name").asText())) {
×
77
                return VersionIdentifier.of(
×
78
                    component.path("version")
×
79
                        .asText()
×
80
                        .replace("\"", "") // weirdly a quotation mark  present in the version string
×
81
                );
82
              }
83
            }
×
84
          } catch (Exception e) {
×
85
            LOG.error("Could not read pgAdmin version from SBOM file '{}'", sbomPath, e);
×
86
          }
×
87
        }
88
      }
89
    }
90

91
    return null;
×
92
  }
93

94
  @Override
95
  public String getInstalledEdition() {
96

97
    if (this.context.getSystemInfo().isWindows()) {
×
98
      Path installationPath = getWindowsInstallationPath();
×
99
      if (installationPath != null) {
×
100
        if (Files.exists(installationPath)) {
×
101
          return "pgadmin";
×
102
        }
103
      }
104
    }
105

106
    return null;
×
107
  }
108

109
  @Override
110
  public void uninstall() {
111

112
    if (this.context.getSystemInfo().isLinux()) {
×
113
      runWithPackageManager(false, getPackageManagerCommandsUninstall());
×
114
    } else if (this.context.getSystemInfo().isWindows()) {
×
115
      Path installationPath = getWindowsInstallationPath();
×
116
      if (installationPath != null) {
×
117
        Path uninstallExecutablePath = installationPath.resolve("unins000.exe");
×
118
        if (Files.isExecutable(uninstallExecutablePath)) {
×
119
          this.context.newProcess().errorHandling(ProcessErrorHandling.LOG_WARNING)
×
120
              .executable(uninstallExecutablePath)
×
121
              .run(ProcessMode.BACKGROUND).getExitCode();
×
122
        }
123
      }
124
    }
125
  }
×
126

127
  private List<PackageManagerCommand> getPackageManagerCommandsUninstall() {
128

129
    List<PackageManagerCommand> pmCommands = new ArrayList<>();
×
130

131
    pmCommands.add(new PackageManagerCommand(NativePackageManager.APT,
×
132
        Arrays.asList("sudo apt -y autoremove pgadmin4 pgadmin4-server pgadmin4-desktop pgadmin4-web")));
×
133

134
    return pmCommands;
×
135
  }
136

137
  @Override
138
  protected String getBinaryName() {
139

140
    return "pgadmin4";
×
141
  }
142

143
  private Path getWindowsInstallationPath() {
144

145
    String appDataPath = System.getenv("APPDATA");
×
146
    if (appDataPath != null && !appDataPath.isBlank()) {
×
147
      try {
148
        Path shortcut = Paths.get(appDataPath)
×
149
            .resolve("Microsoft")
×
150
            .resolve("Windows")
×
151
            .resolve("Start Menu")
×
152
            .resolve("Programs")
×
153
            .resolve(PG_ADMIN)
×
154
            .resolve(PG_ADMIN + ".lnk");
×
155

156
        Process process = new ProcessBuilder(
×
157
            "powershell",
158
            "-NoProfile",
159
            "-Command",
160
            "(New-Object -ComObject WScript.Shell)"
161
                + ".CreateShortcut('" + shortcut + "')"
162
                + ".TargetPath"
163
        ).redirectErrorStream(true).start();
×
164

165
        Path installationPath = Paths.get(new String(process.getInputStream().readAllBytes()).trim());
×
166
        return installationPath.getParent().getParent();
×
167
      } catch (Exception e) {
×
168
        // we only log this in debug because a meaningful message already gets logged from a super class
169
        // if no installation is found. If the path is simply false the same applies.
170
        LOG.debug("Couldn't resolve installation path of {}", PG_ADMIN);
×
171
      }
172
    }
173

174
    return null;
×
175
  }
176
}
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

© 2026 Coveralls, Inc