Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7e25169
Convert PCGen-base and PCGen-Formula to JPMS subprojects
Vest May 16, 2026
2fa9e7f
Phase 6: Migrate main source to new PCGen-Formula/PCGen-base APIs
Vest May 16, 2026
08034b6
Fix simple test compilation errors for new PCGen-Formula/PCGen-base APIs
Vest May 16, 2026
afb54fb
Fix test compilation and runtime failures for JPMS API migration
Vest May 16, 2026
a457367
Update Gradle wrapper to 9.5.1
Vest May 16, 2026
0330b17
Remove processSolver calls after user-input channel writes
Vest May 16, 2026
a22ace8
Open pcgen.cdom.base to pcgen.base for StagingProxy reflection access
Vest May 16, 2026
62f37d5
Add JUnit Platform Launcher to subproject test dependencies
Vest May 17, 2026
febc907
Revert String equality branch in CaseInsensitiveString.equals()
Vest May 17, 2026
2ace84f
Restore processSolver after addModifier/removeModifier in SolverManag…
Vest May 17, 2026
9541b0e
Resolve global scope correctly in SolverManagerFacet
Vest May 17, 2026
2cb73bb
Copy globalVarScopedMap entry on PlayerCharacter clone
Vest May 17, 2026
0eeccaa
Fix CI release pipeline after JPMS subproject migration
Vest May 19, 2026
d8091ee
Generate PCGen-Formula parser at build time via JJTree+JavaCC
Vest May 19, 2026
76b69bd
Generate redundant JJTree outputs at build time
Vest May 19, 2026
df818ee
Document why SimpleNode is hand-maintained
Vest May 19, 2026
d29929b
Fix DynamicScope.getName() to return fully-qualified scope name
Vest May 19, 2026
65ac6ab
Fix getLocalVariableID to use owner's local scope, not global PC scope
Vest May 19, 2026
beb7593
Address Sonar issues in VariableUtilities
Vest May 19, 2026
137c116
Fix stale links and git rebase command in README
Vest May 19, 2026
fcc45a8
Include PCGen-base and PCGen-Formula test results in CI report
Vest May 19, 2026
69993f6
Drop unused orange-extensions compileOnly dependency
Vest May 19, 2026
2c15a06
Move xmlunit-core to testImplementation scope
Vest May 19, 2026
ca9df42
Add UNICODE_INPUT=true to suppress JavaCC non-ASCII warning
Vest May 19, 2026
fa680c1
Document fullJpackage as the correct native bundle task
Vest May 19, 2026
aa8da72
Remove dead cross-platform build infrastructure from jlink/jpackage
Vest May 19, 2026
056aad4
Collapse per-platform JDK/JFX tasks to single host-targeted tasks
Vest May 19, 2026
a6fc5f1
Disable unused distZip/distTar tasks
Vest May 19, 2026
6eb0132
Remove dead build tasks and stale debug prints
Vest May 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/gradle-release-manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,10 @@ jobs:
cache-read-only: false
cache-overwrite-existing: true

# Cache cross-platform JDK and JavaFX jmod archives downloaded by
# downloadJdk_* / downloadJavaFXMods_* tasks. These are pinned by
# Cache the host-platform JDK and JavaFX jmod archives downloaded by
# the downloadJdk / downloadJfxMods tasks. Filenames are stamped with
# ${hostOs}_${hostArch}, so each runner OS gets its own cache bucket
# via the runner-keyed actions/cache key. These are pinned by
# javaVersion (gradle.properties) and the URL templates (build.gradle),
# so keying on those file hashes invalidates correctly when we bump
# the JDK or JavaFX version. We cache only the archives (.tar.gz / .zip)
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/gradle-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,10 @@ jobs:
cache-read-only: false
cache-overwrite-existing: true

# Cache cross-platform JDK and JavaFX jmod archives downloaded by
# downloadJdk_* / downloadJavaFXMods_* tasks. These are pinned by
# Cache the host-platform JDK and JavaFX jmod archives downloaded by
# the downloadJdk / downloadJfxMods tasks. Filenames are stamped with
# ${hostOs}_${hostArch}, so each runner OS gets its own cache bucket
# via the runner-keyed actions/cache key. These are pinned by
# javaVersion (gradle.properties) and the URL templates (build.gradle),
# so keying on those file hashes invalidates correctly when we bump
# the JDK or JavaFX version. We cache only the archives (.tar.gz / .zip)
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/gradle-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ jobs:
build/test-results/**/*.xml
build/test-results/**/*.trx
build/test-results/**/*.json
PCGen-base/build/test-results/**/*.xml
PCGen-base/build/test-results/**/*.trx
PCGen-base/build/test-results/**/*.json
PCGen-Formula/build/test-results/**/*.xml
PCGen-Formula/build/test-results/**/*.trx
PCGen-Formula/build/test-results/**/*.json

