SHiNE-server/build.gradle

298 lines
10 KiB
Groovy
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

plugins {
id 'java'
id 'application'
id 'com.github.johnrengelman.shadow' version '8.1.1'
}
def appVersionProps = new Properties()
def appVersionFile = file('VERSION.properties')
if (appVersionFile.exists()) {
appVersionFile.withInputStream { appVersionProps.load(it) }
}
def serverVersionFromFile = String.valueOf(appVersionProps.getProperty('server.version', '1.1_codex')).trim()
allprojects {
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
}
}
group = 'shine'
version = serverVersionFromFile
layout.buildDirectory.set(file('SHiNE-server/build'))
sourceSets {
main {
java.srcDirs = ['SHiNE-server/src/main/java']
resources.srcDirs = ['SHiNE-server/src/main/resources']
}
test {
java.srcDirs = ['SHiNE-server/src/test/java']
resources.srcDirs = ['SHiNE-server/src/test/resources']
}
}
tasks.jar {
enabled = false // это что бы не создавала обычный джар, а будет только толстый джар
}
tasks.processResources {
filteringCharset = 'UTF-8'
filesMatching('application.properties') {
expand(projectVersion: project.version.toString())
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.eclipse.jetty:jetty-server:11.0.20' // WS сервер
implementation 'org.eclipse.jetty:jetty-servlet:11.0.20'
implementation 'org.eclipse.jetty.websocket:websocket-jetty-server:11.0.20'
implementation 'org.bouncycastle:bcprov-jdk18on:1.78.1' // шифрование
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1' // json
// implementation 'org.slf4j:slf4j-api:2.0.9'
implementation 'ch.qos.logback:logback-classic:1.5.6'
// Logback (реализация SLF4J + классический модуль)
runtimeOnly "ch.qos.logback:logback-classic:1.5.6"
testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
implementation "org.slf4j:slf4j-api:2.0.16" // вызов логгера
// runtimeOnly "org.apache.logging.log4j:log4j-core:2.24.3" // Реализация: Log4j2 пишет в файл/консоль
// runtimeOnly "org.apache.logging.log4j:log4j-slf4j2-impl:2.24.3" // Реализация: Log4j2 пишет в файл/консоль
implementation project(':shine-server-config') // модуль настроек из application.properties
implementation project(":shine-server-log") // модуль логирования и уведомления админов
implementation project(':shine-server-crypto') // модуль сервера для работы с криптографией
implementation project(':shine-server-db') // модуль для работы с БД содержит и сущности из БД и саму работу с БД
implementation project(':shine-server-blockchain') // модуль для работы с блокчейном
implementation project(':shine-server-geo') // модуль для определения геолокации по IP
implementation project(':shine-server-net-protocol') // Модуль отвечающий за протокол (классы Net..Request/Response
implementation project(':shine-server-net-server') // Хэндлеры для обработки сетевых запросов
// -------------------- ТЕСТЫ (JUnit 5) --------------------
// Один BOM на всё семейство JUnit (Jupiter + Platform модули)
testImplementation platform("org.junit:junit-bom:5.10.2")
// JUnit Jupiter (Test, BeforeAll, Assertions)
testImplementation "org.junit.jupiter:junit-jupiter"
// JUnit Platform Suite (@Suite, @SelectClasses)
testImplementation "org.junit.platform:junit-platform-suite-api"
testRuntimeOnly "org.junit.platform:junit-platform-suite-engine"
// Нужно для компиляции RussianSummaryListener (org.junit.platform.launcher.*)
// и чтобы JUnit мог подхватить listener при запуске
testImplementation "org.junit.platform:junit-platform-launcher"
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
}
test {
useJUnitPlatform()
}
application {
// 👇 класс с методом main
mainClass = 'server.ws.WsServer'
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
shadowJar {
// создаём 1 файл без постфиксов
archiveBaseName.set('shine-server')
archiveClassifier.set('')
archiveVersion.set('')
mergeServiceFiles()
manifest {
attributes(
'Main-Class': 'server.ws.WsServer'
)
}
}
tasks.named('test') {
enabled = false
}
tasks.register('cleanServerLogs') {
group = "!!test"
description = "Clear server logs/app.log and remove rolled log files"
doLast {
File logsDir = file('SHiNE-server/logs')
if (!logsDir.exists()) {
logsDir.mkdirs()
}
File appLog = new File(logsDir, 'app.log')
if (!appLog.exists()) {
appLog.createNewFile()
}
appLog.text = ''
fileTree(logsDir) {
include 'app.*.log'
}.files.each { File f ->
if (!f.delete()) {
throw new GradleException("Failed to delete log file: ${f.absolutePath}")
}
}
println "Server logs cleared: ${logsDir.absolutePath}"
}
}
tasks.register('integrationTest', JavaExec) {
group = "!!test"
description = "Clean data → kill 7070 → start WS → run all IT tests"
classpath = sourceSets.test.runtimeClasspath
mainClass = "test.it.IT_RunAllCleanStartWsMain"
workingDir = file('SHiNE-server')
// пробрасываем системные флаги (по желанию)
systemProperty "it.debug", System.getProperty("it.debug", "true")
systemProperty "it.login", System.getProperty("it.login", "anya24")
dependsOn testClasses
}
tasks.named('build') {
finalizedBy tasks.named('integrationTest')
}
tasks.register('deployServer', JavaExec) {
group = "!!deployment"
description = "Build → upload to server → restart service (без удаления БД, без IT тестов)"
classpath = sourceSets.test.runtimeClasspath
mainClass = "test.it.IT_DeployRestartNoCleanNoTestsMain"
workingDir = file('SHiNE-server')
// можно переопределить при запуске:
// ./gradlew deployServer -Dit.remoteHost=... -Dit.wsUri=...
dependsOn shadowJar
systemProperty "it.remoteHost", System.getProperty("it.remoteHost", "shineup.me")
systemProperty "it.remoteUser", System.getProperty("it.remoteUser", "player")
systemProperty "it.remoteDir", System.getProperty("it.remoteDir", "/home/player/SHiNE/shine-server")
systemProperty "it.service", System.getProperty("it.service", "shine-server")
systemProperty "it.localJar", System.getProperty("it.localJar", "build/libs/shine-server.jar")
dependsOn testClasses
}
tasks.register('deployUI', Exec) {
group = "!!deployment"
description = "Deploy WEB UI (production: shineup.me)"
workingDir = rootDir
commandLine 'bash', file('deploy_shine-PWA.sh').absolutePath
}
tasks.register('startLocal', Exec) {
group = "!!run"
description = "Builds server, starts local WS server and local HTTP UI for end-to-end local testing"
dependsOn shadowJar
dependsOn cleanServerLogs
workingDir = rootDir
def wsPort = System.getProperty("localWsPort", "7070")
def webPort = System.getProperty("localWebPort", "8088")
commandLine 'bash', '-lc', """
set -euo pipefail
JAR_PATH="${file('SHiNE-server/build/libs/shine-server.jar').absolutePath}"
UI_DIR="${file('shine-UI').absolutePath}"
WS_PORT="${wsPort}"
WEB_PORT="${webPort}"
is_port_busy() {
local port="\$1"
if command -v ss >/dev/null 2>&1; then
ss -ltnH "sport = :\$port" | grep -q .
elif command -v lsof >/dev/null 2>&1; then
lsof -iTCP:"\$port" -sTCP:LISTEN >/dev/null 2>&1
else
return 1
fi
}
pick_free_port() {
local p="\$1"
while is_port_busy "\$p"; do
p=\$((p + 1))
done
echo "\$p"
}
WS_PORT="\$(pick_free_port "\$WS_PORT")"
WEB_PORT="\$(pick_free_port "\$WEB_PORT")"
echo "Starting SHiNE local stack..."
echo "WS server port: \$WS_PORT"
echo "UI HTTP port: \$WEB_PORT"
echo "Client URL: http://localhost:\$WEB_PORT/?localWsPort=\$WS_PORT"
(
cd "${file('SHiNE-server').absolutePath}"
java -Dserver.port="\$WS_PORT" -jar "\$JAR_PATH"
) &
SERVER_PID=\$!
trap 'kill \$SERVER_PID 2>/dev/null || true' EXIT INT TERM
CLIENT_URL="http://localhost:\$WEB_PORT/?localWsPort=\$WS_PORT"
if command -v xdg-open >/dev/null 2>&1; then
(xdg-open "\$CLIENT_URL" >/dev/null 2>&1 || true) &
elif command -v open >/dev/null 2>&1; then
(open "\$CLIENT_URL" >/dev/null 2>&1 || true) &
elif command -v cmd.exe >/dev/null 2>&1; then
(cmd.exe /c start "" "\$CLIENT_URL" >/dev/null 2>&1 || true) &
else
echo "Browser auto-open is not available on this host. Open manually: \$CLIENT_URL"
fi
SPA_SERVER_SCRIPT="${file('scripts/local_spa_server.py').absolutePath}"
if command -v python3 >/dev/null 2>&1; then
SHINE_UI_PORT="\$WEB_PORT" python3 "\$SPA_SERVER_SCRIPT"
else
SHINE_UI_PORT="\$WEB_PORT" python "\$SPA_SERVER_SCRIPT"
fi
"""
}
tasks.register('startLocalWithBuild') {
group = "!!run"
description = "Build server (build) and then start local stack (startLocal)"
dependsOn tasks.named('build')
dependsOn tasks.named('startLocal')
}
tasks.named('startLocal').configure {
mustRunAfter tasks.named('build')
}