diff options
15 files changed, 209 insertions, 53 deletions
diff --git a/api/src/main/java/market/guess/api/GuessMarketContext.java b/api/src/main/java/market/guess/api/GuessMarketContext.java index e11defb..4edb437 100644 --- a/api/src/main/java/market/guess/api/GuessMarketContext.java +++ b/api/src/main/java/market/guess/api/GuessMarketContext.java | |||
| @@ -2,6 +2,7 @@ package market.guess.api; | |||
| 2 | 2 | ||
| 3 | import java.math.BigDecimal; | 3 | import java.math.BigDecimal; |
| 4 | import market.guess.model.event.EventDetailDTO; | 4 | import market.guess.model.event.EventDetailDTO; |
| 5 | import market.guess.model.market.PurchaseReceiptDTO; | ||
| 5 | 6 | ||
| 6 | public interface GuessMarketContext { | 7 | public interface GuessMarketContext { |
| 7 | Result<PurchaseReceiptDTO> placeOrder( | 8 | Result<PurchaseReceiptDTO> placeOrder( |
diff --git a/api/src/main/java/market/guess/model/event/EventDetailDTO.java b/api/src/main/java/market/guess/model/event/EventDetailDTO.java index 9f59b53..f5c4edf 100644 --- a/api/src/main/java/market/guess/model/event/EventDetailDTO.java +++ b/api/src/main/java/market/guess/model/event/EventDetailDTO.java | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | package market.guess.model.event; | 1 | package market.guess.model.event; |
| 2 | 2 | ||
| 3 | import java.util.List; | 3 | import java.util.List; |
| 4 | import market.guess.api.MarketStateDTO; | 4 | import market.guess.model.market.MarketStateDTO; |
| 5 | import market.guess.api.TradeRowDTO; | 5 | import market.guess.model.market.TradeRowDTO; |
| 6 | 6 | ||
| 7 | public record EventDetailDTO( | 7 | public record EventDetailDTO( |
| 8 | EventSummaryDTO summary, | 8 | EventSummaryDTO summary, |
diff --git a/api/src/main/java/market/guess/api/MarketDTO.java b/api/src/main/java/market/guess/model/market/MarketDTO.java index b7c48a2..6b31375 100644 --- a/api/src/main/java/market/guess/api/MarketDTO.java +++ b/api/src/main/java/market/guess/model/market/MarketDTO.java | |||
| @@ -1,3 +1,3 @@ | |||
| 1 | package market.guess.api; | 1 | package market.guess.model.market; |
| 2 | 2 | ||
| 3 | public record MarketDTO(String key, String name, String price, String volume) {} | 3 | public record MarketDTO(String key, String name, String price, String volume) {} |
diff --git a/api/src/main/java/market/guess/api/MarketStateDTO.java b/api/src/main/java/market/guess/model/market/MarketStateDTO.java index da2fff0..3e9b967 100644 --- a/api/src/main/java/market/guess/api/MarketStateDTO.java +++ b/api/src/main/java/market/guess/model/market/MarketStateDTO.java | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package market.guess.api; | 1 | package market.guess.model.market; |
| 2 | 2 | ||
| 3 | import java.util.List; | 3 | import java.util.List; |
| 4 | import market.guess.model.event.MechanismType; | 4 | import market.guess.model.event.MechanismType; |
diff --git a/api/src/main/java/market/guess/api/PurchaseReceiptDTO.java b/api/src/main/java/market/guess/model/market/PurchaseReceiptDTO.java index 02e8007..0341542 100644 --- a/api/src/main/java/market/guess/api/PurchaseReceiptDTO.java +++ b/api/src/main/java/market/guess/model/market/PurchaseReceiptDTO.java | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package market.guess.api; | 1 | package market.guess.model.market; |
| 2 | 2 | ||
| 3 | import java.util.List; | 3 | import java.util.List; |
| 4 | 4 | ||
diff --git a/api/src/main/java/market/guess/api/TradeRowDTO.java b/api/src/main/java/market/guess/model/market/TradeRowDTO.java index 68d159a..d3053b3 100644 --- a/api/src/main/java/market/guess/api/TradeRowDTO.java +++ b/api/src/main/java/market/guess/model/market/TradeRowDTO.java | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | package market.guess.api; | 1 | package market.guess.model.market; |
| 2 | 2 | ||
| 3 | public record TradeRowDTO( | 3 | public record TradeRowDTO( |
| 4 | String at, String userName, String optionName, String quantity, String pricePaid) {} | 4 | String at, String userName, String optionName, String quantity, String pricePaid) {} |
diff --git a/service/src/main/java/market/guess/service/LocalGuessMarketContext.java b/service/src/main/java/market/guess/service/LocalGuessMarketContext.java index f04324b..c85dadf 100644 --- a/service/src/main/java/market/guess/service/LocalGuessMarketContext.java +++ b/service/src/main/java/market/guess/service/LocalGuessMarketContext.java | |||
| @@ -3,10 +3,10 @@ package market.guess.service; | |||
| 3 | import java.math.BigDecimal; | 3 | import java.math.BigDecimal; |
| 4 | import java.time.Instant; | 4 | import java.time.Instant; |
| 5 | import market.guess.api.GuessMarketContext; | 5 | import market.guess.api.GuessMarketContext; |
| 6 | import market.guess.api.PurchaseReceiptDTO; | ||
| 7 | import market.guess.api.Result; | 6 | import market.guess.api.Result; |
| 8 | import market.guess.api.TradeRowDTO; | ||
| 9 | import market.guess.model.event.EventDetailDTO; | 7 | import market.guess.model.event.EventDetailDTO; |
| 8 | import market.guess.model.market.PurchaseReceiptDTO; | ||
| 9 | import market.guess.model.market.TradeRowDTO; | ||
| 10 | import market.guess.service.catalog.infrastructure.MarketContext; | 10 | import market.guess.service.catalog.infrastructure.MarketContext; |
| 11 | import market.guess.service.domain.Order; | 11 | import market.guess.service.domain.Order; |
| 12 | import market.guess.service.fulfillment.FulfillmentContext; | 12 | import market.guess.service.fulfillment.FulfillmentContext; |
diff --git a/service/src/main/java/market/guess/service/catalog/infrastructure/adapter/LedgerMapper.java b/service/src/main/java/market/guess/service/catalog/infrastructure/adapter/LedgerMapper.java new file mode 100644 index 0000000..5a46540 --- /dev/null +++ b/service/src/main/java/market/guess/service/catalog/infrastructure/adapter/LedgerMapper.java | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | package market.guess.service.catalog.infrastructure.adapter; | ||
| 2 | |||
| 3 | import market.guess.model.ledger.LedgerDTO; | ||
| 4 | import market.guess.service.ledger.Ledger; | ||
| 5 | import org.mapstruct.Mapper; | ||
| 6 | |||
| 7 | @Mapper | ||
| 8 | public interface LedgerMapper { | ||
| 9 | LedgerDTO ledgerToLedgerDTO(Ledger ledger); | ||
| 10 | } | ||
diff --git a/service/src/main/java/market/guess/service/domain/Event.java b/service/src/main/java/market/guess/service/domain/Event.java index 1e17457..4517a4e 100644 --- a/service/src/main/java/market/guess/service/domain/Event.java +++ b/service/src/main/java/market/guess/service/domain/Event.java | |||
| @@ -4,13 +4,13 @@ import java.math.BigDecimal; | |||
| 4 | import java.time.Instant; | 4 | import java.time.Instant; |
| 5 | import java.util.ArrayList; | 5 | import java.util.ArrayList; |
| 6 | import java.util.List; | 6 | import java.util.List; |
| 7 | import market.guess.api.MarketDTO; | ||
| 8 | import market.guess.api.MarketStateDTO; | ||
| 9 | import market.guess.api.TradeRowDTO; | ||
| 10 | import market.guess.model.event.CommissionTiming; | 7 | import market.guess.model.event.CommissionTiming; |
| 11 | import market.guess.model.event.EventStatus; | 8 | import market.guess.model.event.EventStatus; |
| 12 | import market.guess.model.event.EventSummaryDTO; | 9 | import market.guess.model.event.EventSummaryDTO; |
| 13 | import market.guess.model.ledger.LedgerType; | 10 | import market.guess.model.ledger.LedgerType; |
| 11 | import market.guess.model.market.MarketDTO; | ||
| 12 | import market.guess.model.market.MarketStateDTO; | ||
| 13 | import market.guess.model.market.TradeRowDTO; | ||
| 14 | import market.guess.service.helpers.BigDecimalOptions; | 14 | import market.guess.service.helpers.BigDecimalOptions; |
| 15 | import market.guess.service.helpers.InstantOptions; | 15 | import market.guess.service.helpers.InstantOptions; |
| 16 | import market.guess.service.ledger.Ledger; | 16 | import market.guess.service.ledger.Ledger; |
diff --git a/service/src/main/java/market/guess/service/domain/Market.java b/service/src/main/java/market/guess/service/domain/Market.java index 3ff7e2d..c5960e3 100644 --- a/service/src/main/java/market/guess/service/domain/Market.java +++ b/service/src/main/java/market/guess/service/domain/Market.java | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | package market.guess.service.domain; | 1 | package market.guess.service.domain; |
| 2 | 2 | ||
| 3 | import java.math.BigDecimal; | 3 | import java.math.BigDecimal; |
| 4 | import market.guess.api.MarketDTO; | 4 | import market.guess.model.market.MarketDTO; |
| 5 | 5 | ||
| 6 | public final class Market { | 6 | public final class Market { |
| 7 | private final String key; | 7 | private final String key; |
diff --git a/service/src/test/java/market/guess/service/catalog/infrastructure/adapter/LedgerMapperTest.java b/service/src/test/java/market/guess/service/catalog/infrastructure/adapter/LedgerMapperTest.java new file mode 100644 index 0000000..976442c --- /dev/null +++ b/service/src/test/java/market/guess/service/catalog/infrastructure/adapter/LedgerMapperTest.java | |||
| @@ -0,0 +1,113 @@ | |||
| 1 | package market.guess.service.catalog.infrastructure.adapter; | ||
| 2 | |||
| 3 | import static org.junit.Assert.assertEquals; | ||
| 4 | import static org.junit.Assert.assertFalse; | ||
| 5 | import static org.junit.Assert.assertNull; | ||
| 6 | import static org.junit.Assert.assertTrue; | ||
| 7 | |||
| 8 | import java.math.BigDecimal; | ||
| 9 | import java.time.Instant; | ||
| 10 | import java.util.List; | ||
| 11 | import market.guess.model.ledger.LedgerDTO; | ||
| 12 | import market.guess.model.ledger.LedgerEntryDTO; | ||
| 13 | import market.guess.model.ledger.LedgerType; | ||
| 14 | import market.guess.service.ledger.Ledger; | ||
| 15 | import market.guess.service.ledger.LedgerEntry; | ||
| 16 | import org.junit.Test; | ||
| 17 | import org.mapstruct.factory.Mappers; | ||
| 18 | |||
| 19 | public class LedgerMapperTest { | ||
| 20 | |||
| 21 | private final LedgerMapper mapper = Mappers.getMapper(LedgerMapper.class); | ||
| 22 | |||
| 23 | @Test | ||
| 24 | public void nullLedgerMapsToNull() { | ||
| 25 | assertNull(mapper.ledgerToLedgerDTO(null)); | ||
| 26 | } | ||
| 27 | |||
| 28 | @Test | ||
| 29 | public void mapsOwnerAndBalanceAsStrings() { | ||
| 30 | Ledger ledger = new Ledger("alice", new BigDecimal("100")); | ||
| 31 | |||
| 32 | LedgerDTO dto = mapper.ledgerToLedgerDTO(ledger); | ||
| 33 | |||
| 34 | assertEquals("alice", dto.owner()); | ||
| 35 | assertEquals("100.00", dto.balance()); | ||
| 36 | } | ||
| 37 | |||
| 38 | @Test | ||
| 39 | public void emptyEntriesMapToEmptyList() { | ||
| 40 | Ledger ledger = new Ledger("alice", new BigDecimal("0")); | ||
| 41 | |||
| 42 | LedgerDTO dto = mapper.ledgerToLedgerDTO(ledger); | ||
| 43 | |||
| 44 | assertTrue(dto.entries().isEmpty()); | ||
| 45 | } | ||
| 46 | |||
| 47 | @Test | ||
| 48 | public void mapsEntryFieldsInOrder() { | ||
| 49 | Ledger ledger = new Ledger("bob", new BigDecimal("0")); | ||
| 50 | ledger.record( | ||
| 51 | new LedgerEntry( | ||
| 52 | 1, | ||
| 53 | Instant.parse("2026-01-01T00:00:00Z"), | ||
| 54 | LedgerType.DEPOSIT, | ||
| 55 | new BigDecimal("50.00"), | ||
| 56 | new BigDecimal("50.00"), | ||
| 57 | "first")); | ||
| 58 | ledger.record( | ||
| 59 | new LedgerEntry( | ||
| 60 | 2, | ||
| 61 | Instant.parse("2026-01-02T00:00:00Z"), | ||
| 62 | LedgerType.PURCHASE, | ||
| 63 | new BigDecimal("-20.00"), | ||
| 64 | new BigDecimal("30.00"), | ||
| 65 | "second")); | ||
| 66 | |||
| 67 | List<LedgerEntryDTO> entries = mapper.ledgerToLedgerDTO(ledger).entries(); | ||
| 68 | |||
| 69 | assertEquals(2, entries.size()); | ||
| 70 | LedgerEntryDTO first = entries.get(0); | ||
| 71 | assertEquals(LedgerType.DEPOSIT, first.type()); | ||
| 72 | assertEquals("50.00", first.amount()); | ||
| 73 | assertEquals("50.00", first.balanceAfter()); | ||
| 74 | assertEquals("first", first.note()); | ||
| 75 | LedgerEntryDTO second = entries.get(1); | ||
| 76 | assertEquals(LedgerType.PURCHASE, second.type()); | ||
| 77 | assertEquals("-20.00", second.amount()); | ||
| 78 | assertEquals("30.00", second.balanceAfter()); | ||
| 79 | assertEquals("second", second.note()); | ||
| 80 | } | ||
| 81 | |||
| 82 | @Test | ||
| 83 | public void nullAmountAndBalanceAfterMapToNullStrings() { | ||
| 84 | Ledger ledger = new Ledger("carol", new BigDecimal("0")); | ||
| 85 | ledger.record(new LedgerEntry(1, Instant.now(), LedgerType.REFUND, null, null, null)); | ||
| 86 | |||
| 87 | LedgerEntryDTO entry = mapper.ledgerToLedgerDTO(ledger).entries().get(0); | ||
| 88 | |||
| 89 | assertNull(entry.amount()); | ||
| 90 | assertNull(entry.balanceAfter()); | ||
| 91 | } | ||
| 92 | |||
| 93 | /** | ||
| 94 | * LedgerEntry.id/time and Ledger's account-blocked state have no matching AccountDTO/ | ||
| 95 | * LedgerEntryDTO source property, so MapStruct leaves them at their Java defaults. This pins that | ||
| 96 | * known gap; once the mapper is taught to fill seq/at/blocked, update these assertions instead of | ||
| 97 | * deleting them. | ||
| 98 | */ | ||
| 99 | @Test | ||
| 100 | public void unmappedTargetPropertiesFallBackToDefaults() { | ||
| 101 | Ledger ledger = new Ledger("dave", new BigDecimal("0")); | ||
| 102 | ledger.record( | ||
| 103 | new LedgerEntry( | ||
| 104 | 7, Instant.now(), LedgerType.COMMISSION, BigDecimal.ONE, BigDecimal.ONE, "n")); | ||
| 105 | |||
| 106 | LedgerDTO dto = mapper.ledgerToLedgerDTO(ledger); | ||
| 107 | |||
| 108 | assertFalse(dto.blocked()); | ||
| 109 | LedgerEntryDTO entry = dto.entries().get(0); | ||
| 110 | assertEquals(0L, entry.seq()); | ||
| 111 | assertNull(entry.at()); | ||
| 112 | } | ||
| 113 | } | ||
diff --git a/tools/_util.sh b/tools/_util.sh index fde4797..a041f2d 100644 --- a/tools/_util.sh +++ b/tools/_util.sh | |||
| @@ -5,15 +5,18 @@ case "$(uname -s)" in | |||
| 5 | *) SEP=":" ;; | 5 | *) SEP=":" ;; |
| 6 | esac | 6 | esac |
| 7 | 7 | ||
| 8 | MODULES="api service ui-console" | 8 | MODULES="api service ui-console ui-desktop" |
| 9 | 9 | ||
| 10 | DEPS_api="" | 10 | DEPS_api="" |
| 11 | DEPS_service="api" | 11 | DEPS_service="api" |
| 12 | DEPS_ui_console="api service" | 12 | DEPS_ui_console="api service" |
| 13 | DEPS_ui_desktop="" | ||
| 13 | 14 | ||
| 14 | RUNTIME_LIB_DIRS="pico jaxb gson" | 15 | RUNTIME_LIB_DIRS="pico jaxb gson openjfx" |
| 15 | 16 | ||
| 16 | MAIN_CLASS="market.guess.ui.console.App" | 17 | EXECUTABLES="ui-console ui-desktop" |
| 18 | MAINCLASS_ui_console="market.guess.ui.console.App" | ||
| 19 | MAINCLASS_ui_desktop="market.guess.ui.desktop.Launcher" | ||
| 17 | 20 | ||
| 18 | JAVA_HOME_DIR=$(java -XshowSettings:properties -version 2>&1 | tr -d '\r' | sed -n 's/^ *java\.home = //p') | 21 | JAVA_HOME_DIR=$(java -XshowSettings:properties -version 2>&1 | tr -d '\r' | sed -n 's/^ *java\.home = //p') |
| 19 | case "$(uname -s)" in | 22 | case "$(uname -s)" in |
| @@ -45,6 +48,24 @@ deps_of() { | |||
| 45 | eval "printf '%s' \"\${$v}\"" | 48 | eval "printf '%s' \"\${$v}\"" |
| 46 | } | 49 | } |
| 47 | 50 | ||
| 51 | mainclass_of() { | ||
| 52 | local v="MAINCLASS_$(echo "$1" | tr '-' '_')" | ||
| 53 | eval "printf '%s' \"\${$v}\"" | ||
| 54 | } | ||
| 55 | |||
| 56 | # JAR manifest lines are capped at 72 bytes; a raw "Key: value" line trips | ||
| 57 | # `line too long` once enough jars are on the Class-Path (openjfx pushed us | ||
| 58 | # over it). Fold per spec: continuation lines start with a single space. | ||
| 59 | write_manifest_attr() { | ||
| 60 | local file="$1" line="$2: $3" | ||
| 61 | : >"$file" | ||
| 62 | while [ "${#line}" -gt 72 ]; do | ||
| 63 | printf '%s\n' "${line:0:72}" >>"$file" | ||
| 64 | line=" ${line:72}" | ||
| 65 | done | ||
| 66 | printf '%s\n\n' "$line" >>"$file" | ||
| 67 | } | ||
| 68 | |||
| 48 | module_cp() { | 69 | module_cp() { |
| 49 | local cp="" | 70 | local cp="" |
| 50 | for d in "$@"; do cp="$cp${cp:+$SEP}build/classes/$d"; done | 71 | for d in "$@"; do cp="$cp${cp:+$SEP}build/classes/$d"; done |
diff --git a/tools/build.sh b/tools/build.sh index 72880ee..b8886b1 100755 --- a/tools/build.sh +++ b/tools/build.sh | |||
| @@ -15,9 +15,10 @@ for m in $MODULES; do | |||
| 15 | cp="${cp:+$cp$SEP}$LIBCP" | 15 | cp="${cp:+$cp$SEP}$LIBCP" |
| 16 | 16 | ||
| 17 | find "$m/src/main/java" -name '*.java' >"$TMP/src.txt" | 17 | find "$m/src/main/java" -name '*.java' >"$TMP/src.txt" |
| 18 | mkdir -p "build/classes/$m" | 18 | mkdir -p "build/classes/$m" "build/generated-sources/$m" |
| 19 | printf ' %-11s sees: %s\n' "$m" "${deps:-<nothing>}" | 19 | printf ' %-11s sees: %s\n' "$m" "${deps:-<nothing>}" |
| 20 | javac --release "$JAVA_RELEASE" -d "build/classes/$m" -cp "$cp" "@$TMP/src.txt" | 20 | javac --release "$JAVA_RELEASE" -d "build/classes/$m" -cp "$cp" \ |
| 21 | -processorpath "$LIBCP" -s "build/generated-sources/$m" "@$TMP/src.txt" | ||
| 21 | done | 22 | done |
| 22 | 23 | ||
| 23 | echo "=== Build OK ===" | 24 | echo "=== Build OK ===" |
diff --git a/tools/package.sh b/tools/package.sh index a85ee6c..186dab5 100644 --- a/tools/package.sh +++ b/tools/package.sh | |||
| @@ -22,63 +22,74 @@ for d in $RUNTIME_LIB_DIRS; do | |||
| 22 | echo " lib/$d/ ($n jars)" | 22 | echo " lib/$d/ ($n jars)" |
| 23 | done | 23 | done |
| 24 | 24 | ||
| 25 | echo "=== Generating console manifest ===" | 25 | echo "=== Generating executable manifests ===" |
| 26 | # Generated from what is actually staged, never hand-maintained. Four silent | 26 | # Generated from what is actually staged, never hand-maintained. Four silent |
| 27 | # failure modes: wildcards match nothing; a missing trailing newline makes jar | 27 | # failure modes: wildcards match nothing; a missing trailing newline makes jar |
| 28 | # drop the line; paths are relative to this jar; and java -jar ignores -cp, so | 28 | # drop the line; paths are relative to this jar; and java -jar ignores -cp, so |
| 29 | # this line is the entire classpath at runtime. | 29 | # this line is the entire classpath at runtime. |
| 30 | MF="$TMP/console-manifest.txt" | 30 | for e in $EXECUTABLES; do |
| 31 | CPLINE="" | 31 | CPLINE="" |
| 32 | for m in $MODULES; do | 32 | for m in $MODULES; do |
| 33 | [ "$m" = ui-console ] && continue | 33 | [ "$m" = "$e" ] && continue |
| 34 | CPLINE="$CPLINE${CPLINE:+ }$m.jar" | 34 | CPLINE="$CPLINE${CPLINE:+ }$m.jar" |
| 35 | done | 35 | done |
| 36 | for d in $RUNTIME_LIB_DIRS; do | 36 | for d in $RUNTIME_LIB_DIRS; do |
| 37 | for j in "$DIST"/lib/"$d"/*.jar; do | 37 | for j in "$DIST"/lib/"$d"/*.jar; do |
| 38 | [ -f "$j" ] || continue | 38 | [ -f "$j" ] || continue |
| 39 | CPLINE="$CPLINE lib/$d/$(basename "$j")" | 39 | CPLINE="$CPLINE lib/$d/$(basename "$j")" |
| 40 | done | ||
| 40 | done | 41 | done |
| 42 | write_manifest_attr "$TMP/$e-manifest.txt" "Class-Path" "$CPLINE" | ||
| 43 | echo " $e: $CPLINE" | ||
| 41 | done | 44 | done |
| 42 | printf 'Class-Path: %s\n\n' "$CPLINE" >"$MF" | ||
| 43 | echo " $CPLINE" | ||
| 44 | 45 | ||
| 45 | echo "=== Packaging ===" | 46 | echo "=== Packaging ===" |
| 46 | for m in $MODULES; do | 47 | for m in $MODULES; do |
| 47 | if [ "$m" = ui-console ]; then | 48 | case " $EXECUTABLES " in |
| 48 | "$JAR" --create --file "$DIST/$m.jar" \ | 49 | *" $m "*) |
| 49 | --main-class "$MAIN_CLASS" --manifest "$MF" -C "build/classes/$m" . | 50 | "$JAR" --create --file "$DIST/$m.jar" --main-class "$(mainclass_of "$m")" \ |
| 50 | else | 51 | --manifest "$TMP/$m-manifest.txt" -C "build/classes/$m" . |
| 52 | ;; | ||
| 53 | *) | ||
| 51 | "$JAR" --create --file "$DIST/$m.jar" -C "build/classes/$m" . | 54 | "$JAR" --create --file "$DIST/$m.jar" -C "build/classes/$m" . |
| 52 | fi | 55 | ;; |
| 56 | esac | ||
| 53 | echo " $DIST/$m.jar" | 57 | echo " $DIST/$m.jar" |
| 54 | done | 58 | done |
| 55 | 59 | ||
| 56 | cat >"$DIST/run.bat" <<'EOF' | 60 | for e in $EXECUTABLES; do |
| 61 | cat >"$DIST/run-${e#ui-}.bat" <<EOF | ||
| 57 | @echo off | 62 | @echo off |
| 58 | cd /d "%~dp0" | 63 | cd /d "%~dp0" |
| 59 | java -jar "%~dp0ui-console.jar" | 64 | java -jar "%~dp0$e.jar" |
| 60 | if errorlevel 1 pause | 65 | if errorlevel 1 pause |
| 61 | EOF | 66 | EOF |
| 67 | done | ||
| 62 | 68 | ||
| 63 | [ -f README.pdf ] && cp README.pdf "$DIST/" | 69 | [ -f README.pdf ] && cp README.pdf "$DIST/" |
| 64 | 70 | ||
| 65 | echo "=== Manifest as it actually landed in the jar ===" | 71 | echo "=== Manifest as it actually landed in the jar ===" |
| 66 | # Cheapest check that prevents a Level-0: if Main-Class or Class-Path didn't | 72 | # Cheapest check that prevents a Level-0: if Main-Class or Class-Path didn't |
| 67 | # survive, it surfaces here instead of on the grader's machine. | 73 | # survive, it surfaces here instead of on the grader's machine. |
| 68 | rm -rf "$TMP/mf" && mkdir -p "$TMP/mf" | 74 | for e in $EXECUTABLES; do |
| 69 | (cd "$TMP/mf" && "$JAR" -xf "$OLDPWD/$DIST/ui-console.jar" META-INF/MANIFEST.MF) | 75 | rm -rf "$TMP/mf" && mkdir -p "$TMP/mf" |
| 70 | sed 's/^/ /' "$TMP/mf/META-INF/MANIFEST.MF" | 76 | (cd "$TMP/mf" && "$JAR" -xf "$OLDPWD/$DIST/$e.jar" META-INF/MANIFEST.MF) |
| 77 | echo "-- $e.jar --" | ||
| 78 | sed 's/^/ /' "$TMP/mf/META-INF/MANIFEST.MF" | ||
| 71 | 79 | ||
| 72 | grep -q '^Main-Class:' "$TMP/mf/META-INF/MANIFEST.MF" || { | 80 | grep -q '^Main-Class:' "$TMP/mf/META-INF/MANIFEST.MF" || { |
| 73 | echo "*** Main-Class missing ***" | 81 | echo "*** Main-Class missing in $e.jar ***" |
| 74 | exit 1 | 82 | exit 1 |
| 75 | } | 83 | } |
| 76 | grep -q 'Class-Path:' "$TMP/mf/META-INF/MANIFEST.MF" || { | 84 | grep -q 'Class-Path:' "$TMP/mf/META-INF/MANIFEST.MF" || { |
| 77 | echo "*** Class-Path missing ***" | 85 | echo "*** Class-Path missing in $e.jar ***" |
| 78 | exit 1 | 86 | exit 1 |
| 79 | } | 87 | } |
| 88 | done | ||
| 80 | 89 | ||
| 81 | echo "======================================" | 90 | echo "======================================" |
| 82 | echo "Self-contained output in $DIST" | 91 | echo "Self-contained output in $DIST" |
| 83 | echo " cd $DIST && java -jar ui-console.jar" | 92 | for e in $EXECUTABLES; do |
| 93 | echo " cd $DIST && java -jar $e.jar" | ||
| 94 | done | ||
| 84 | echo "======================================" | 95 | echo "======================================" |
diff --git a/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java b/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java index 3ff752c..69a9a9a 100644 --- a/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java +++ b/ui-console/src/main/java/market/guess/ui/console/io/InputProcessor.java | |||
| @@ -5,9 +5,9 @@ import java.nio.file.Path; | |||
| 5 | import java.util.List; | 5 | import java.util.List; |
| 6 | import java.util.Scanner; | 6 | import java.util.Scanner; |
| 7 | import java.util.function.Function; | 7 | import java.util.function.Function; |
| 8 | import market.guess.api.MarketStateDTO; | 8 | import market.guess.model.market.MarketStateDTO; |
| 9 | import market.guess.api.PurchaseReceiptDTO; | 9 | import market.guess.model.market.PurchaseReceiptDTO; |
| 10 | import market.guess.api.TradeRowDTO; | 10 | import market.guess.model.market.TradeRowDTO; |
| 11 | 11 | ||
| 12 | public final class InputProcessor { | 12 | public final class InputProcessor { |
| 13 | private static final int OPTION_WIDTH = 18; | 13 | private static final int OPTION_WIDTH = 18; |
| @@ -192,4 +192,3 @@ public final class InputProcessor { | |||
| 192 | padRight(at, AT_WIDTH)); | 192 | padRight(at, AT_WIDTH)); |
| 193 | } | 193 | } |
| 194 | } | 194 | } |
| 195 | |||