mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-06 18:30:57 +00:00
test
This commit is contained in:
parent
83f35bf40e
commit
90382f5467
221
.github/workflows/file_hash_generation.yml
vendored
221
.github/workflows/file_hash_generation.yml
vendored
@ -8,7 +8,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- 'src/main/resources/templates/**'
|
- 'src/main/resources/templates/**'
|
||||||
- 'src/main/resources/static/**'
|
- 'src/main/resources/static/**'
|
||||||
workflow_dispatch: # Allow manual triggering
|
workflow_dispatch: # Allow manual triggering
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
generate-hash:
|
generate-hash:
|
||||||
@ -18,81 +18,170 @@ jobs:
|
|||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up JDK
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: '17'
|
||||||
|
|
||||||
- name: Calculate template hashes
|
- name: Calculate template hashes
|
||||||
id: hash
|
id: hash
|
||||||
run: |
|
run: |
|
||||||
# Create a script to calculate individual file hashes
|
# Create a Java program to calculate hashes
|
||||||
cat > calculate-hashes.sh << 'EOF'
|
cat > HashGenerator.java << 'EOF'
|
||||||
#!/bin/bash
|
import java.io.File;
|
||||||
set -e
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
# Directories to hash
|
public class HashGenerator {
|
||||||
TEMPLATE_DIR="src/main/resources/templates"
|
private static final String TEMPLATE_DIR = "src/main/resources/templates";
|
||||||
STATIC_DIR="src/main/resources/static"
|
private static final String STATIC_DIR = "src/main/resources/static";
|
||||||
OUTPUT_FILE="src/main/resources/reference-hash.json"
|
private static final String OUTPUT_FILE = "src/main/resources/reference-hash.json";
|
||||||
|
|
||||||
# Create output directory if it doesn't exist
|
// Text file extensions that need normalization
|
||||||
mkdir -p $(dirname "$OUTPUT_FILE")
|
private static final List<String> TEXT_EXTENSIONS = List.of(
|
||||||
|
"html", "htm", "css", "js", "txt", "md", "xml", "json", "csv", "properties"
|
||||||
|
);
|
||||||
|
|
||||||
# Text file extensions that need normalization
|
public static void main(String[] args) throws IOException {
|
||||||
TEXT_EXTENSIONS=("html" "htm" "css" "js" "txt" "md" "xml" "json" "csv" "properties")
|
List<FileEntry> entries = new ArrayList<>();
|
||||||
|
|
||||||
# Function to check if a file is a text file
|
// Process templates directory
|
||||||
is_text_file() {
|
processDirectory(new File(TEMPLATE_DIR), entries, "templates");
|
||||||
ext="${1##*.}"
|
|
||||||
for text_ext in "${TEXT_EXTENSIONS[@]}"; do
|
// Process static directory
|
||||||
if [ "$ext" = "$text_ext" ]; then
|
processDirectory(new File(STATIC_DIR), entries, "static");
|
||||||
return 0
|
|
||||||
fi
|
// Sort entries for consistent output
|
||||||
done
|
Collections.sort(entries);
|
||||||
return 1
|
|
||||||
|
// Write JSON output
|
||||||
|
writeJsonOutput(entries);
|
||||||
|
|
||||||
|
System.out.println("Generated hashes for " + entries.size() + " files");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processDirectory(File dir, List<FileEntry> entries, String basePath) throws IOException {
|
||||||
|
if (!dir.exists() || !dir.isDirectory()) {
|
||||||
|
System.out.println("Directory not found: " + dir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
processFilesRecursively(dir, dir, entries, basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processFilesRecursively(File baseDir, File currentDir, List<FileEntry> entries, String basePath)
|
||||||
|
throws IOException {
|
||||||
|
File[] files = currentDir.listFiles();
|
||||||
|
if (files == null) return;
|
||||||
|
|
||||||
|
for (File file : files) {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
processFilesRecursively(baseDir, file, entries, basePath);
|
||||||
|
} else {
|
||||||
|
// Get relative path
|
||||||
|
String relativePath = baseDir.toPath().relativize(file.toPath()).toString()
|
||||||
|
.replace('\\', '/');
|
||||||
|
String fullPath = basePath + "/" + relativePath;
|
||||||
|
|
||||||
|
// Calculate hash
|
||||||
|
String hash = calculateFileHash(file);
|
||||||
|
|
||||||
|
entries.add(new FileEntry(fullPath, hash));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String calculateFileHash(File file) throws IOException {
|
||||||
|
String extension = getFileExtension(file.getName()).toLowerCase();
|
||||||
|
boolean isTextFile = TEXT_EXTENSIONS.contains(extension);
|
||||||
|
|
||||||
|
if (isTextFile) {
|
||||||
|
return calculateNormalizedTextFileHash(file.toPath());
|
||||||
|
} else {
|
||||||
|
return calculateBinaryFileHash(file.toPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String calculateNormalizedTextFileHash(Path filePath) throws IOException {
|
||||||
|
byte[] content = Files.readAllBytes(filePath);
|
||||||
|
String text = new String(content, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
// Normalize line endings to LF (remove CRs)
|
||||||
|
text = text.replace("\r", "");
|
||||||
|
|
||||||
|
byte[] normalizedBytes = text.getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
CRC32 checksum = new CRC32();
|
||||||
|
checksum.update(normalizedBytes, 0, normalizedBytes.length);
|
||||||
|
return String.valueOf(checksum.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String calculateBinaryFileHash(Path filePath) throws IOException {
|
||||||
|
byte[] content = Files.readAllBytes(filePath);
|
||||||
|
|
||||||
|
CRC32 checksum = new CRC32();
|
||||||
|
checksum.update(content, 0, content.length);
|
||||||
|
return String.valueOf(checksum.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getFileExtension(String filename) {
|
||||||
|
int lastDot = filename.lastIndexOf('.');
|
||||||
|
if (lastDot == -1 || lastDot == filename.length() - 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return filename.substring(lastDot + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeJsonOutput(List<FileEntry> entries) throws IOException {
|
||||||
|
File outputFile = new File(OUTPUT_FILE);
|
||||||
|
outputFile.getParentFile().mkdirs();
|
||||||
|
|
||||||
|
try (FileWriter writer = new FileWriter(outputFile)) {
|
||||||
|
writer.write("{\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < entries.size(); i++) {
|
||||||
|
FileEntry entry = entries.get(i);
|
||||||
|
writer.write(" \"" + entry.path + "\": \"" + entry.hash + "\"");
|
||||||
|
|
||||||
|
if (i < entries.size() - 1) {
|
||||||
|
writer.write(",");
|
||||||
|
}
|
||||||
|
writer.write("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.write("}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class to represent a file and its hash
|
||||||
|
private static class FileEntry implements Comparable<FileEntry> {
|
||||||
|
final String path;
|
||||||
|
final String hash;
|
||||||
|
|
||||||
|
FileEntry(String path, String hash) {
|
||||||
|
this.path = path;
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(FileEntry other) {
|
||||||
|
return path.compareTo(other.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to calculate normalized hash for text files
|
|
||||||
calculate_text_hash() {
|
|
||||||
# Normalize line endings to LF and calculate CRC32
|
|
||||||
tr -d '\r' < "$1" | cksum | awk '{print $1}'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to calculate hash for binary files
|
|
||||||
calculate_binary_hash() {
|
|
||||||
cksum "$1" | awk '{print $1}'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Start JSON
|
|
||||||
echo "{" > "$OUTPUT_FILE"
|
|
||||||
|
|
||||||
# Find all files and calculate CRC32 hash
|
|
||||||
FIRST=true
|
|
||||||
find "$TEMPLATE_DIR" "$STATIC_DIR" -type f | sort | while read file; do
|
|
||||||
# Get relative path from src/main/resources
|
|
||||||
REL_PATH=$(echo "$file" | sed 's|^src/main/resources/||')
|
|
||||||
|
|
||||||
# Calculate hash based on file type
|
|
||||||
if is_text_file "$file"; then
|
|
||||||
HASH=$(calculate_text_hash "$file")
|
|
||||||
else
|
|
||||||
HASH=$(calculate_binary_hash "$file")
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add to JSON
|
|
||||||
if [ "$FIRST" = true ]; then
|
|
||||||
FIRST=false
|
|
||||||
else
|
|
||||||
echo "," >> "$OUTPUT_FILE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo " \"$REL_PATH\": \"$HASH\"" >> "$OUTPUT_FILE"
|
|
||||||
done
|
|
||||||
|
|
||||||
# End JSON
|
|
||||||
echo "}" >> "$OUTPUT_FILE"
|
|
||||||
|
|
||||||
echo "Generated hashes for $(grep -c ":" "$OUTPUT_FILE") files"
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
chmod +x calculate-hashes.sh
|
# Compile and run the Java program
|
||||||
./calculate-hashes.sh
|
javac HashGenerator.java
|
||||||
|
java HashGenerator
|
||||||
|
|
||||||
- name: Commit and push if changed
|
- name: Commit and push if changed
|
||||||
run: |
|
run: |
|
||||||
|
@ -255,28 +255,20 @@ public class TemplateIntegrityConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String computeNormalizedTextFileHash(Path filePath, String extension) throws IOException {
|
private String computeNormalizedTextFileHash(Path filePath, String extension) throws IOException {
|
||||||
byte[] content = Files.readAllBytes(filePath);
|
byte[] content = Files.readAllBytes(filePath);
|
||||||
String text = new String(content, StandardCharsets.UTF_8);
|
String text = new String(content, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
// Normalize line endings to LF
|
// Remove ALL carriage returns to match GitHub workflow's tr -d '\r'
|
||||||
text = text.replace("\r\n", "\n");
|
text = text.replace("\r", "");
|
||||||
|
|
||||||
// Additional HTML-specific normalization if needed
|
byte[] normalizedBytes = text.getBytes(StandardCharsets.UTF_8);
|
||||||
if (extension.equals("html") || extension.equals("htm")) {
|
|
||||||
// Optional: normalize whitespace between HTML tags
|
Checksum checksum = new CRC32();
|
||||||
// text = text.replaceAll(">\\s+<", "><");
|
checksum.update(normalizedBytes, 0, normalizedBytes.length);
|
||||||
|
return String.valueOf(checksum.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] normalizedBytes = text.getBytes(StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
Checksum checksum = new CRC32();
|
|
||||||
checksum.update(normalizedBytes, 0, normalizedBytes.length);
|
|
||||||
// Return decimal representation to match GitHub workflow
|
|
||||||
return String.valueOf(checksum.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private String computeBinaryFileHash(Path filePath) throws IOException {
|
private String computeBinaryFileHash(Path filePath) throws IOException {
|
||||||
Checksum checksum = new CRC32();
|
Checksum checksum = new CRC32();
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}"
|
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}"
|
||||||
xmlns:th="https://www.thymeleaf.org">
|
xmlns:th="https://www.thymeleaf.org">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<th:block th:insert="~{fragments/common :: head(title='')}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title='')}"></th:block>
|
||||||
</head>
|
</head>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user