- name: Run Coverage
run: ./gradlew testCoverage
Expand Down
3 changes: 1 addition & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ Always use the wrapper (./gradlew). Java 25 is required; Gradle will fetch depen
- ./gradlew clean (also triggers cleanPlugins, cleanOutput, cleanJdks, cleanMods, cleanMasterSheets)

Notes
- Some tasks trigger downloads of JDKs/JavaFX for all platforms (downloadJDKs, extractJDKs, downloadJavaFXMods) or host SDK (downloadJavaFXLocal/extractJavaFXLocal). CI caches build/jre and build/libs.
- The `jre` task prepares all platform JDKs with JavaFX modules for runtime image creation.
- jlink/jpackage build only the host platform. The download/extract tasks (downloadJdk, extractJdk, downloadJfxMods, extractJfxMods) target the host OS/arch automatically; the host SDK helper for local dev is downloadJavaFXLocal/extractJavaFXLocal. CI caches build/jre and build/libs.
- Runtime bundles expect assets in data/, system/, outputsheets/, preview/, vendordata/, homebrewdata/.

## Running From Source
Expand Down
219 changes: 63 additions & 156 deletions PCGen-Formula/build.gradle
Original file line number Diff line number Diff line change
@@ -1,186 +1,93 @@
/*
* PCGen formula component build using the Gradle tool. This file specifies the
* core build tasks and refers to other files in the code/gradle directory for
* additional tasks for specific output.
*
* Developer build: gradle
* Incremental dev build: gradle build
* Full build: gradle all
*/

plugins {
id "ca.coglinc2.javacc" version "3.0.0"
id 'java'
id 'eclipse'
id 'jacoco'
id 'ivy-publish'
id 'checkstyle'
id 'pmd'
id 'com.github.ben-manes.versions' version '0.39.0'
id 'com.github.spotbugs' version '4.7.5'
id 'java-library'
}

group = 'net.sourceforge.pcgen'
description = """PCGen formula library"""

defaultTasks 'clean', 'build'

sourceCompatibility = 1.11
targetCompatibility = 1.11

ext {
majorVersion = 1
minorVersion = 0
}
description = 'PCGen formula library - generic expression parser and solver system'

