initial commit
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(java -version)"
|
||||
]
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
.kotlin
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
|
||||
## local ##
|
||||
/database/
|
||||
/javadoc-storage/
|
||||
/jvs.yml
|
||||
@@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>codes.thischwa</groupId>
|
||||
<artifactId>jvc</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
|
||||
<name>JavadocViewerService</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>4.0.4</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:https://git.mein-gateway.de/thischwa/JavadocViewerService.git</developerConnection>
|
||||
<connection>scm:git:https://git.mein-gateway.de/thischwa/JavadocViewerService.git</connection>
|
||||
<url>https://git.mein-gateway.de/thischwa/JavadocViewerService</url>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>mygitea</id>
|
||||
<url>https://git.mein-gateway.de/api/packages/thischwa/maven</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>mygitea</id>
|
||||
<url>https://git.mein-gateway.de/api/packages/thischwa/maven</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jgit</groupId>
|
||||
<artifactId>org.eclipse.jgit</artifactId>
|
||||
<version>6.6.1.202309021850-r</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
package codes.thischwa.jvs;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
public class JavadocViewerServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(JavadocViewerServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package codes.thischwa.jvs.config;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "jvs")
|
||||
@Data
|
||||
public class JvsConfig {
|
||||
private String configPath;
|
||||
private String baseDir;
|
||||
private List<RepoConfig> repositories;
|
||||
|
||||
@Data
|
||||
public static class RepoConfig {
|
||||
private String name;
|
||||
private String url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package codes.thischwa.jvs.model;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.Data;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
public class GitRepository {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, unique = true)
|
||||
private String name;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String url;
|
||||
|
||||
private String lastTag;
|
||||
|
||||
private LocalDateTime updated;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package codes.thischwa.jvs.repository;
|
||||
|
||||
import codes.thischwa.jvs.model.GitRepository;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface GitRepositoryRepository extends JpaRepository<GitRepository, Long> {
|
||||
Optional<GitRepository> findByName(String name);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package codes.thischwa.jvs.service;
|
||||
|
||||
import codes.thischwa.jvs.config.JvsConfig;
|
||||
import codes.thischwa.jvs.model.GitRepository;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class GitService {
|
||||
private final JvsConfig jvsConfig;
|
||||
|
||||
public Optional<String> updateAndCheckoutLatestTag(GitRepository repoEntity) {
|
||||
Path repoPath = Path.of(jvsConfig.getBaseDir(), "repos", repoEntity.getName());
|
||||
try {
|
||||
Git git;
|
||||
if (Files.exists(repoPath)) {
|
||||
git = Git.open(repoPath.toFile());
|
||||
git.fetch().setCheckFetchedObjects(true).call();
|
||||
} else {
|
||||
git = Git.cloneRepository()
|
||||
.setURI(repoEntity.getUrl())
|
||||
.setDirectory(repoPath.toFile())
|
||||
.setCloneAllBranches(true)
|
||||
.setNoCheckout(false)
|
||||
.call();
|
||||
}
|
||||
|
||||
List<Ref> tags = git.tagList().call();
|
||||
Optional<Ref> latestVTag = tags.stream()
|
||||
.filter(ref -> ref.getName().startsWith("refs/tags/v"))
|
||||
.max(Comparator.comparing(Ref::getName));
|
||||
|
||||
if (latestVTag.isPresent()) {
|
||||
String tagName = latestVTag.get().getName().substring("refs/tags/".length());
|
||||
git.checkout().setName(tagName).call();
|
||||
log.info("Repository {} checked out at tag {}.", repoEntity.getName(), tagName);
|
||||
return Optional.of(tagName);
|
||||
} else {
|
||||
log.warn("No v* tag found for repository {}.", repoEntity.getName());
|
||||
}
|
||||
} catch (IOException | GitAPIException e) {
|
||||
log.error("Error processing repository " + repoEntity.getName(), e);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public File getRepoDirectory(String name) {
|
||||
return Path.of(jvsConfig.getBaseDir(), "repos", name).toFile();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package codes.thischwa.jvs.service;
|
||||
|
||||
import codes.thischwa.jvs.config.JvsConfig;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.stream.Stream;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class JavadocService {
|
||||
private final JvsConfig jvsConfig;
|
||||
|
||||
public boolean generateJavadoc(String projectName, File repoDir) {
|
||||
File outputDir = Path.of(jvsConfig.getBaseDir(), "javadoc", projectName).toFile();
|
||||
if (!outputDir.exists()) {
|
||||
outputDir.mkdirs();
|
||||
}
|
||||
|
||||
// Try Maven first if a pom.xml is present
|
||||
if (new File(repoDir, "pom.xml").exists()) {
|
||||
boolean success = runMavenJavadoc(repoDir, outputDir);
|
||||
if (success) {
|
||||
copyGeneratedJavadoc(repoDir, outputDir);
|
||||
}
|
||||
return success;
|
||||
} else {
|
||||
log.warn("No pom.xml found in {}. Manual javadoc generation is not implemented.", projectName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void copyGeneratedJavadoc(File repoDir, File targetDir) {
|
||||
// Possible standard paths for Javadoc
|
||||
String[] possiblePaths = {
|
||||
"target/reports/apidocs",
|
||||
"target/site/apidocs",
|
||||
"target/apidocs"
|
||||
};
|
||||
|
||||
for (String relPath : possiblePaths) {
|
||||
File sourceDir = new File(repoDir, relPath);
|
||||
if (sourceDir.exists() && sourceDir.isDirectory()) {
|
||||
log.info("Found Javadoc in {}, copying to {}", sourceDir.getAbsolutePath(), targetDir.getAbsolutePath());
|
||||
try {
|
||||
copyDirectory(sourceDir.toPath(), targetDir.toPath());
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
log.error("Error copying Javadoc from {} to {}", sourceDir.getAbsolutePath(), targetDir.getAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
log.warn("No generated Javadoc files found in the standard directories of {}.", repoDir.getName());
|
||||
}
|
||||
|
||||
private void copyDirectory(Path source, Path target) throws IOException {
|
||||
try (Stream<Path> stream = Files.walk(source)) {
|
||||
stream.forEach(path -> {
|
||||
try {
|
||||
Path dest = target.resolve(source.relativize(path));
|
||||
if (Files.isDirectory(path)) {
|
||||
if (!Files.exists(dest)) {
|
||||
Files.createDirectories(dest);
|
||||
}
|
||||
} else {
|
||||
Files.copy(path, dest, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean runMavenJavadoc(File repoDir, File outputDir) {
|
||||
ProcessBuilder pb = new ProcessBuilder(
|
||||
"mvn", "javadoc:javadoc",
|
||||
"-Dmaven.javadoc.failOnError=false",
|
||||
"--no-transfer-progress",
|
||||
"-Dlombok.delombok.skip=true",
|
||||
"-Dcheckstyle.skip=true",
|
||||
"-Djacoco.skip=true"
|
||||
);
|
||||
pb.directory(repoDir);
|
||||
pb.redirectErrorStream(true);
|
||||
|
||||
try {
|
||||
Process process = pb.start();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
log.info("[MAVEN] {}", line);
|
||||
}
|
||||
}
|
||||
int exitCode = process.waitFor();
|
||||
if (exitCode == 0) {
|
||||
log.info("Javadoc successfully generated in {}", outputDir.getAbsolutePath());
|
||||
return true;
|
||||
} else {
|
||||
log.error("Maven javadoc failed with exit code {}", exitCode);
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
log.error("Error executing Maven javadoc", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package codes.thischwa.jvs.service;
|
||||
|
||||
import codes.thischwa.jvs.config.JvsConfig;
|
||||
import codes.thischwa.jvs.model.GitRepository;
|
||||
import codes.thischwa.jvs.repository.GitRepositoryRepository;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class RepoConfigLoader {
|
||||
private final JvsConfig jvsConfig;
|
||||
private final GitRepositoryRepository repository;
|
||||
|
||||
@PostConstruct
|
||||
public void loadConfig() {
|
||||
File configFile = new File(jvsConfig.getConfigPath());
|
||||
if (!configFile.exists()) {
|
||||
log.info("Configuration file {} not found.", jvsConfig.getConfigPath());
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
|
||||
try {
|
||||
JvsConfig yamlConfig = mapper.readValue(configFile, JvsConfig.class);
|
||||
if (yamlConfig.getRepositories() != null) {
|
||||
for (JvsConfig.RepoConfig repoCfg : yamlConfig.getRepositories()) {
|
||||
if (repository.findByName(repoCfg.getName()).isEmpty()) {
|
||||
GitRepository repo = new GitRepository();
|
||||
repo.setName(repoCfg.getName());
|
||||
repo.setUrl(repoCfg.getUrl());
|
||||
repository.save(repo);
|
||||
log.info("Repository {} added from configuration.", repoCfg.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading configuration file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package codes.thischwa.jvs.service;
|
||||
|
||||
import codes.thischwa.jvs.model.GitRepository;
|
||||
import codes.thischwa.jvs.repository.GitRepositoryRepository;
|
||||
import java.io.File;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class UpdateScheduler {
|
||||
private final GitRepositoryRepository repository;
|
||||
private final GitService gitService;
|
||||
private final JavadocService javadocService;
|
||||
|
||||
@Scheduled(fixedRateString = "${jvs.update-interval:PT1H}")
|
||||
public void updateAll() {
|
||||
log.info("Starting scheduled update of repositories...");
|
||||
List<GitRepository> repos = repository.findAll();
|
||||
for (GitRepository repo : repos) {
|
||||
updateRepo(repo);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRepo(GitRepository repo) {
|
||||
log.info("Checking repository: {}", repo.getName());
|
||||
Optional<String> latestTag = gitService.updateAndCheckoutLatestTag(repo);
|
||||
if (latestTag.isPresent()) {
|
||||
String tag = latestTag.get();
|
||||
if (!tag.equals(repo.getLastTag())) {
|
||||
log.info("New tag {} found for {}. Generating Javadoc...", tag, repo.getName());
|
||||
File repoDir = gitService.getRepoDirectory(repo.getName());
|
||||
if (javadocService.generateJavadoc(repo.getName(), repoDir)) {
|
||||
repo.setLastTag(tag);
|
||||
repo.setUpdated(LocalDateTime.now());
|
||||
repository.save(repo);
|
||||
}
|
||||
} else {
|
||||
log.info("Repository {} is already up to date ({}).", repo.getName(), tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package codes.thischwa.jvs.web;
|
||||
|
||||
import codes.thischwa.jvs.repository.GitRepositoryRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
@RequiredArgsConstructor
|
||||
public class HomeController {
|
||||
private final GitRepositoryRepository repository;
|
||||
|
||||
@GetMapping("/")
|
||||
public String index(Model model) {
|
||||
model.addAttribute("repos", repository.findAll());
|
||||
return "index";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package codes.thischwa.jvs.web;
|
||||
|
||||
import codes.thischwa.jvs.config.JvsConfig;
|
||||
import java.nio.file.Path;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
private final JvsConfig jvsConfig;
|
||||
|
||||
public WebConfig(JvsConfig jvsConfig) {
|
||||
this.jvsConfig = jvsConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
String javadocPath = Path.of(jvsConfig.getBaseDir(), "javadoc").toAbsolutePath().toUri().toString();
|
||||
if (!javadocPath.endsWith("/")) {
|
||||
javadocPath += "/";
|
||||
}
|
||||
registry.addResourceHandler("/**")
|
||||
.addResourceLocations(javadocPath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:h2:file:./database/jvsdb
|
||||
driverClassName: org.h2.Driver
|
||||
username: sa
|
||||
password: ""
|
||||
jpa:
|
||||
database-platform: org.hibernate.dialect.H2Dialect
|
||||
hibernate:
|
||||
ddl-auto: none
|
||||
liquibase:
|
||||
change-log: classpath:db/changelog/db.changelog-master.yaml
|
||||
|
||||
jvs:
|
||||
config-path: jvs.yml
|
||||
base-dir: ./javadoc-storage
|
||||
update-interval: PT1H
|
||||
@@ -0,0 +1,32 @@
|
||||
databaseChangeLog:
|
||||
- changeSet:
|
||||
id: 1
|
||||
author: junie
|
||||
changes:
|
||||
- createTable:
|
||||
tableName: git_repository
|
||||
columns:
|
||||
- column:
|
||||
name: id
|
||||
type: BIGINT
|
||||
autoIncrement: true
|
||||
constraints:
|
||||
primaryKey: true
|
||||
nullable: false
|
||||
- column:
|
||||
name: name
|
||||
type: VARCHAR(255)
|
||||
constraints:
|
||||
nullable: false
|
||||
unique: true
|
||||
- column:
|
||||
name: url
|
||||
type: VARCHAR(512)
|
||||
constraints:
|
||||
nullable: false
|
||||
- column:
|
||||
name: last_tag
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: updated
|
||||
type: TIMESTAMP
|
||||
@@ -0,0 +1,3 @@
|
||||
databaseChangeLog:
|
||||
- include:
|
||||
file: db/changelog/001-init-schema.yaml
|
||||
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>Javadoc Viewer Service</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-5">
|
||||
<h1>Projekt Javadoc Übersicht</h1>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Git URL</th>
|
||||
<th>Letzter Tag</th>
|
||||
<th>Letztes Update</th>
|
||||
<th>Aktion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="repo : ${repos}">
|
||||
<td th:text="${repo.name}">Projekt</td>
|
||||
<td th:text="${repo.url}">URL</td>
|
||||
<td th:text="${repo.lastTag}">v1.0</td>
|
||||
<td th:text="${#temporals.format(repo.updated, 'dd.MM.yyyy HH:mm')}">-</td>
|
||||
<td>
|
||||
<a th:if="${repo.lastTag != null}" th:href="@{/{name}/index.html(name=${repo.name})}" class="btn btn-primary btn-sm">Javadoc öffnen</a>
|
||||
<span th:if="${repo.lastTag == null}" class="badge bg-secondary">Noch nicht generiert</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user