repositories {
mavenCentral()
ivy {
name "Pcgen Repo"
url 'http://pc-gen.org/librepo'
allowInsecureProtocol true
java {
toolchain {
languageVersion = JavaLanguageVersion.of(25)
}
modularity.inferModulePath = true
}

dependencies {
// Use this if you want to reference your own local pcgen base, alter the
// relative path to what you need.
//compile files("../../pcgen-base/PCGen-base/build/libs/PCgen-base-1.0.jar")

implementation group: 'net.sourceforge.pcgen', name: 'PCGen-base', version:'1.0.220'
testImplementation group: 'org.junit.platform', name: 'junit-platform-runner', version: '1.8.0'
testImplementation group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.7.2'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.0'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.8.0'
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.8.0'
}
def generatedJjtreeDir = layout.buildDirectory.dir('generated/sources/jjtree').get().asFile
def generatedJavaccDir = layout.buildDirectory.dir('generated/sources/javacc').get().asFile

sourceSets {
main {
java {
srcDirs 'code/src/java'
}
}
javacc {
java {
srcDirs 'code/src/javacc'
}
java { srcDirs = ['code/src/java', generatedJjtreeDir, generatedJavaccDir] }
}
test {
java {
srcDirs 'code/src/test'
}
}
}

test {
useJUnitPlatform()
reports {
junitXml.enabled = true
html.enabled = false
java { srcDirs = ['code/src/test'] }
}
systemProperties 'property': 'value'
}

jacocoTestReport {
reports {
xml {
enabled true // coveralls plugin depends on xml format report
}

html {
enabled true
}
}

afterEvaluate {
getClassDirectories().from(files(classDirectories.files.collect {
fileTree(dir: it, exclude: ['**/testsupport/**', '**/Abstract**TestCase', '**/**Test', 'pcgen/base/formula/parse/FormulaParser**', 'pcgen/base/formula/parse/AST**', 'pcgen/base/formula/parse/JJT**', 'pcgen/base/formula/parse/Node**', 'pcgen/base/formula/parse/ParseException**', 'pcgen/base/formula/parse/SimpleCharStream**', 'pcgen/base/formula/parse/Token**'])
}))
}
}

compileJjtree {
inputDirectory = file('code/src/jjtree')
// We consciously choose to put the output in the main repo tree so that
// SimpleNode only exists once...
outputDirectory = file('code/src/javacc/')
include '**/*.java'
repositories {
mavenCentral()
}

compileJavacc {
inputDirectory = file('code/src/javacc/')
outputDirectory = file('code/src/java/')
configurations {
javacc
}

// Calculate the version number - runs in the parse phase
allprojects {
ext.buildTimestamp = new Date().format('yyyy-MM-dd HH:mm:ss Z')
if (System.env.BUILD_NUMBER) {
project.version = "$majorVersion.$minorVersion.$System.env.BUILD_NUMBER"
dependencies {
api project(':PCGen-base')

javacc 'net.java.dev.javacc:javacc:7.0.13'

testImplementation platform('org.junit:junit-bom:5.11.4')
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.junit.jupiter:junit-jupiter-params'
testImplementation 'junit:junit:4.13.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

// SimpleNode.java and Operator.java in code/src/java are hand-maintained; everything
// else in pcgen/base/formula/parse is generated at build time. JJTree produces the AST
// classes, the visitor interfaces, and an annotated .jj grammar; JavaCC then turns the
// .jj into the parser and token classes.
tasks.register('jjtree', JavaExec) {
def src = file('code/src/jjtree/pcgen/base/formula/parse/formula.jjt')
def outDir = new File(generatedJjtreeDir, 'pcgen/base/formula/parse')
inputs.file(src)
outputs.dir(generatedJjtreeDir)
classpath = configurations.javacc
mainClass = 'jjtree'
args "-OUTPUT_DIRECTORY=${outDir}", src.absolutePath
doFirst {
generatedJjtreeDir.deleteDir()
outDir.mkdirs()
}
else {
project.version = "$majorVersion.$minorVersion"
doLast {
// SimpleNode is hand-maintained in code/src/java; drop JJTree's stub so the
// two don't collide on the source path.
new File(outDir, 'SimpleNode.java').delete()
}
}

task echoVer() doLast {
println "${project.name} Version: ${project.version} (${buildTimestamp})"
}

jar {
manifest {
attributes 'Implementation-Title': 'PCGenFormulaLibrary', 'Implementation-Version': project.version,
'Built-On': buildTimestamp
tasks.register('javacc', JavaExec) {
dependsOn 'jjtree'
def jjFile = new File(generatedJjtreeDir, 'pcgen/base/formula/parse/formula.jj')
def outDir = new File(generatedJavaccDir, 'pcgen/base/formula/parse')
inputs.file(jjFile)
outputs.dir(generatedJavaccDir)
classpath = configurations.javacc
mainClass = 'javacc'
args "-OUTPUT_DIRECTORY=${outDir}", jjFile.absolutePath
doFirst {
generatedJavaccDir.deleteDir()
outDir.mkdirs()
}
}

task sourceJar(type: Jar) {
from sourceSets.main.java
classifier "sources"
tasks.named('compileJava') {
dependsOn 'javacc'
}

task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
tasks.named('test') {
useJUnitPlatform()
}

// Rules for how we publish our artifacts in ivy compliant format
publishing {
repositories {
ivy {
name "fileRepo"
url '/var/www/librepo'
}
}
publications {
ivy(IvyPublication) {
from components.java
configurations {
sources {}
javadoc {}
}
artifact(sourceJar) {
type "sources"
conf "sources"
}
artifact(javadocJar) {
type "javadoc"
conf "javadoc"
}
descriptor.withXml {
asNode().info[0].appendNode('description', description)
}
}
}
}

//We end up with an unneeded task with SpotBugs and JavaCC that causes a failure
//see: https://github.com/spotbugs/spotbugs-gradle-plugin/issues/70
tasks.whenTaskAdded {task ->
if(task.name.contains("spotbugsJavacc")) {
task.enabled = false
}
}

apply from: 'gradle/reporting.gradle'
20 changes: 20 additions & 0 deletions PCGen-Formula/code/src/java/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module pcgen.formula {
requires transitive pcgen.base;

exports pcgen.base.formula;
exports pcgen.base.formula.analysis;
exports pcgen.base.formula.base;
exports pcgen.base.formula.exception;
exports pcgen.base.formula.factory;
exports pcgen.base.formula.function;
exports pcgen.base.formula.inst;
exports pcgen.base.formula.library;
exports pcgen.base.formula.operator.array;
exports pcgen.base.formula.operator.bool;
exports pcgen.base.formula.operator.generic;
exports pcgen.base.formula.operator.number;
exports pcgen.base.formula.operator.string;
exports pcgen.base.formula.parse;
exports pcgen.base.formula.visitor;
exports pcgen.base.solver;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package pcgen.base.formula.inst;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -70,4 +71,13 @@ public boolean isRelated(ImplementedScope scope1, ImplementedScope scope2)
|| scope2.drawsFrom().contains(scope1);
}

/**
* Returns a Collection of all ImplementedScope objects in this library.
*
* @return A Collection of all ImplementedScope objects
*/
public Collection<ImplementedScope> getScopes()
{
return scopeCache.values();
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# Generated by JJTree from code/src/jjtree/.../formula.jjt at build time.
/AST*.java
/FormulaParserDefaultVisitor.java
/FormulaParserTreeConstants.java
/FormulaParserVisitor.java
/JJTFormulaParserState.java
/Node.java

# Generated by JavaCC from the JJTree-produced .jj at build time.
/formula.jj
/FormulaParser.java
/FormulaParserConstants.java
Expand Down
Loading
Loading