From d0467d259bb04fd746ddb08708cfdaea71519fa0 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Wed, 20 Dec 2023 15:02:24 +0100 Subject: [PATCH 001/106] FEAT: impl new tests container --- .github/workflows/builddocker.yml | 42 +++++++++++++++++++++++++++++++ .github/workflows/test.yml | 30 ++++++++-------------- Dockerfile | 30 ++++++++++++++++++++++ docker-compose.yml | 19 +++----------- 4 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 .github/workflows/builddocker.yml create mode 100644 Dockerfile diff --git a/.github/workflows/builddocker.yml b/.github/workflows/builddocker.yml new file mode 100644 index 00000000000..401ecb2cf86 --- /dev/null +++ b/.github/workflows/builddocker.yml @@ -0,0 +1,42 @@ +name: Build and publish busted tests docker image +on: + workflow_dispatch: +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Generate docker image metadata + uses: docker/metadata-action@v5 + id: meta + with: + images: | + ghcr.io/${{ github.repository_owner }}/busted-tests + labels: | + org.opencontainers.image.description=A docker image packaged with the correct verions of tools to run PathOfBuilding busted tests. Includes emmylua debugger files. Refer to https://github.com/Paliak/PathOfBuilding/blob/tests-rework/CONTRIBUTING.md#setting-up-a-development-environment for usage instructions. + org.opencontainers.image.licenses=https://opensource.org/licenses/MIT + tags: | + type=sha + type=raw,value=latest + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + platforms: linux/amd64 + cache-from: type=gha + cache-to: type=gha,mode=max + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d77adae0be..6e1c5b0ee3f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,28 +1,20 @@ name: Run Tests on: + workflow_dispatch: push: branches: [ dev ] pull_request: branches: [ dev ] jobs: - run_tests: + run_unit_tests: runs-on: ubuntu-latest + container: + # No good way to automatically get the lowercase repo owner name here. + image: ghcr.io/paliak/busted-tests:latest + volumes: + - ${{ github.workspace }}:/root steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Install Lua/LuaJIT - uses: leafo/gh-actions-lua@v8.0.0 - with: - luaVersion: "luajit-2.0.5" - - name: Install LuaRocks - uses: leafo/gh-actions-luarocks@v4.0.0 - - name: Install busted - run: luarocks install busted - - name: Install cluacov - run: luarocks install cluacov - - name: Install coveralls integration - run: luarocks install luacov-coveralls - - name: Run tests - run: busted --lua=/home/runner/work/PathOfBuilding/PathOfBuilding/.lua/bin/luajit - - name: Report coverage - run: cd src; luacov-coveralls --repo-token=${{ secrets.github_token }} -e TestData -e Data -e runtime + - name: Checkout repository + uses: actions/checkout@v4 + - name: Run busted tests + run: busted --lua=luajit \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000000..75d11d48a99 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +FROM alpine:3.18 as base +RUN apk add --no-cache wget unzip openssl build-base readline-dev cmake readline-dev git ca-certificates + +FROM base as buildbase +WORKDIR /opt +RUN wget https://www.lua.org/ftp/lua-5.1.5.tar.gz && tar -xf lua-5.1.5.tar.gz +RUN cd lua-5.1.5 && make linux && make install + +FROM buildbase as luarocks +RUN wget https://luarocks.org/releases/luarocks-3.7.0.tar.gz && tar xf luarocks-3.7.0.tar.gz +RUN cd luarocks-3.7.0 && ./configure && make + +FROM buildbase as luajit +RUN git clone --depth 1 --branch v2.1.0-beta3 https://github.com/LuaJIT/LuaJIT +RUN cd LuaJIT && make + +FROM buildbase as emmyluadebugger +RUN git clone --depth 1 --branch 1.7.1 https://github.com/EmmyLua/EmmyLuaDebugger +RUN cd EmmyLuaDebugger && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release ../ && make + +FROM base +RUN --mount=type=cache,from=buildBase,source=/opt,target=/opt make -C /opt/lua-5.1.5/ install +RUN --mount=type=cache,from=luarocks,source=/opt,target=/opt make -C /opt/luarocks-3.7.0/ install +RUN luarocks install busted && luarocks install cluacov +RUN --mount=type=cache,from=luajit,source=/opt,target=/opt make -C /opt/LuaJIT/ install +RUN ln -sf /usr/local/bin/luajit-2.1.0-beta3 /usr/local/bin/luajit +RUN --mount=type=cache,from=emmyluadebugger,source=/opt,target=/opt make -C /opt/EmmyLuaDebugger/build/ install + +WORKDIR /root +CMD busted --lua=luajit \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index ebb2a04a9c4..a65bab7e2d2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,19 +1,8 @@ -version: "3.8" services: - busted-tests: - image: summ1else/poe-busted-image + build: . container_name: busted-tests - command: bash -c "rm -f spec/test_results.log && busted --lua=luajit | tee spec/test_results.log" + ports: + - "9966:9966" volumes: - - ./:/root - depends_on: - - busted-generate-build - - busted-generate-build: - image: summ1else/poe-busted-image - container_name: busted-generate-build - command: bash -c "rm -f spec/test_generation.log && busted --lua=luajit -r generate | tee spec/test_generation.log" - restart: "no" - volumes: - - ./:/root + - ./:/root \ No newline at end of file From bc1de3f9782748f489c547cc23cdf93c6bcebd7d Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 01:52:37 +0100 Subject: [PATCH 002/106] FEAT: initial implementaion of test build logic --- .github/workflows/test.yml | 54 ++++++++++++++++++++++++++++++++++++-- Dockerfile | 2 +- docker-compose.yml | 13 +++++++-- spec/GenerateBuilds.lua | 9 ++++--- spec/buildDiff.sh | 29 ++++++++++++++++++++ src/Modules/Data.lua | 2 +- 6 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 spec/buildDiff.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6e1c5b0ee3f..165f705bc6e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,11 +10,61 @@ jobs: runs-on: ubuntu-latest container: # No good way to automatically get the lowercase repo owner name here. - image: ghcr.io/paliak/busted-tests:latest + image: ghcr.io/paliak/busted-tests volumes: - ${{ github.workspace }}:/root steps: - name: Checkout repository uses: actions/checkout@v4 - name: Run busted tests - run: busted --lua=luajit \ No newline at end of file + run: busted --lua=luajit + run_build_diff: + runs-on: ubuntu-latest + container: + # No good way to automatically get the lowercase repo owner name here. + image: ghcr.io/paliak/busted-tests + volumes: + - ${{ github.workspace }}:/root + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup environment + run: > + mkdir /cache; + cd /root && + git config --global --add safe.directory /root && + echo "DEV_BRANCH_SHA=$(git rev-parse dev)" >> $GITHUB_ENV + - name: Check if build cache exists + id: cache-builds + uses: actions/cache@v3 + env: + cache-name: cached-dev-builds + with: + path: /cache + key: ${{ env.DEV_BRANCH_SHA }} + - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} + name: Generate builds in reference to dev branch + run: > + mkdir /devRef && + cp -r /root/. /devRef/ && + cd /devRef && + git restore . && + git clean -fd && + git checkout dev && + cp /root/.busted . && + rm -rf /devRef/spec/ && + cp -r /root/spec/ /devRef/spec/ && + BUILDCACHEPREFIX='/cache' busted --lua=luajit -r generate && + date > "/cache/${{ env.DEV_BRANCH_SHA }}" && + cd /root + - name: Generate builds in reference to current commit + run: busted --lua=luajit -r generate + - name: Display differences + run: > + for build in /cache/*.lua; + do + BASENAME=$(basename "$build"); + echo "[-] Diff for $BASENAME"; + diff "$build" "/tmp/$BASENAME"; + echo "[+] Diff for $BASENAME"; + done diff --git a/Dockerfile b/Dockerfile index 75d11d48a99..ebea48b0260 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM alpine:3.18 as base -RUN apk add --no-cache wget unzip openssl build-base readline-dev cmake readline-dev git ca-certificates +RUN apk add --no-cache wget unzip openssl build-base readline-dev cmake readline-dev git ca-certificates tar FROM base as buildbase WORKDIR /opt diff --git a/docker-compose.yml b/docker-compose.yml index a65bab7e2d2..11e6c85f813 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,17 @@ services: busted-tests: - build: . + #build: . + image: ghcr.io/paliak/busted-tests container_name: busted-tests ports: - "9966:9966" volumes: - - ./:/root \ No newline at end of file + - ./:/root + busted-diff: + #build: . + image: ghcr.io/paliak/busted-tests + container_name: busted-diff + command: /bin/sh -c ./spec/buildDiff.sh + volumes: + - ./:/root + - /tmp/buildcache:/cache \ No newline at end of file diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index 514357fdcca..70828ab63c9 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -15,7 +15,7 @@ local function fetchBuilds(path, buildList) end local fileText = fileHnd:read("*a") fileHnd:close() - buildList[f] = fileText + buildList[file] = fileText end end end @@ -42,12 +42,13 @@ function buildTable(tableName, values, string) end local buildList = fetchBuilds("../spec/TestBuilds") + + for filename, testBuild in pairs(buildList) do + print("[+] Computing " .. filename) loadBuildFromXML(testBuild) - local fileHnd, errMsg = io.open(filename:gsub("^(.+)%..+$", "%1.lua"), "w+") - fileHnd:write("return {\n xml = [[") + local fileHnd, errMsg = io.open(filename:gsub("(.+)%..+$", (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/%1.lua"), "w+") fileHnd:write(testBuild) - fileHnd:write("]],\n ") fileHnd:write(buildTable("output", build.calcsTab.mainOutput) .. "\n}") fileHnd:close() end \ No newline at end of file diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh new file mode 100644 index 00000000000..64ba95e10a4 --- /dev/null +++ b/spec/buildDiff.sh @@ -0,0 +1,29 @@ +#!/bin/sh +headref=$(git rev-parse HEAD) +devref=$(git rev-parse dev) + +if [[ ! -f "/cache/$devref" ]] # Output of builds outdated or nonexistent +then + git config --global --add safe.directory /root && \ + mkdir /devRef && cp -r /root/. /devRef/ && cd /devRef && \ + git restore . && git clean -fd && git checkout dev && \ + cp /root/.busted . && rm -rf /devRef/spec/ && cp -r /root/spec/ /devRef/spec/ && \ + BUILDCACHEPREFIX='/cache' busted --lua=luajit -r generate && \ + date > "/cache/$devref" && cd /root && echo "[+] Build cache computed for $devref"; rm -rf /devRef +fi + +if [[ -f "/cache/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev +then + BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && && echo "[+] Build cache computed for $headref" +fi + +if [[ -f "/tmp/$headref" ]] # Make sure generating builds for current HEAD was successful +then + for build in /cache/*.lua + do + BASENAME=$(basename "$build") + echo "[-] Diff for $BASENAME" + diff "$build" "/tmp/$BASENAME" + echo "[+] Diff for $BASENAME" + done +fi diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index 654d49821a3..9623d7bd380 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -859,7 +859,7 @@ data.printMissingMinionSkills = function() for _, minion in pairs(data.minions) do for _, skillId in ipairs(minion.skillList) do if not data.skills[skillId] and not missing[skillId] then - ConPrintf("'%s' missing skill '%s'", minion.name, skillId) + --ConPrintf("'%s' missing skill '%s'", minion.name, skillId) missing[skillId] = true end end From ad84c6a74a72c0b1c042bc3b67ffe5c2cc8b4c8c Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 03:17:24 +0100 Subject: [PATCH 003/106] DOCS: add some documentation on how to use emmy lua with docker --- CONTRIBUTING.md | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8a9f4b1fa84..cda3c10a939 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -214,20 +214,18 @@ More tests can be added to this folder to test specific functionality, or new te Docker alternative: 1. Install [Docker](https://www.docker.com/get-started) -2. Run `docker-compose up -d` from the command line -3. View last results in `spec/test_results.log` +2. Run `docker-compose up` from the command line -### Creating new test builds or fixing an existing build - -Sometimes a change will be made that intends to change the stats garnered by PoB, which will break our tests. -1. Add the new build XML (if applicable) to the `TestBuilds` folder -2. Run `busted --lua=luajit -r generate` to generate a LUA file that contains the current stats of that build -3. Run `busted --lua=luajit` and the tests should pass - -Docker alternative: - -1. Add the new build XML (if applicable) to the `TestBuilds` folder -2. Run `docker-compose up -d` to generate a LUA file that contains the current stats of that build and run the tests +### Debugging tests +When running tests with a docker container it is possible to use emmylua for debugging. Paste in the following right under `function launch:OnInit()` in `./src/Launch.lua`: +```lua +package.cpath = package.cpath .. ";/usr/local/bin/?.so" +local dbg = require("emmy_core") +-- This port must match the Visual Studio Code configuration. Default is 9966. +dbg.tcpListen("localhost", 9966) +dbg.waitIDE() +``` +After running `docker-compose up` the code will wait at the `dbg.waitIDE()` line until a debugger is attached. This will allow stepping through any code that is internal to POB but will not work for busted related code. ## Path of Building development tutorials From 97529ce551b14faf6e44bf2ef348eb6a6ffc97db Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 03:21:38 +0100 Subject: [PATCH 004/106] DOCS: update line about modcache --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cda3c10a939..7d56e70498d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ Feature requests are always welcome. Note that not all requests will receive an ### When submitting a pull request: * **Pull requests must be created against the `dev` branch**, as all changes to the code are staged there before merging to `master`. * Make sure that the changes have been thoroughly tested! -* Make sure not to commit `./src/Data/ModCache.lua`. This is a very large, automatically generated file that is updated in the repository for releases only. +* Make sure to commit `./src/Data/ModCache.lua` if your changes cause it to differ. This will generally be caused by editing `./src/Modules/ModParser.lua`. * There are many more files in the `./src/Data` directory that are automatically generated. This is indicated by the header `-- This file is automatically generated, do not edit!`. To change these, instead change the scripts in the `./src/Export` directory and rerun the exporter. For your PR, please include all relevant changes to both the scripts and data files. From 7b3d334d230f6e373f7576e1e168630b29ac2850 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 03:36:14 +0100 Subject: [PATCH 005/106] FIX: docker compose build-diff script --- spec/buildDiff.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 64ba95e10a4..0b6e2e7c9f2 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -14,7 +14,7 @@ fi if [[ -f "/cache/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev then - BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && && echo "[+] Build cache computed for $headref" + BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && echo "[+] Build cache computed for $headref" fi if [[ -f "/tmp/$headref" ]] # Make sure generating builds for current HEAD was successful From b0a455a1748a76e8c54a5722747cebedc4c6b489 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 09:25:02 +0100 Subject: [PATCH 006/106] FIX: simplify test.yml --- .github/workflows/test.yml | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 165f705bc6e..22a4685197e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,9 +31,10 @@ jobs: - name: Setup environment run: > mkdir /cache; - cd /root && - git config --global --add safe.directory /root && + git config --global --add safe.directory . && echo "DEV_BRANCH_SHA=$(git rev-parse dev)" >> $GITHUB_ENV + - name: Generate builds in reference to current commit + run: busted --lua=luajit -r generate - name: Check if build cache exists id: cache-builds uses: actions/cache@v3 @@ -45,20 +46,9 @@ jobs: - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} name: Generate builds in reference to dev branch run: > - mkdir /devRef && - cp -r /root/. /devRef/ && - cd /devRef && - git restore . && - git clean -fd && git checkout dev && - cp /root/.busted . && - rm -rf /devRef/spec/ && - cp -r /root/spec/ /devRef/spec/ && + git checkout $GITHUB_SHA -- .busted spec && BUILDCACHEPREFIX='/cache' busted --lua=luajit -r generate && - date > "/cache/${{ env.DEV_BRANCH_SHA }}" && - cd /root - - name: Generate builds in reference to current commit - run: busted --lua=luajit -r generate - name: Display differences run: > for build in /cache/*.lua; From 2c334d2113c71de1ffda9dbc7f76ae54f90c20cd Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 09:28:42 +0100 Subject: [PATCH 007/106] FIX: make sure directory is root before takign hash of dev --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 22a4685197e..376fbbd66b2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,8 @@ jobs: - name: Setup environment run: > mkdir /cache; - git config --global --add safe.directory . && + cd /root && + git config --global --add safe.directory /root && echo "DEV_BRANCH_SHA=$(git rev-parse dev)" >> $GITHUB_ENV - name: Generate builds in reference to current commit run: busted --lua=luajit -r generate From 60dca6ea8a58575e2998eb863f8a3b967c62095a Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 10:06:38 +0100 Subject: [PATCH 008/106] FIX: use dedicated cache folder in spec --- .github/workflows/test.yml | 36 ++++++++++++++++++------------------ docker-compose.yml | 3 +-- spec/Cache/README.md | 1 + spec/buildDiff.sh | 10 +++++----- 4 files changed, 25 insertions(+), 25 deletions(-) create mode 100644 spec/Cache/README.md diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 376fbbd66b2..dd2c5498d82 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,8 +11,6 @@ jobs: container: # No good way to automatically get the lowercase repo owner name here. image: ghcr.io/paliak/busted-tests - volumes: - - ${{ github.workspace }}:/root steps: - name: Checkout repository uses: actions/checkout@v4 @@ -23,17 +21,9 @@ jobs: container: # No good way to automatically get the lowercase repo owner name here. image: ghcr.io/paliak/busted-tests - volumes: - - ${{ github.workspace }}:/root steps: - - name: Checkout repository + - name: Checkout HEAD uses: actions/checkout@v4 - - name: Setup environment - run: > - mkdir /cache; - cd /root && - git config --global --add safe.directory /root && - echo "DEV_BRANCH_SHA=$(git rev-parse dev)" >> $GITHUB_ENV - name: Generate builds in reference to current commit run: busted --lua=luajit -r generate - name: Check if build cache exists @@ -42,17 +32,27 @@ jobs: env: cache-name: cached-dev-builds with: - path: /cache - key: ${{ env.DEV_BRANCH_SHA }} + path: spec/Cache + key: ${{ github.event.pull_request.base.sha }} + - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} + name: Checkout dev + uses: actions/checkout@v4 + with: + ref: 'dev' + - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} + name: Checkout new test related files in case they changed + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + sparse-checkout: | + .busted + spec - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} name: Generate builds in reference to dev branch - run: > - git checkout dev && - git checkout $GITHUB_SHA -- .busted spec && - BUILDCACHEPREFIX='/cache' busted --lua=luajit -r generate && + run: BUILDCACHEPREFIX='${{ github.workspace }}/spec/Cache' busted --lua=luajit -r generate - name: Display differences run: > - for build in /cache/*.lua; + for build in spec/Cache/*.lua; do BASENAME=$(basename "$build"); echo "[-] Diff for $BASENAME"; diff --git a/docker-compose.yml b/docker-compose.yml index 11e6c85f813..23eb2f24f58 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,5 +13,4 @@ services: container_name: busted-diff command: /bin/sh -c ./spec/buildDiff.sh volumes: - - ./:/root - - /tmp/buildcache:/cache \ No newline at end of file + - ./:/root \ No newline at end of file diff --git a/spec/Cache/README.md b/spec/Cache/README.md new file mode 100644 index 00000000000..d6a6b8de4fc --- /dev/null +++ b/spec/Cache/README.md @@ -0,0 +1 @@ +# This folder is for generated builds to be cached during build diff process. https://github.com/Paliak/PathOfBuilding/blob/dev/CONTRIBUTING.md#testing \ No newline at end of file diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 0b6e2e7c9f2..7f2f1c9bbfc 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -2,24 +2,24 @@ headref=$(git rev-parse HEAD) devref=$(git rev-parse dev) -if [[ ! -f "/cache/$devref" ]] # Output of builds outdated or nonexistent +if [[ ! -f "/root/spec/Cache/$devref" ]] # Output of builds outdated or nonexistent then git config --global --add safe.directory /root && \ mkdir /devRef && cp -r /root/. /devRef/ && cd /devRef && \ git restore . && git clean -fd && git checkout dev && \ cp /root/.busted . && rm -rf /devRef/spec/ && cp -r /root/spec/ /devRef/spec/ && \ - BUILDCACHEPREFIX='/cache' busted --lua=luajit -r generate && \ - date > "/cache/$devref" && cd /root && echo "[+] Build cache computed for $devref"; rm -rf /devRef + BUILDCACHEPREFIX='/root/spec/Cache' busted --lua=luajit -r generate && \ + date > "/root/spec/Cache/$devref" && cd /root && echo "[+] Build cache computed for $devref"; rm -rf /devRef fi -if [[ -f "/cache/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev +if [[ -f "/root/spec/Cache/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev then BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && echo "[+] Build cache computed for $headref" fi if [[ -f "/tmp/$headref" ]] # Make sure generating builds for current HEAD was successful then - for build in /cache/*.lua + for build in /root/spec/Cache/*.lua do BASENAME=$(basename "$build") echo "[-] Diff for $BASENAME" From a75b2a1bb705aa8722ecedf93a377c08acf715f3 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 10:13:11 +0100 Subject: [PATCH 009/106] FIX: use non conical sparse checkout due to a non directory path --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dd2c5498d82..ea2c88f9416 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -44,9 +44,10 @@ jobs: uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} + sparse-checkout-cone-mode: false sparse-checkout: | .busted - spec + spec/* - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} name: Generate builds in reference to dev branch run: BUILDCACHEPREFIX='${{ github.workspace }}/spec/Cache' busted --lua=luajit -r generate From 0875d6e6d1da0498da8fabb5417d35f65bfe9a1e Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 10:21:53 +0100 Subject: [PATCH 010/106] FIX: path issue when generating dev builds --- .github/workflows/test.yml | 15 ++++++--------- spec/GenerateBuilds.lua | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ea2c88f9416..dd018ef4f7e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,23 +34,20 @@ jobs: with: path: spec/Cache key: ${{ github.event.pull_request.base.sha }} + - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} + name: Save changes to tests files + run: cp -r .busted spec /tmp/ - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} name: Checkout dev uses: actions/checkout@v4 with: ref: 'dev' - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} - name: Checkout new test related files in case they changed - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - sparse-checkout-cone-mode: false - sparse-checkout: | - .busted - spec/* + name: Patch dev with latest tests files + run: rm -rf .busted spec && cp -r /tmp/.busted /tmp/spec . - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} name: Generate builds in reference to dev branch - run: BUILDCACHEPREFIX='${{ github.workspace }}/spec/Cache' busted --lua=luajit -r generate + run: BUILDCACHEPREFIX="$(realpath spec/Cache)" busted --lua=luajit -r generate - name: Display differences run: > for build in spec/Cache/*.lua; diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index 70828ab63c9..e6f1b19b0cd 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -45,7 +45,7 @@ local buildList = fetchBuilds("../spec/TestBuilds") for filename, testBuild in pairs(buildList) do - print("[+] Computing " .. filename) + print("[+] Computing " .. filename:gsub("(.+)%..+$", (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/%1.lua")) loadBuildFromXML(testBuild) local fileHnd, errMsg = io.open(filename:gsub("(.+)%..+$", (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/%1.lua"), "w+") fileHnd:write(testBuild) From 9d581fcc964687f92231cb99eea5b8feb6ddc1dc Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 12:26:26 +0100 Subject: [PATCH 011/106] FIX: remove outdate cache when using docker compose --- spec/buildDiff.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 7f2f1c9bbfc..f6711fd8589 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -4,12 +4,14 @@ devref=$(git rev-parse dev) if [[ ! -f "/root/spec/Cache/$devref" ]] # Output of builds outdated or nonexistent then + rm "/root/spec/Cache/*" git config --global --add safe.directory /root && \ mkdir /devRef && cp -r /root/. /devRef/ && cd /devRef && \ git restore . && git clean -fd && git checkout dev && \ cp /root/.busted . && rm -rf /devRef/spec/ && cp -r /root/spec/ /devRef/spec/ && \ BUILDCACHEPREFIX='/root/spec/Cache' busted --lua=luajit -r generate && \ - date > "/root/spec/Cache/$devref" && cd /root && echo "[+] Build cache computed for $devref"; rm -rf /devRef + date > "/root/spec/Cache/$devref" && cd /root && echo "[+] Build cache computed for $devref" + rm -rf /devRef fi if [[ -f "/root/spec/Cache/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev From 3ea5a77a11c80adaab03e51f2f3a50d38c46e61a Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 12:37:28 +0100 Subject: [PATCH 012/106] TEST: test tests --- spec/System/TestSkills_spec.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/System/TestSkills_spec.lua b/spec/System/TestSkills_spec.lua index 5c384712dd1..04b10adb16a 100644 --- a/spec/System/TestSkills_spec.lua +++ b/spec/System/TestSkills_spec.lua @@ -53,4 +53,8 @@ describe("TestAttacks", function() assert.True(build.calcsTab.mainOutput.SkillTriggerRate == build.calcsTab.mainOutput.Speed) end) + + it("Test Tests", function() + assert.True(false) + end) end) \ No newline at end of file From 8883655878fea71d0ba6d8b2889428f5a3c0311f Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 12:46:17 +0100 Subject: [PATCH 013/106] Revert "TEST: test tests" This reverts commit 3ea5a77a11c80adaab03e51f2f3a50d38c46e61a. --- spec/System/TestSkills_spec.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/System/TestSkills_spec.lua b/spec/System/TestSkills_spec.lua index 04b10adb16a..5c384712dd1 100644 --- a/spec/System/TestSkills_spec.lua +++ b/spec/System/TestSkills_spec.lua @@ -53,8 +53,4 @@ describe("TestAttacks", function() assert.True(build.calcsTab.mainOutput.SkillTriggerRate == build.calcsTab.mainOutput.Speed) end) - - it("Test Tests", function() - assert.True(false) - end) end) \ No newline at end of file From 3304edd11d956b9f301e5c2800ec9ca46b382e7c Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 25 Dec 2023 13:53:34 +0100 Subject: [PATCH 014/106] FIX: issues with docker-compose --- docker-compose.yml | 2 +- spec/buildDiff.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 23eb2f24f58..63a67fc3e71 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,6 @@ services: #build: . image: ghcr.io/paliak/busted-tests container_name: busted-diff - command: /bin/sh -c ./spec/buildDiff.sh + command: command: /bin/sh -c 'chmod 777 ./spec/buildDiff.sh && ./spec/buildDiff.sh' volumes: - ./:/root \ No newline at end of file diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index f6711fd8589..3eb31e9da4a 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -1,11 +1,12 @@ #!/bin/sh +git config --system --add safe.directory /root headref=$(git rev-parse HEAD) devref=$(git rev-parse dev) if [[ ! -f "/root/spec/Cache/$devref" ]] # Output of builds outdated or nonexistent then rm "/root/spec/Cache/*" - git config --global --add safe.directory /root && \ + rm -rf /devRef mkdir /devRef && cp -r /root/. /devRef/ && cd /devRef && \ git restore . && git clean -fd && git checkout dev && \ cp /root/.busted . && rm -rf /devRef/spec/ && cp -r /root/spec/ /devRef/spec/ && \ From 9f7e0e83264d0d8e457f8bcb6a85f04f11dbc058 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 26 Dec 2023 22:13:59 +0100 Subject: [PATCH 015/106] FIX: typo in docker-compose --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 63a67fc3e71..e16260c20f6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,6 @@ services: #build: . image: ghcr.io/paliak/busted-tests container_name: busted-diff - command: command: /bin/sh -c 'chmod 777 ./spec/buildDiff.sh && ./spec/buildDiff.sh' + command: /bin/sh -c 'chmod 777 ./spec/buildDiff.sh && ./spec/buildDiff.sh' volumes: - ./:/root \ No newline at end of file From f48955b27989480e02c87f6036cfd84d2a956d44 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 26 Dec 2023 22:28:03 +0100 Subject: [PATCH 016/106] FIX: pull out path generation into a variable --- spec/GenerateBuilds.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index e6f1b19b0cd..b23d0e8618c 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -45,9 +45,10 @@ local buildList = fetchBuilds("../spec/TestBuilds") for filename, testBuild in pairs(buildList) do - print("[+] Computing " .. filename:gsub("(.+)%..+$", (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/%1.lua")) + local filepath = filename:gsub("(.+)%..+$", (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/%1.lua") + print("[+] Computing " .. filepath) loadBuildFromXML(testBuild) - local fileHnd, errMsg = io.open(filename:gsub("(.+)%..+$", (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/%1.lua"), "w+") + local fileHnd, errMsg = io.open(filepath, "w+") fileHnd:write(testBuild) fileHnd:write(buildTable("output", build.calcsTab.mainOutput) .. "\n}") fileHnd:close() From 0bccf5d4a545bb763d77af45d1460c775809c573 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Thu, 28 Dec 2023 17:34:10 +0100 Subject: [PATCH 017/106] FIX: make the build cache back into valid lua file --- spec/GenerateBuilds.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index b23d0e8618c..06c62c29376 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -45,11 +45,13 @@ local buildList = fetchBuilds("../spec/TestBuilds") for filename, testBuild in pairs(buildList) do - local filepath = filename:gsub("(.+)%..+$", (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/%1.lua") + local filepath = filename:gsub("(.+)%..+$", (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/%1.lua") print("[+] Computing " .. filepath) loadBuildFromXML(testBuild) local fileHnd, errMsg = io.open(filepath, "w+") + fileHnd:write("return {\n xml = [[") fileHnd:write(testBuild) + fileHnd:write("]],\n") fileHnd:write(buildTable("output", build.calcsTab.mainOutput) .. "\n}") fileHnd:close() end \ No newline at end of file From bfc38879afbe6536f762267a21cbf6a03fecde77 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 29 Dec 2023 20:12:11 +0100 Subject: [PATCH 018/106] FIX: github actions uses sh -e which uses the diff exit code. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dd018ef4f7e..269a05fd9c4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,6 +54,6 @@ jobs: do BASENAME=$(basename "$build"); echo "[-] Diff for $BASENAME"; - diff "$build" "/tmp/$BASENAME"; + diff "$build" "/tmp/$BASENAME" || true; echo "[+] Diff for $BASENAME"; done From 11515974df4742c5af9d6eef0e1ab73f55c685ad Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 1 Jan 2024 10:04:31 +0100 Subject: [PATCH 019/106] FIX: manually trigger gc to stave off out of memory crash. Misc fixes. --- Dockerfile | 1 + docker-compose.yml | 1 + spec/GenerateBuilds.lua | 18 +++++++++++++++--- spec/buildDiff.sh | 3 ++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index ebea48b0260..4443cabdc37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,5 +26,6 @@ RUN --mount=type=cache,from=luajit,source=/opt,target=/opt make -C /opt/LuaJIT/ RUN ln -sf /usr/local/bin/luajit-2.1.0-beta3 /usr/local/bin/luajit RUN --mount=type=cache,from=emmyluadebugger,source=/opt,target=/opt make -C /opt/EmmyLuaDebugger/build/ install +ENV HISTFILE=/dev/null WORKDIR /root CMD busted --lua=luajit \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index e16260c20f6..986b038e710 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,7 @@ services: #build: . image: ghcr.io/paliak/busted-tests container_name: busted-diff + tty: true command: /bin/sh -c 'chmod 777 ./spec/buildDiff.sh && ./spec/buildDiff.sh' volumes: - ./:/root \ No newline at end of file diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index 06c62c29376..40a9577e65a 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -42,16 +42,28 @@ function buildTable(tableName, values, string) end local buildList = fetchBuilds("../spec/TestBuilds") - +local currentBuild = 0 +local buildCount = 0 +for _, _ in pairs(buildList) do + buildCount = buildCount + 1 +end for filename, testBuild in pairs(buildList) do local filepath = filename:gsub("(.+)%..+$", (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/%1.lua") - print("[+] Computing " .. filepath) + print(string.format("[+] %d/%d Computing %s", currentBuild, buildCount, filepath)) + currentBuild = currentBuild + 1 loadBuildFromXML(testBuild) + local fileHnd, errMsg = io.open(filepath, "w+") fileHnd:write("return {\n xml = [[") - fileHnd:write(testBuild) + fileHnd:write(build:SaveDB("Cache")) fileHnd:write("]],\n") fileHnd:write(buildTable("output", build.calcsTab.mainOutput) .. "\n}") fileHnd:close() + if (currentBuild % 10 == 0) then -- Duct tape fix for memory usage + local before = collectgarbage("count") + LoadModule("Data/ModCache", modLib.parseModCache) + collectgarbage("collect") + ConPrintf("%dkB => %dkB", before, collectgarbage("count")) + end end \ No newline at end of file diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 3eb31e9da4a..16e8d4d2dcc 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -5,7 +5,7 @@ devref=$(git rev-parse dev) if [[ ! -f "/root/spec/Cache/$devref" ]] # Output of builds outdated or nonexistent then - rm "/root/spec/Cache/*" + rm /root/spec/Cache/* rm -rf /devRef mkdir /devRef && cp -r /root/. /devRef/ && cd /devRef && \ git restore . && git clean -fd && git checkout dev && \ @@ -17,6 +17,7 @@ fi if [[ -f "/root/spec/Cache/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev then + rm /tmp/* BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && echo "[+] Build cache computed for $headref" fi From 4640e8132e22b3a82df52eb1467086aea8ae7270 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 1 Jan 2024 10:07:09 +0100 Subject: [PATCH 020/106] FIX: remove outdated comment --- src/HeadlessWrapper.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/HeadlessWrapper.lua b/src/HeadlessWrapper.lua index 4bee744be12..c6f9502826c 100644 --- a/src/HeadlessWrapper.lua +++ b/src/HeadlessWrapper.lua @@ -166,8 +166,6 @@ end dofile("Launch.lua") --- Prevents loading of ModCache --- Allows running mod parsing related tests without pushing ModCache -- The CI env var will be true when run from github workflows but should be false for other tools using the headless wrapper mainObject.continuousIntegrationMode = os.getenv("CI") From d472b1e2b00fc2e5e2531aefabe29163534c520e Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 5 Jan 2024 04:47:27 +0100 Subject: [PATCH 021/106] FEAT: add needed pkgs to Dockerfile --- Dockerfile | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4443cabdc37..aabd4f1b065 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM alpine:3.18 as base -RUN apk add --no-cache wget unzip openssl build-base readline-dev cmake readline-dev git ca-certificates tar +RUN apk add --no-cache curl unzip openssl build-base readline-dev cmake readline-dev git ca-certificates libcurl curl-dev zlib parallel tar FROM base as buildbase WORKDIR /opt @@ -21,11 +21,13 @@ RUN cd EmmyLuaDebugger && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Re FROM base RUN --mount=type=cache,from=buildBase,source=/opt,target=/opt make -C /opt/lua-5.1.5/ install RUN --mount=type=cache,from=luarocks,source=/opt,target=/opt make -C /opt/luarocks-3.7.0/ install -RUN luarocks install busted && luarocks install cluacov -RUN --mount=type=cache,from=luajit,source=/opt,target=/opt make -C /opt/LuaJIT/ install -RUN ln -sf /usr/local/bin/luajit-2.1.0-beta3 /usr/local/bin/luajit -RUN --mount=type=cache,from=emmyluadebugger,source=/opt,target=/opt make -C /opt/EmmyLuaDebugger/build/ install -ENV HISTFILE=/dev/null -WORKDIR /root -CMD busted --lua=luajit \ No newline at end of file +#Install here to install pkgs in pararell with compilation of emmylua and luajit +RUN luarocks install busted +RUN luarocks install cluacov +RUN luarocks install Lua-cURL +RUN luarocks install lua-zlib +RUN luarocks install luaposix + +RUN --mount=type=cache,from=luajit,source=/opt,target=/opt make -C /opt/LuaJIT/ install && ln -sf /usr/local/bin/luajit-2.1.0-beta3 /usr/local/bin/luajit +RUN --mount=type=cache,from=emmyluadebugger,source=/opt,target=/opt make -C /opt/EmmyLuaDebugger/build/ install \ No newline at end of file From 203f9b8ec1f5f28b255c5c96bd813e005d5c5858 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 5 Jan 2024 04:50:14 +0100 Subject: [PATCH 022/106] FIX: minor hardening of test runner containers --- docker-compose.yml | 27 ++++++++++++++++++++------- spec/Cache/README.md | 1 - 2 files changed, 20 insertions(+), 8 deletions(-) delete mode 100644 spec/Cache/README.md diff --git a/docker-compose.yml b/docker-compose.yml index 986b038e710..9499d20fd96 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,30 @@ services: busted-tests: - #build: . - image: ghcr.io/paliak/busted-tests + build: . + #image: ghcr.io/paliak/busted-tests container_name: busted-tests + command: busted --lua=luajit + security_opt: + - no-new-privileges:true ports: - "9966:9966" + working_dir: /workdir volumes: - - ./:/root + - ./:/workdir:ro busted-diff: - #build: . - image: ghcr.io/paliak/busted-tests + build: . + #image: ghcr.io/paliak/busted-tests + environment: + WORKDIR: /workdir + CACHEDIR: /cache container_name: busted-diff tty: true - command: /bin/sh -c 'chmod 777 ./spec/buildDiff.sh && ./spec/buildDiff.sh' + command: /bin/sh /workdir/spec/buildDiff.sh + security_opt: + - no-new-privileges:true + working_dir: /workdir volumes: - - ./:/root \ No newline at end of file + - ./:/workdir:ro + - busted-diff-cache:/cache +volumes: + busted-diff-cache: \ No newline at end of file diff --git a/spec/Cache/README.md b/spec/Cache/README.md deleted file mode 100644 index d6a6b8de4fc..00000000000 --- a/spec/Cache/README.md +++ /dev/null @@ -1 +0,0 @@ -# This folder is for generated builds to be cached during build diff process. https://github.com/Paliak/PathOfBuilding/blob/dev/CONTRIBUTING.md#testing \ No newline at end of file From 1ff1d084b7bf844c1f18383a94f5118596f2ee01 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 5 Jan 2024 05:30:46 +0100 Subject: [PATCH 023/106] FEAT: more verbose diff. Fixes to timeless data. Impl import from link. --- spec/GenerateBuilds.lua | 105 +- spec/System/TestBuilds_spec.lua | 35 - spec/TestBuilds/.gitignore | 1 - spec/TestBuilds/3.13/Dual Savior.lua | 1119 ----------- .../3.13/Dual Wield Cospris CoC.lua | 1645 ---------------- .../3.13/Generals Perforate Zerker.lua | 1611 ---------------- .../3.13/Mirage Archer Toxic Rain.lua | 1717 ----------------- spec/TestBuilds/3.13/OccVortex.lua | 1064 ---------- spec/TestBuilds/{3.13 => }/Dual Savior.xml | 0 .../{3.13 => }/Dual Wield Cospris CoC.xml | 0 .../{3.13 => }/Generals Perforate Zerker.xml | 0 .../{3.13 => }/Mirage Archer Toxic Rain.xml | 0 spec/TestBuilds/{3.13 => }/OccVortex.xml | 0 spec/buildDiff.sh | 32 +- spec/buildOutputDiff.lua | 22 + spec/builds.txt | 9 + src/HeadlessWrapper.lua | 102 +- 17 files changed, 193 insertions(+), 7269 deletions(-) delete mode 100644 spec/System/TestBuilds_spec.lua delete mode 100644 spec/TestBuilds/.gitignore delete mode 100644 spec/TestBuilds/3.13/Dual Savior.lua delete mode 100644 spec/TestBuilds/3.13/Dual Wield Cospris CoC.lua delete mode 100644 spec/TestBuilds/3.13/Generals Perforate Zerker.lua delete mode 100644 spec/TestBuilds/3.13/Mirage Archer Toxic Rain.lua delete mode 100644 spec/TestBuilds/3.13/OccVortex.lua rename spec/TestBuilds/{3.13 => }/Dual Savior.xml (100%) rename spec/TestBuilds/{3.13 => }/Dual Wield Cospris CoC.xml (100%) rename spec/TestBuilds/{3.13 => }/Generals Perforate Zerker.xml (100%) rename spec/TestBuilds/{3.13 => }/Mirage Archer Toxic Rain.xml (100%) rename spec/TestBuilds/{3.13 => }/OccVortex.xml (100%) create mode 100644 spec/buildOutputDiff.lua create mode 100644 spec/builds.txt diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index 40a9577e65a..c35739a0868 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -1,27 +1,57 @@ -local function fetchBuilds(path, buildList) - buildList = buildList or {} - for file in lfs.dir(path) do - if file ~= "." and file ~= ".." then - local f = path..'/'..file - local attr = lfs.attributes (f) - assert(type(attr) == "table") - if attr.mode == "directory" then - fetchBuilds(f, buildList) - else - if file:match("^.+(%..+)$") == ".xml" then - local fileHnd, errMsg = io.open(f, "r") - if not fileHnd then - return nil, errMsg - end - local fileText = fileHnd:read("*a") - fileHnd:close() - buildList[file] = fileText +local function fetchBuilds(path) + local co = coroutine.create(function(path) + if os.getenv("BUILDLINKS") then + local fileHnd, errMsg = io.open(os.getenv("BUILDLINKS"), "r") + if not fileHnd then + error(errMsg) + end + local fileText = fileHnd:read("*a") + for line in magiclines( fileText ) do + if line ~= "" then + for j=1,#buildSites.websiteList do + if line:match(buildSites.websiteList[j].matchURL) then + -- TODO: cache the downloaded xmls + buildSites.DownloadBuild(line, buildSites.websiteList[j], function(isSuccess, data) + if isSuccess then + coroutine.yield({xml = Inflate(common.base64.decode(data:gsub("-","+"):gsub("_","/"))), filename = line}) + else + print("Failed to download build: " .. line) + end + end) + break + end + end + end + end + else + for file in lfs.dir(path) do + if file ~= "." and file ~= ".." then + local f = path..'/'..file + local attr = lfs.attributes (f) + assert(type(attr) == "table") + if attr.mode ~= "directory" and file:match("^.+(%..+)$") == ".xml" then + local fileHnd, errMsg = io.open(f, "r") + if not fileHnd then + error(errMsg) + end + local fileText = fileHnd:read("*a") + fileHnd:close() + coroutine.yield({xml = fileText, filename = file}) + end end end end + end) + + return function() + local ok, result = coroutine.resume(co, path) + if not ok then + error(result) + end + return result end - return buildList -end + end + function buildTable(tableName, values, string) string = string or "" @@ -41,29 +71,16 @@ function buildTable(tableName, values, string) return string end -local buildList = fetchBuilds("../spec/TestBuilds") -local currentBuild = 0 -local buildCount = 0 -for _, _ in pairs(buildList) do - buildCount = buildCount + 1 -end +for testBuild in fetchBuilds("../spec/TestBuilds") do + local filename = testBuild.filename:gsub('%W','') + local filepath = (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/" .. filename + print("[+] Computing ".. filepath) + loadBuildFromXML(testBuild.xml) + local buildHnd = io.open(filepath .. ".build", "w+") + buildHnd:write(build:SaveDB("Cache")) + buildHnd:close() -for filename, testBuild in pairs(buildList) do - local filepath = filename:gsub("(.+)%..+$", (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/%1.lua") - print(string.format("[+] %d/%d Computing %s", currentBuild, buildCount, filepath)) - currentBuild = currentBuild + 1 - loadBuildFromXML(testBuild) - - local fileHnd, errMsg = io.open(filepath, "w+") - fileHnd:write("return {\n xml = [[") - fileHnd:write(build:SaveDB("Cache")) - fileHnd:write("]],\n") - fileHnd:write(buildTable("output", build.calcsTab.mainOutput) .. "\n}") - fileHnd:close() - if (currentBuild % 10 == 0) then -- Duct tape fix for memory usage - local before = collectgarbage("count") - LoadModule("Data/ModCache", modLib.parseModCache) - collectgarbage("collect") - ConPrintf("%dkB => %dkB", before, collectgarbage("count")) - end + local outputHnd = io.open(filepath .. ".lua", "w+") + outputHnd:write("return {\n " .. buildTable("output", build.calcsTab.mainOutput) .. "\n}") + outputHnd:close() end \ No newline at end of file diff --git a/spec/System/TestBuilds_spec.lua b/spec/System/TestBuilds_spec.lua deleted file mode 100644 index f59b2398c42..00000000000 --- a/spec/System/TestBuilds_spec.lua +++ /dev/null @@ -1,35 +0,0 @@ -local function fetchBuilds(path, buildList) - buildList = buildList or {} - for file in lfs.dir(path) do - if file ~= "." and file ~= ".." then - local f = path..'/'..file - local attr = lfs.attributes (f) - assert(type(attr) == "table") - if attr.mode == "directory" then - fetchBuilds(f, buildList) - elseif file:match("^.+(%..+)$") == ".lua" then - buildList[file] = LoadModule(f) - end - end - end - return buildList -end - -expose("test all builds #builds", function() - local buildList = fetchBuilds("../spec/TestBuilds") - for buildName, testBuild in pairs(buildList) do - loadBuildFromXML(testBuild.xml, buildName) - testBuild.result = {} - for key, value in pairs(testBuild.output) do - -- Have to assign it to a temporary table here, as the tests will run later, when the 'build' isn't changing - testBuild.result[key] = build.calcsTab.mainOutput[key] - it("on build: " .. buildName .. ", key: " .. key, function() - if type(value) == "number" and type(testBuild.result[key]) == "number" then - assert.are.same(round(value, 4), round(testBuild.result[key] or 0, 4)) - else - assert.are.same(value, testBuild.result[key]) - end - end) - end - end -end) diff --git a/spec/TestBuilds/.gitignore b/spec/TestBuilds/.gitignore deleted file mode 100644 index 87c309b759a..00000000000 --- a/spec/TestBuilds/.gitignore +++ /dev/null @@ -1 +0,0 @@ -# This file is to keep an empty TestBuilds folder around when the CI process uses it to find test builds if there aren't any to find \ No newline at end of file diff --git a/spec/TestBuilds/3.13/Dual Savior.lua b/spec/TestBuilds/3.13/Dual Savior.lua deleted file mode 100644 index db83e887942..00000000000 --- a/spec/TestBuilds/3.13/Dual Savior.lua +++ /dev/null @@ -1,1119 +0,0 @@ -return { - xml = [[ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - 8% increased maximum Life - Regenerate 1% of Life per second - - - 3% increased maximum Life - - - Gain 1 Endurance Charge every second if you've been Hit Recently - - - 24% increased Evasion Rating and Armour - 8% increased maximum Life - 10% chance to Intimidate Enemies for 4 seconds on Hit - - - 2% increased Cast Speed - - - 4% increased maximum Mana - - - 4% increased Skill Effect Duration - - - +1% to maximum Fire Resistance - +20% to Fire Resistance - - - 3% increased maximum Energy Shield - - - +10% to Cold Resistance - - - 5% increased Area of Effect - - - 2% increased maximum Life - - - Minions deal 80% increased Damage - - - 15% increased effect of Non-Curse Auras from your Skills - - - 12% increased Fire Damage - - - 1% Chance to Block Spell Damage - - - 5% increased maximum Energy Shield - - - 10% increased maximum Life - Regenerate 1.1% of Life per second - - - +11% to Fire Resistance - - - 3% increased effect of Non-Curse Auras from your Skills - - - 3% increased Effect of your Curses - - - 9% increased Evasion Rating - - - 5% increased Skill Effect Duration - - - 10% increased Area Damage - - - 12% increased Mana Regeneration Rate - - - 10% increased Attack Damage - - - +8% to Chaos Resistance - - - +9% to Critical Strike Multiplier - - - 2% chance to deal Double Damage - 25% increased Physical Damage - - - 3% increased maximum Life - - - 3% increased Movement Speed - - - 3% increased Cast Speed - 11% increased Projectile Damage - 5% chance to Shock - 6% chance to Ignite - - - 12% increased Spell Damage - - - 1% chance to Dodge Attack Hits - - - 7% increased Projectile Speed - - - 3% increased Attack Speed - - - 5% increased Effect of your Curses - - - 7% increased Physical Damage - - - 7% increased Armour - - - +12% to Lightning Resistance - - - 2% increased maximum Life - - - 10% increased Fire Damage - - - 11% increased Area Damage - - - +10% to Fire Resistance - - - 7% increased Area Damage - - - 7% increased Fire Damage - 6% increased maximum Mana - +11% to Lightning Resistance - - - +8% to Critical Strike Multiplier - - - 10% increased Critical Strike Chance - - - 3% increased maximum Life - - - 7% increased Spell Damage - - - 20% increased Area of Effect of Aura Skills - 15% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - +9% to Critical Strike Multiplier - - - 1% chance to Dodge Spell Hits - - - +10% to Fire Resistance - - - +8% to Critical Strike Multiplier - - - 8% increased Armour - - - 5% increased maximum Energy Shield - - - 3% increased maximum Life - - - 28% increased Cold Damage - 10% of Physical Damage Converted to Cold Damage - - - 7% increased maximum Life - 0.4% of Attack Damage Leeched as Life - - - 12% increased Area Damage - - - 7% increased Spell Damage - - - +8% to Critical Strike Multiplier - - - +14% to Fire Resistance - - - 8% increased Chaos Damage - - - 12% increased Physical Damage - - - 10% increased Lightning Damage - - - 3% increased maximum Life - - - 5% increased Area of Effect - - - 6% increased Area of Effect - - - 10% chance to gain a Frenzy Charge on Hit - - - 8% increased maximum Life - Regenerate 0.7% of Life per second - - - 9% increased Evasion Rating - - - +13% to Fire Resistance - - - +11% to Fire Resistance - - - 11% increased Fire Damage - - - 10% increased Projectile Speed - - - 7% increased Projectile Damage - - - 20% increased Area of Effect of Aura Skills - 15% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - 3% increased Movement Speed - - - Minions deal 12% increased Damage - - - 2% increased maximum Life - - - +13% to Lightning Resistance - - - +6% to Chaos Resistance - - - +12% to Lightning Resistance - - - +12% to Fire Resistance - - - +12% to Cold Resistance - - - 10% increased Damage over Time - - - 10% increased Chaos Damage - - - 30% increased Chaos Damage - 25% chance to inflict Withered for 2 seconds on Hit - - - 27% increased Spell Damage - 43% increased Critical Strike Chance for Spells - - - +9% to Critical Strike Multiplier - - - 3% increased effect of Non-Curse Auras from your Skills - - - 12% increased Chaos Damage - - - 3% increased Movement Speed - - - 3% increased Movement Speed - - - 1% Chance to Block Spell Damage - - - 7% increased Spell Damage - - - 33% increased Fire Damage - Damage Penetrates 2% Fire Resistance - - - 9% increased Chaos Damage - - - 9% increased Fire Damage - - - 4% chance to Freeze - - - 1% Chance to Block Spell Damage - - - +9% to Critical Strike Multiplier - - - 5% increased maximum Energy Shield - - - 1% chance to Dodge Spell Hits - - - +7% to Chaos Resistance - - - 2% increased maximum Life - - - +1% to maximum Chaos Resistance - +17% to Chaos Resistance - - - 2% increased maximum Life - - - +8% to Chaos Resistance - - - 34% increased Fire Damage - Damage Penetrates 3% Fire Resistance - - - +12% to Fire Resistance - - - +12% to Cold Resistance - - - 8% increased Attack Damage - - - 4% increased maximum Life - - - 4% increased maximum Mana - - - 12% increased Chaos Damage - - - 12% increased Evasion Rating - - - - https://www.pathofexile.com/passive-skill-tree/AAAABAECAHZ_hMR-4J5X5FF7jA== - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Rarity: UNIQUE -The Saviour -Legion Sword -Quality: 20 -Sockets: R-R-R -LevelReq: 62 -Implicits: 1 -40% increased Global Accuracy Rating -Triggers Level 20 Reflection when Equipped -{range:0.5}(40-50)% increased Physical Damage -{range:0.5}Adds (16-22) to (40-45) Physical Damage -{range:0.5}(8-12)% increased Attack Speed -{range:0.5}(8-12)% increased Critical Strike Chance - - - - - - - Rarity: UNIQUE -Actum -Butcher Axe -League: Heist -Quality: 20 -LevelReq: 63 -Implicits: 0 -Has no Sockets -{range:0.5}(200-250)% increased Physical Damage -You have no Intelligence -{range:0.5}Critical Strike Chance is (20-30)% for Hits with this Weapon - - - - Rarity: UNIQUE -The Saviour -Legion Sword -Quality: 20 -Sockets: R-R-R -LevelReq: 62 -Implicits: 1 -40% increased Global Accuracy Rating -Triggers Level 20 Reflection when Equipped -{range:1}(40-50)% increased Physical Damage -{range:0.5}Adds (16-22) to (40-45) Physical Damage -{range:0.5}(8-12)% increased Attack Speed -{range:0.5}(8-12)% increased Critical Strike Chance - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]], - output = {["SpellSuppressionChanceOverCap"] = 0, -["FrenzyChargesMin"] = 0, -["RageCost"] = 0, -["HitChance"] = 100, -["LightningDotEHP"] = 57.5, -["BrittleDurationMod"] = 0, -["CrabBarriersMax"] = 0, -["SiphoningChargesMax"] = 0, -["AvoidColdDamageChance"] = 0, -["AnyTakenReflect"] = 0, -["InspirationCharges"] = 5, -["AbsorptionChargesMax"] = 0, -["LifePercentCost"] = 0, -["ReqInt"] = 0, -["ProjectileNotHitChance"] = 0, -["LifeCost"] = 0, -["ManaPercentCost"] = 0, -["MaxManaLeechRate"] = 9.4, -["PhysicalTakenReflectMult"] = 1, -["LightningLightningBaseTakenHitMult"] = 1.6, -["SelfShockDuration"] = 100, -["ManaOnHit"] = 0, -["AfflictionChargesMax"] = 0, -["PhysicalProjectileDamageChance"] = 15, -["ManaCost"] = 0, -["SpellSuppressionEffect"] = 50, -["BloodChargesMax"] = 5, -["FireMeleeDamageChance"] = 15, -["PhysicalGuardEffectiveLife"] = 92, -["ActiveTrapLimit"] = 15, -["PhysicalAegis"] = 0, -["EnergyShieldRegen"] = 0, -["LightningAegis"] = 0, -["SiphoningCharges"] = 0, -["PhysicalTakenHitMult"] = 1, -["ChaosDotEHP"] = 57.5, -["Gear:Ward"] = 0, -["LightningGuardAbsorbRate"] = 0, -["MissingLightningResist"] = 135, -["MaxManaLeechInstance"] = 4.7, -["LightningGuardEffectivePool"] = 0, -["BleedDuration"] = 5, -["MaxEnergyShieldLeechRate"] = 0, -["EnergyShieldLeechInstanceRate"] = 0, -["PhysicalNumberOfHits"] = 14.0541, -["ChaosTakenHit"] = 1, -["FireFireBaseTakenHitMult"] = 1.6, -["CurrentShock"] = 0, -["PhysicalResist"] = 0, -["ColdSpellProjectileDamageChance"] = 0, -["FireResistOver75"] = 0, -["ShockEffectMod"] = 0, -["ColdResist"] = -60, -["SpellProjectileBlockChance"] = 0, -["ColdTakenReflectMult"] = 1.6, -["Dex"] = 14, -["TheoreticalOffensiveWarcryEffect"] = 1, -["PowerChargesMax"] = 3, -["SelfBleedDuration"] = 100, -["PhysicalDamageReduction"] = 0, -["SelfChillEffect"] = 100, -["Str"] = 52, -["SpellDodgeChanceOverCap"] = 0, -["FireProjectileDamageChance"] = 15, -["LightningSpellProjectileDamageChance"] = 0, -["AttackDodgeChanceOverCap"] = 0, -["AnyGuard"] = false, -["PhysicalTakenReflect"] = 1, -["MaximumScorch"] = 50, -["ShieldBlockChance"] = 0, -["EnergyShieldLeechGainRate"] = 0, -["SpellBlockChance"] = 0, -["PhysicalMindOverMatter"] = 0, -["LightningManaEffectiveLife"] = 92, -["ManaLeechInstances"] = 0, -["LightningResistOver75"] = 0, -["ColdTakenReflect"] = 1, -["SpellBlockChanceMax"] = 75, -["ChaosEnergyShieldBypass"] = 100, -["ManaOnHitRate"] = 0, -["DamageTakenOnBlock"] = 0, -["SapChance"] = 0, -["EnergyShieldRechargeDelay"] = 2, -["BlockChanceOverCap"] = 0, -["ChallengerCharges"] = 0, -["Int"] = 14, -["ColdEnergyShieldBypass"] = 0, -["FireResistTotal"] = -60, -["FreezeAvoidChance"] = 0, -["ChaosTakenHitMult"] = 1.6, -["AttackDodgeChance"] = 0, -["ReqDex"] = 155, -["ColdTakenHit"] = 1, -["LightningProjectileDamageChance"] = 15, -["BrittleEffectMod"] = 0, -["BrutalChargesMin"] = 0, -["ChaosMindOverMatter"] = 0, -["BleedChance"] = 25, -["Armour"] = 0, -["PoisonAvoidChance"] = 0, -["LightningResistTotal"] = -60, -["InterruptStunAvoidChance"] = 0, -["AverageDamage"] = 257.6858, -["ColdTakenHitMult"] = 1.6, -["PowerCharges"] = 0, -["Devotion"] = 0, -["MissingColdResist"] = 135, -["ChaosGuardAbsorbRate"] = 0, -["PhysicalTakenHit"] = 1, -["WeaponRange"] = 15, -["ColdGuardAbsorbRate"] = 0, -["LifeUnreserved"] = 92, -["FireResist"] = -60, -["RemovableFrenzyCharges"] = 0, -["ChaosAegis"] = 0, -["ScorchChance"] = 0, -["Spec:EvasionInc"] = 0, -["SapEffectMod"] = 0, -["PhysicalTotalPool"] = 92, -["Spec:ArmourInc"] = 0, -["BlockDuration"] = 0.35, -["ManaLeechPerHit"] = 0, -["Spec:ManaInc"] = 0, -["MissingChaosResist"] = 135, -["Spec:LifeInc"] = 0, -["ExtraPoints"] = 2, -["FireTakenHit"] = 1, -["FullDPS"] = 0, -["BleedAvoidChance"] = 0, -["AverageNotHitChance"] = 0, -["TotalDot"] = 0, -["EnergyShieldOnBlock"] = 0, -["TotalDotDPS"] = 89.7264, -["StunAvoidChance"] = 0, -["PreEffectiveCritChance"] = 5.5, -["DamageReductionMax"] = 90, -["Life"] = 92, -["DurationMod"] = 1, -["WithIgniteDPS"] = 659.8818, -["EnduranceCharges"] = 0, -["WithPoisonDPS"] = 659.8818, -["CombinedAvg"] = 659.8818, -["ColdTakenDotMult"] = 1.6, -["ChaosAverageDamageChance"] = 7.5, -["CombinedDPS"] = 749.6082, -["ChaosMaximumHitTaken"] = 57.5, -["ChillEffectMod"] = 0, -["PhysicalTotalEHP"] = 105.1946, -["ESCost"] = 0, -["ColdMindOverMatter"] = 0, -["PhysicalGuardEffectivePool"] = 0, -["ImpaleStoredDamage"] = 0, -["MaximumShock"] = 50, -["ImpaleChance"] = 0, -["EnergyShieldLeechInstant"] = 0, -["SpellProjectileNotHitChance"] = 0, -["LifeRegenPercent"] = 0, -["LightningResist"] = -60, -["PhysicalSpellProjectileDamageChance"] = 0, -["LifeLeechGainRate"] = 0, -["SpellNotHitChance"] = 0, -["LightningMeleeDamageChance"] = 15, -["PhysicalMaximumHitTaken"] = 92, -["ExertedAttackUptimeRatio"] = 0, -["ManaUnreservedPercent"] = 100, -["ProjectileEvadeChance"] = 0, -["AbsorptionCharges"] = 0, -["ScorchEffectMod"] = 0, -["PhysicalDotEHP"] = 92, -["ScorchDurationMod"] = 0, -["MaxEnergyShieldLeechInstance"] = 0, -["Spec:EnergyShieldInc"] = 0, -["PhysicalSpellDamageChance"] = 0, -["EnergyShieldLeechInstances"] = 0, -["AvoidPhysicalDamageChance"] = 0, -["FreezeDurationMod"] = 0, -["FreezeChance"] = 5.5, -["CullMultiplier"] = 1, -["BleedDamage"] = 454.9256, -["ChaosResistTotal"] = -60, -["CrabBarriers"] = 0, -["LightningResistOverCap"] = 0, -["EnergyShieldOnSpellBlock"] = 0, -["ShockChance"] = 5.5, -["SelfIgniteDuration"] = 100, -["TotalDotInstance"] = 0, -["ManaReservedPercent"] = 0, -["IgniteChance"] = 5.5, -["LightningTakenReflectMult"] = 1.6, -["AvoidChaosDamageChance"] = 0, -["ColdResistOver75"] = 0, -["AnyAegis"] = false, -["TotalPoisonDPS"] = 0, -["PoisonChance"] = 0, -["BleedDPS"] = 89.7264, -["LowestOfMaximumLifeAndMaximumMana"] = 47, -["ColdDotEHP"] = 57.5, -["CritIgniteDotMulti"] = 1.5, -["SelfPoisonDuration"] = 100, -["EnergyShieldLeechInstantRate"] = 0, -["BleedEffMult"] = 1, -["BrutalCharges"] = 0, -["BleedStacks"] = 1, -["BleedStacksMax"] = 1, -["FireSpellDamageChance"] = 0, -["BleedDotMulti"] = 1, -["InspirationChargesMax"] = 5, -["ChaosResist"] = -60, -["ManaLeechGainRate"] = 0, -["ManaLeechRate"] = 0, -["ManaLeechInstanceRate"] = 0.94, -["ManaUnreserved"] = 47, -["EnergyShield"] = 0, -["EnergyShieldLeechPerHit"] = 0, -["EnergyShieldLeechRate"] = 0, -["LifeLeechPerHit"] = 0, -["LifeLeechRate"] = 0, -["FireGuardEffectivePool"] = 0, -["WardRechargeDelay"] = 5, -["FireTakenReflectMult"] = 1.6, -["MaxLifeLeechInstance"] = 9.2, -["SpellSuppressionEffectiveChance"] = 0, -["EnduranceChargesMin"] = 0, -["EnergyShieldOnHitRate"] = 0, -["EnergyShieldOnHit"] = 0, -["LifeOnHitRate"] = 0, -["LifeUnreservedPercent"] = 100, -["LifeOnHit"] = 0, -["ShowBlockEffect"] = true, -["ManaLeechInstantRate"] = 0, -["ChaosTakenDotMult"] = 1.6, -["ShockAvoidChance"] = 0, -["IgniteDotMulti"] = 1, -["BlockChanceMax"] = 75, -["EnergyShieldLeechDuration"] = 0, -["LightRadiusMod"] = 1, -["LifeLeechInstantRate"] = 0, -["LifeLeechInstant"] = 0, -["ManaRegen"] = 0.8, -["ChaosChaosBaseTakenHitMult"] = 1.6, -["LifeLeechInstances"] = 0, -["LifeLeechDuration"] = 0, -["TotalDPS"] = 659.8818, -["CritChance"] = 5.5, -["WithBleedDPS"] = 749.6082, -["BlitzCharges"] = 0, -["AvoidLightningDamageChance"] = 0, -["FistOfWarCooldown"] = 0, -["ColdColdBaseTakenHitMult"] = 1.6, -["LightningGuardEffectiveLife"] = 92, -["AvoidFireDamageChance"] = 0, -["ChaosSpellProjectileDamageChance"] = 0, -["SapDurationMod"] = 0, -["FrenzyCharges"] = 0, -["TotalCharges"] = 0, -["ChaosTakenReflectMult"] = 1.6, -["AilmentWarcryEffect"] = 1, -["LifeReserved"] = 0, -["SpellSuppressionChance"] = 0, -["RallyingHitEffect"] = 1, -["FireSpellProjectileDamageChance"] = 0, -["SeismicHitEffect"] = 1, -["TheoreticalMaxOffensiveWarcryEffect"] = 1, -["MaxOffensiveWarcryEffect"] = 1, -["OffensiveWarcryEffect"] = 1, -["EnemyCurseLimit"] = 1, -["Time"] = 0.781, -["LightningEnergyShieldBypass"] = 0, -["Speed"] = 1.2804, -["ColdTotalPool"] = 92, -["LightningMindOverMatter"] = 0, -["ActiveMineLimit"] = 15, -["ChaosTotalEHP"] = 64.7351, -["ChaosNumberOfHits"] = 8.6486, -["ChaosMeleeDamageChance"] = 15, -["FireNumberOfHits"] = 8.6486, -["ColdTotalEHP"] = 64.7351, -["PhysicalResistWhenHit"] = 0, -["ColdNumberOfHits"] = 8.6486, -["IgniteAvoidChance"] = 0, -["FireManaEffectiveLife"] = 92, -["BlitzChargesMax"] = 0, -["BloodCharges"] = 5, -["LightningAverageDamageChance"] = 7.5, -["ColdMaximumHitTaken"] = 57.5, -["SelfFreezeDuration"] = 100, -["LightningMaximumHitTaken"] = 57.5, -["SelfBlindDuration"] = 100, -["FireDotEHP"] = 57.5, -["MovementSpeedMod"] = 1, -["FireTotalPool"] = 92, -["ColdProjectileDamageChance"] = 15, -["BrittleChance"] = 0, -["ChaosSpellDamageChance"] = 0, -["LowestAttribute"] = 14, -["EnduranceChargesMax"] = 3, -["ActionSpeedMod"] = 1, -["SpellBlockChanceOverCap"] = 0, -["MeleeEvadeChance"] = 0, -["ChillAvoidChance"] = 0, -["ProjectileBlockChance"] = 15, -["FireTotalEHP"] = 64.7351, -["RemovableEnduranceCharges"] = 0, -["FireAverageDamageChance"] = 7.5, -["CritBleedDotMulti"] = 1.5, -["ChaosGuardEffectivePool"] = 0, -["ColdAverageDamageChance"] = 7.5, -["CritExtraDamageReduction"] = 0, -["ColdMeleeDamageChance"] = 15, -["LightningSpellDamageChance"] = 0, -["Gear:EnergyShield"] = 0, -["FireResistOverCap"] = 0, -["SelfShockEffect"] = 100, -["ChallengerChargesMax"] = 0, -["LifeReservedPercent"] = 0, -["PhysicalTakenDotMult"] = 1, -["LightningTakenHitMult"] = 1.6, -["StunDuration"] = 0.35, -["PhysicalMeleeDamageChance"] = 15, -["LifeRegen"] = 0, -["AnyMindOverMatter"] = false, -["ManaRegenInc"] = 0, -["MissingFireResist"] = 135, -["AfflictionChargesMin"] = 0, -["WarcryPower"] = 0, -["LightningTakenReflect"] = 1, -["PhysicalAverageDamageChance"] = 7.5, -["LowestOfArmourAndEvasion"] = 0, -["PowerChargesMin"] = 0, -["AverageBlockChance"] = 7.5, -["ColdResistTotal"] = -60, -["FireMindOverMatter"] = 0, -["LightningTotalPool"] = 92, -["TotalPoisonStacks"] = 0, -["dontSplitEvade"] = true, -["AbsorptionChargesMin"] = 0, -["ChaosGuardEffectiveLife"] = 92, -["LifeLeechInstanceRate"] = 1.84, -["ManaOnBlock"] = 0, -["EnergyShieldRechargeAppliesToEnergyShield"] = true, -["MaxLifeLeechRate"] = 18.4, -["ColdResistOverCap"] = 0, -["PhysicalEnergyShieldBypass"] = 0, -["Gear:Armour"] = 0, -["BlockEffect"] = 100, -["ReqStr"] = 122, -["BrutalChargesMax"] = 0, -["LightningTotalEHP"] = 64.7351, -["ChaosProjectileDamageChance"] = 15, -["ManaLeechDuration"] = 0, -["EnergyShieldRecoveryRateMod"] = 1, -["ChaosResistOver75"] = 0, -["EnergyShieldRegenPercent"] = nan, -["CurrentScorch"] = 0, -["SelfChillDuration"] = 100, -["BlockChance"] = 15, -["FireGuardAbsorbRate"] = 0, -["EnergyShieldRecharge"] = 0, -["ChaosManaEffectiveLife"] = 92, -["EffectiveMovementSpeedMod"] = 1, -["AfflictionCharges"] = 0, -["TotalAttr"] = 80, -["FireAegis"] = 0, -["FireEnergyShieldBypass"] = 0, -["Evasion"] = 15, -["Gear:Evasion"] = 0, -["Mana"] = 47, -["LifeOnBlock"] = 0, -["AvoidProjectilesChance"] = 0, -["ColdGuardEffectiveLife"] = 92, -["ColdSpellDamageChance"] = 0, -["ShockDurationMod"] = 0, -["ColdAegis"] = 0, -["PhysicalGuardAbsorbRate"] = 0, -["LightningTakenDotMult"] = 1.6, -["ChaosTakenReflect"] = 1, -["CullPercent"] = 0, -["ColdGuardEffectivePool"] = 0, -["FireGuardEffectiveLife"] = 92, -["PhysicalPhysicalBaseTakenHitMult"] = 1, -["FrenzyChargesMax"] = 3, -["ChaosResistOverCap"] = 0, -["BlindAvoidChance"] = 0, -["FireMaximumHitTaken"] = 57.5, -["Ward"] = 0, -["ManaRecoveryRateMod"] = 1, -["RemovablePowerCharges"] = 0, -["ColdManaEffectiveLife"] = 92, -["LifeRecoveryRateMod"] = 1, -["LightningNumberOfHits"] = 8.6486, -["CritMultiplier"] = 1.5, -["ManaReserved"] = 0, -["ChillDurationMod"] = 0, -["ChaosTotalPool"] = 92, -["FireTakenHitMult"] = 1.6, -["GhostShrouds"] = 0, -["AnyBypass"] = false, -["FireTakenReflect"] = 1, -["SpellDodgeChance"] = 0, -["MeleeNotHitChance"] = 0, -["ManaLeechInstant"] = 0, -["PhysicalManaEffectiveLife"] = 92, -["EvadeChance"] = 0, -["FireTakenDotMult"] = 1.6, -["LightningTakenHit"] = 1, -} - -} \ No newline at end of file diff --git a/spec/TestBuilds/3.13/Dual Wield Cospris CoC.lua b/spec/TestBuilds/3.13/Dual Wield Cospris CoC.lua deleted file mode 100644 index 0f095c45aa1..00000000000 --- a/spec/TestBuilds/3.13/Dual Wield Cospris CoC.lua +++ /dev/null @@ -1,1645 +0,0 @@ -return { - xml = [[ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 8% increased maximum Life - Regenerate 1% of Life per second - - - 3% increased maximum Life - - - Gain 1 Endurance Charge every second if you've been Hit Recently - - - 24% increased Evasion Rating and Armour - 8% increased maximum Life - 10% chance to Intimidate Enemies for 4 seconds on Hit - - - 2% increased Cast Speed - - - 4% increased maximum Mana - - - 4% increased Skill Effect Duration - - - +1% to maximum Fire Resistance - +20% to Fire Resistance - - - 3% increased maximum Energy Shield - - - +10% to Cold Resistance - - - 5% increased Area of Effect - - - 2% increased maximum Life - - - Minions deal 80% increased Damage - - - 15% increased effect of Non-Curse Auras from your Skills - - - 12% increased Fire Damage - - - 1% Chance to Block Spell Damage - - - 5% increased maximum Energy Shield - - - 10% increased maximum Life - Regenerate 1.1% of Life per second - - - +11% to Fire Resistance - - - 3% increased effect of Non-Curse Auras from your Skills - - - 3% increased Effect of your Curses - - - 9% increased Evasion Rating - - - 5% increased Skill Effect Duration - - - 10% increased Area Damage - - - 12% increased Mana Regeneration Rate - - - 10% increased Attack Damage - - - +8% to Chaos Resistance - - - +9% to Critical Strike Multiplier - - - 2% chance to deal Double Damage - 25% increased Physical Damage - - - 3% increased maximum Life - - - 3% increased Movement Speed - - - 3% increased Cast Speed - 11% increased Projectile Damage - 5% chance to Shock - 6% chance to Ignite - - - 12% increased Spell Damage - - - 1% chance to Dodge Attack Hits - - - 7% increased Projectile Speed - - - 3% increased Attack Speed - - - 5% increased Effect of your Curses - - - 7% increased Physical Damage - - - 7% increased Armour - - - +12% to Lightning Resistance - - - 2% increased maximum Life - - - 10% increased Fire Damage - - - 11% increased Area Damage - - - +10% to Fire Resistance - - - 7% increased Area Damage - - - 7% increased Fire Damage - 6% increased maximum Mana - +11% to Lightning Resistance - - - +8% to Critical Strike Multiplier - - - 10% increased Critical Strike Chance - - - 3% increased maximum Life - - - 7% increased Spell Damage - - - 20% increased Area of Effect of Aura Skills - 15% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - +9% to Critical Strike Multiplier - - - 1% chance to Dodge Spell Hits - - - +10% to Fire Resistance - - - +8% to Critical Strike Multiplier - - - 8% increased Armour - - - 5% increased maximum Energy Shield - - - 3% increased maximum Life - - - 28% increased Cold Damage - 10% of Physical Damage Converted to Cold Damage - - - 7% increased maximum Life - 0.4% of Attack Damage Leeched as Life - - - 12% increased Area Damage - - - 7% increased Spell Damage - - - +8% to Critical Strike Multiplier - - - +14% to Fire Resistance - - - 8% increased Chaos Damage - - - 12% increased Physical Damage - - - 10% increased Lightning Damage - - - 3% increased maximum Life - - - 5% increased Area of Effect - - - 6% increased Area of Effect - - - 10% chance to gain a Frenzy Charge on Hit - - - 8% increased maximum Life - Regenerate 0.7% of Life per second - - - 9% increased Evasion Rating - - - +13% to Fire Resistance - - - +11% to Fire Resistance - - - 11% increased Fire Damage - - - 10% increased Projectile Speed - - - 7% increased Projectile Damage - - - 20% increased Area of Effect of Aura Skills - 15% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - 3% increased Movement Speed - - - Minions deal 12% increased Damage - - - 2% increased maximum Life - - - +13% to Lightning Resistance - - - +6% to Chaos Resistance - - - +12% to Lightning Resistance - - - +12% to Fire Resistance - - - +12% to Cold Resistance - - - 10% increased Damage over Time - - - 10% increased Chaos Damage - - - 30% increased Chaos Damage - 25% chance to inflict Withered for 2 seconds on Hit - - - 27% increased Spell Damage - 43% increased Critical Strike Chance for Spells - - - +9% to Critical Strike Multiplier - - - 3% increased effect of Non-Curse Auras from your Skills - - - 12% increased Chaos Damage - - - 3% increased Movement Speed - - - 3% increased Movement Speed - - - 1% Chance to Block Spell Damage - - - 7% increased Spell Damage - - - 33% increased Fire Damage - Damage Penetrates 2% Fire Resistance - - - 9% increased Chaos Damage - - - 9% increased Fire Damage - - - 4% chance to Freeze - - - 1% Chance to Block Spell Damage - - - +9% to Critical Strike Multiplier - - - 5% increased maximum Energy Shield - - - 1% chance to Dodge Spell Hits - - - +7% to Chaos Resistance - - - 2% increased maximum Life - - - +1% to maximum Chaos Resistance - +17% to Chaos Resistance - - - 2% increased maximum Life - - - +8% to Chaos Resistance - - - 34% increased Fire Damage - Damage Penetrates 3% Fire Resistance - - - +12% to Fire Resistance - - - +12% to Cold Resistance - - - 8% increased Attack Damage - - - 4% increased maximum Life - - - 4% increased maximum Mana - - - 12% increased Chaos Damage - - - 12% increased Evasion Rating - - - - https://www.pathofexile.com/passive-skill-tree/AAAABAIBAJuh_EcN0VH7FyYxRaKj99fjhKcre9eMC1ha74iExS9vLU3v66EvH0GMNtteQjrK0wkH1890EH_GMe8NfFgH5-pQMHBSM3IS8WNDG8hd8jsN7LDB8xEPkydwu80WJMDQrSKBxKIWvxhqMlgfx8HFbWwfGCZFD8RMLVBCQdCv64nTuXxJsbQMUimsmM_dbRkUsLjKppmbtVyKXGtrkPGKfbA2PTt8vooki9kTKwpdjjlS-TPDbY9GeoSYU_k3hEgPqy9y7BiXBioLJC3DOlM1VeAZiuq6H0yCHtdK - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Rarity: UNIQUE -Watcher's Eye -Prismatic Jewel -Unique ID: 40f9711d5bd7ad2bcbddaf71c705607aef0eecd3dcadaafec6c0192f79b82863 -Item Level: 86 -Limited to: 1 -Implicits: 0 -5% increased maximum Energy Shield -4% increased maximum Life -4% increased maximum Mana -+1.71% to Critical Strike Chance while affected by Hatred -Effects of Consecrated Ground you create while affected by Zealotry Linger for 2 seconds -Damage Penetrates 15% Cold Resistance while affected by Hatred - - - Rarity: RARE -Dusk Glimmer -Large Cluster Jewel -Unique ID: 2d3cbcc8d8386a5eb230ea8596ae126ec82707dd70839f76f8cf275157a657e1 -Item Level: 82 -LevelReq: 54 -Implicits: 3 -{crafted}Adds 8 Passive Skills -{crafted}2 Added Passive Skills are Jewel Sockets -{crafted}Added Small Passive Skills grant: 12% increased Cold Damage -Added Small Passive Skills also grant: 5% increased Mana Regeneration Rate -1 Added Passive Skill is Blanketed Snow -1 Added Passive Skill is Prismatic Heart -1 Added Passive Skill is Widespread Destruction - - - Rarity: RARE -Kraken Joy -Cobalt Jewel -Unique ID: fd16398b69819790167994dc77e3b69f977be69130d8026b3b02c7239b4a4446 -Item Level: 83 -Implicits: 1 -5% increased Elemental Damage -+11% to Global Critical Strike Multiplier -+14% to Critical Strike Multiplier for Spells -+17% to Critical Strike Multiplier with Cold Skills -8% increased maximum Energy Shield - - - Rarity: UNIQUE -Energy From Within -Cobalt Jewel -Unique ID: 70e1ed44f66615911c6fe0dd1e7c13ef9af4cb1057416a9f2c97e06af979d564 -Item Level: 84 -LevelReq: 26 -Radius: Large -Implicits: 1 -Corrupted Blood cannot be inflicted on you -6% increased maximum Energy Shield -Increases and Reductions to Life in Radius are Transformed to apply to Energy Shield -Corrupted - - - Rarity: RARE -Chimeric Breath -Cobalt Jewel -Unique ID: 674c7bf1100affed697857e93f5d0b79ac6d1aabeb0ecc9181ae76f25a2ea58e -Item Level: 85 -Implicits: 0 -+11% to Global Critical Strike Multiplier -+13% to Critical Strike Multiplier for Spells -+18% to Critical Strike Multiplier with Cold Skills -8% increased maximum Energy Shield - - - Rarity: UNIQUE -Thread of Hope -Crimson Jewel -Unique ID: 4a1fe5b365677ccfdefe80eeaae4d200458f9f71f1ed528cd3f8d9ebdcf151f8 -Item Level: 86 -Radius: Variable -Implicits: 1 -Damage Penetrates 1% Elemental Resistances -Only affects Passives in Large Ring -Passives in Radius can be Allocated without being connected to your tree --11% to all Elemental Resistances -Corrupted - - - Rarity: RARE -Hypnotic Glisten -Medium Cluster Jewel -Unique ID: 18ddae58580b5458b52a8e07b972f43592bfd4e9bf5b10c928dd50c67bbfd06f -Item Level: 83 -LevelReq: 54 -Implicits: 3 -{crafted}Adds 4 Passive Skills -{crafted}1 Added Passive Skill is a Jewel Socket -{crafted}Added Small Passive Skills grant: 15% increased Critical Strike Chance -Added Small Passive Skills also grant: +3% to Lightning Resistance -Added Small Passive Skills also grant: +5 to Strength -1 Added Passive Skill is Pressure Points -1 Added Passive Skill is Quick Getaway - - - Rarity: RARE -Chimeric Spark -Large Cluster Jewel -Unique ID: db1f34511e33c0f8a512380923f2f10bfc2b0a590d83755525c2bbcc7af88bf6 -Item Level: 83 -LevelReq: 54 -Implicits: 4 -{crafted}Adds 8 Passive Skills -{crafted}2 Added Passive Skills are Jewel Sockets -{crafted}Added Small Passive Skills grant: 12% increased Cold Damage -3% increased Area of Effect of Aura Skills -Added Small Passive Skills also grant: +3 to Dexterity -1 Added Passive Skill is Blanketed Snow -1 Added Passive Skill is Prismatic Heart -1 Added Passive Skill is Widespread Destruction - - - Rarity: RARE -Eagle Hope -Medium Cluster Jewel -Unique ID: 44b55f1694ba9a9bb7c6719105c00f47cc1af341df11e0f936188e2c0969d182 -Item Level: 81 -LevelReq: 54 -Implicits: 3 -{crafted}Adds 5 Passive Skills -{crafted}1 Added Passive Skill is a Jewel Socket -{crafted}Added Small Passive Skills grant: 15% increased Critical Strike Chance -Added Small Passive Skills also grant: +5% to Cold Resistance -Added Small Passive Skills also grant: +5 to Intelligence -1 Added Passive Skill is Pressure Points -1 Added Passive Skill is Quick Getaway - - - Rarity: RARE -Oblivion Sliver -Cobalt Jewel -Unique ID: 64a1323507e4508e9f9009a31cd5edd6f6ea9bd445309f2d28f2efeb7b7bba0f -Item Level: 83 -Implicits: 0 -{fractured}8% increased maximum Energy Shield -+12% to Global Critical Strike Multiplier -+13% to Critical Strike Multiplier for Spells -+18% to Critical Strike Multiplier with Cold Skills - - - Rarity: RARE -Brood Ornament -Cobalt Jewel -Unique ID: 562947158c410aa04616602d94434f3162856e8e125c61ceacc5794d81662ae3 -Item Level: 78 -Implicits: 0 -+12% to Global Critical Strike Multiplier -+15% to Critical Strike Multiplier for Spells -+18% to Critical Strike Multiplier with Cold Skills -8% increased maximum Energy Shield - - - Rarity: RARE -Dusk Cut -Medium Cluster Jewel -Unique ID: e8b79cf8b11b6cab2c9a44d1d57cab5175b61d7d01f5a5556d6f09e6df1f1723 -Item Level: 81 -LevelReq: 54 -Implicits: 3 -{crafted}Adds 4 Passive Skills -{crafted}1 Added Passive Skill is a Jewel Socket -{crafted}Added Small Passive Skills grant: 3% increased Effect of your Curses -Added Small Passive Skills also grant: +5% to Cold Resistance -Added Small Passive Skills also grant: Regenerate 0.1% of Life per Second -1 Added Passive Skill is Evil Eye -1 Added Passive Skill is Wish for Death - - - Rarity: RARE -Eagle Hope -Cobalt Jewel -Unique ID: 0409c46e4c9b270990ec666b8b75e985d3983093e7c296ef40a9e7bf9688cf9b -Item Level: 72 -Implicits: 0 -{fractured}+12% to Global Critical Strike Multiplier -+13% to Critical Strike Multiplier for Spells -+18% to Critical Strike Multiplier with Cold Skills -8% increased maximum Energy Shield - - - Rarity: RARE -Dread Knuckle -Moonstone Ring -Unique ID: 346d82b5f01400d23caf59978fbb87a3f3e2adff0e20e32c86409f065bcef5b2 -Shaper Item -Elder Item -Item Level: 83 -LevelReq: 64 -Implicits: 1 -+30 to maximum Energy Shield -Trigger Level 12 Assassin's Mark when you Hit a Rare or Unique Enemy -Adds 20 to 41 Cold Damage to Spells and Attacks -+19% to Global Critical Strike Multiplier -+56 to maximum Energy Shield -6% chance to Freeze -Adds 12 to 30 Cold Damage against Chilled or Frozen Enemies -{crafted}16% increased Cold Damage - - - Rarity: RARE -Behemoth Spur -Two-Toned Boots (Armour/Energy Shield) -Unique ID: 8037cba8056b90a2bd2c9982010207a08e4a236ada4bbb7ec19da5a085687098 -Hunter Item -Redeemer Item -Item Level: 86 -Quality: 30 -Sockets: G-G-B-B -LevelReq: 70 -Implicits: 2 -{crafted}80% chance to Avoid being Stunned if you've Killed Recently -+12% to Fire and Lightning Resistances -+42 to Strength -9% increased Strength -35% increased Movement Speed -19% chance to gain Elusive on Critical Strike -9% increased Elusive Effect -18% increased Effect of Tailwind on you -You have Tailwind if you have dealt a Critical Strike Recently -{crafted}+34 to maximum Energy Shield - - - Rarity: RARE -Honour Veil -Hubris Circlet -Unique ID: 93f4283be9c8db994476a3a5bfd9ef60fdf32fcc255f191c622cc1b21a2a666e -Warlord Item -Redeemer Item -Item Level: 86 -Quality: 30 -Sockets: G-G-B G -LevelReq: 69 -Implicits: 1 -{crafted}Zealotry has 15% reduced Mana Reservation -+20% to Global Critical Strike Multiplier -96% increased Energy Shield -22% increased Elemental Damage -7% reduced Mana Reserved -Damage Penetrates 3% of Enemy Elemental Resistances -Nearby Enemies have -9% to Cold Resistance -{crafted}+45 to maximum Energy Shield - - - Rarity: UNIQUE -Cospri's Malice -Jewelled Foil -Unique ID: 0a331d6968381dd99594f5cd6132943b1b1e5e39020397605501603949191678 -Item Level: 75 -Quality: 20 -Sockets: B-B-B -LevelReq: 68 -Implicits: 3 -{crafted}Quality does not increase Physical Damage -{crafted}Grants 1% increased Elemental Damage per 2% Quality -Skills fire an additional Projectile -Trigger a Socketed Cold Spell on Melee Critical Strike -+257 Intelligence Requirement -No Physical Damage -Adds 94 to 167 Cold Damage -Adds 57 to 101 Cold Damage to Spells -9% increased Attack Speed -60% increased Critical Strike Chance against Chilled Enemies -Corrupted - - - Rarity: RARE -Kraken Shackle -Crystal Belt -Unique ID: 1fdf3bc5ec92991c311859456844a857333f206c599831e057caee7d05bf2ac0 -Shaper Item -Crusader Item -Item Level: 86 -LevelReq: 79 -Implicits: 1 -+96 to maximum Energy Shield -+61 to maximum Energy Shield -16% increased maximum Energy Shield -+48% to Fire Resistance -+43% to Lightning Resistance -36% increased Energy Shield from Body Armour -28% increased Spell Damage during any Flask Effect -20% increased Cooldown Recovery - - - Rarity: RARE -Mind Spiral -Topaz Ring -Unique ID: b6dd3b4d9bcb60886aa7c2c1faf5e3da9fa1b5f4f18ad40ecd673c529ccfeab0 -Crusader Item -Item Level: 85 -LevelReq: 67 -Implicits: 1 -+36% to Lightning Resistance -25% increased Spell Damage -+45 to maximum Energy Shield -13% increased maximum Energy Shield -+19% to all Elemental Resistances -+57% to Fire Resistance -+56% to Cold Resistance - - - Rarity: MAGIC -Alchemist's Quicksilver Flask of Adrenaline -Unique ID: df4a300d384a39f893e08838bbb21f77d2e0308232f32a2be7056171752ecbda -Item Level: 42 -Quality: 20 -LevelReq: 16 -Implicits: 0 -30% increased Movement Speed during Flask effect -25% increased effect -33% reduced Duration - - - Rarity: UNIQUE -Atziri's Promise -Amethyst Flask -Unique ID: 82a02cd5ae91c45af9d472f20355e22c148033f4156a9db34d04524441df9cbd -Item Level: 85 -Quality: 0 -LevelReq: 68 -Implicits: 0 -2% of Chaos Damage Leeched as Life during Flask effect -Gain 20% of Physical Damage as Extra Chaos Damage during effect -Gain 15% of Elemental Damage as Extra Chaos Damage during effect - - - Rarity: MAGIC -Enduring Eternal Mana Flask of Heat -Unique ID: c8691aa616346249cdae9722f0b78f2a70c8c1b1441be40c73b0780ef713b484 -Item Level: 72 -Quality: 26 -LevelReq: 65 -Implicits: 0 -30% reduced Amount Recovered -Immunity to Freeze and Chill during Flask effect -Removes Freeze and Chill on use -30% reduced Duration -Flask Effect is not removed at Full Mana -Flask Effect does not Queue - - - Rarity: UNIQUE -Dying Sun -Ruby Flask -Unique ID: 2c27fad04da58e0c7faf96884765635ab45ec396bf6ac92ff8b8f94bfeb2b9b8 -Item Level: 80 -Quality: 0 -LevelReq: 68 -Implicits: 0 -8% reduced Charges used -Skills fire 2 additional Projectiles during Flask Effect -25% increased Area of Effect during Flask Effect - - - Rarity: UNIQUE -Shavronne's Wrappings -Occultist's Vestment -Unique ID: c5663fe63ec58fca7c88c5988623dd3bdceb89c9e8ac624d8227fc9f47d39f67 -Item Level: 70 -Quality: 20 -Sockets: G-G-G-B-B-B -LevelReq: 62 -Implicits: 2 -+1 to Level of Socketed Gems -+2 to Level of Socketed Projectile Gems -134% increased Energy Shield -10% faster start of Energy Shield Recharge -+36% to Lightning Resistance -Reflects 1 to 250 Lightning Damage to Melee Attackers -Chaos Damage does not bypass Energy Shield -Corrupted - - - Rarity: UNIQUE -Cospri's Malice -Jewelled Foil -Unique ID: e022814fd14bf965ffb1abf8305e539c1ab40ab59c4add1ae8927f3a83af8480 -Item Level: 83 -Quality: 0 -Sockets: B-G-B -LevelReq: 68 -Implicits: 1 -Skills fire an additional Projectile -Trigger a Socketed Cold Spell on Melee Critical Strike -+257 Intelligence Requirement -No Physical Damage -Adds 91 to 161 Cold Damage -Adds 55 to 106 Cold Damage to Spells -14% increased Attack Speed -60% increased Critical Strike Chance against Chilled Enemies -Corrupted - - - Rarity: RARE -Agony Touch -Fingerless Silk Gloves -Unique ID: 38caeb692e3b3996b6162db7fc10810a0bf205ad18ce3c413eaabffa986c2440 -Hunter Item -Item Level: 85 -Quality: 28 -Sockets: W-W-W-B -LevelReq: 70 -Implicits: 2 -{crafted}Trigger Commandment of Frost on Kill -16% increased Spell Damage -+588 to Accuracy Rating -+47 to maximum Energy Shield -96% increased Energy Shield -+48% to Cold Resistance -Unnerve Enemies for 4 seconds on Hit -50% increased Damage with Hits against Chilled Enemies -{crafted}12% increased Attack Speed - - - Rarity: UNIQUE -Bottled Faith -Sulphur Flask -Unique ID: 8a2882da1154eaefb6594f530acd5234a62b9093ba09702355432766c2f2e045 -Item Level: 85 -Quality: 20 -LevelReq: 35 -Implicits: 1 -Creates Consecrated Ground on Use -45% increased Duration -Consecrated Ground created by this Flask has Tripled Radius -+2% to Critical Strike Chance against Enemies on Consecrated Ground during Effect -Consecrated Ground created during Effect applies 10% increased Damage taken to Enemies - - - Rarity: UNIQUE -Badge of the Brotherhood -Turquoise Amulet -Unique ID: e6b2caa3bf151e3cbbaffce1c93329c2252d608bb683c24b70cb3be8e7d0e887 -Item Level: 85 -LevelReq: 60 -Implicits: 2 -{crafted}Allocates Overcharge -+24 to Dexterity and Intelligence -Your Maximum Frenzy Charges is equal to your Maximum Power Charges -9% increased Cooldown Recovery Rate of Travel Skills per Frenzy Charge -10% increased Effect of Elusive on you per Power Charge -25% chance to lose a Frenzy Charge when you use a Travel Skill -22% chance to lose a Power Charge when you gain Elusive - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]], - output = {["SpellSuppressionChanceOverCap"] = 0, -["FrenzyChargesMin"] = 0, -["EnergyShieldOnGloves"] = 202, -["HitChance"] = 100, -["LightningDotEHP"] = 24929.1667, -["CrabBarriersMax"] = 0, -["BlockEffect"] = 100, -["AvoidColdDamageChance"] = 25, -["PierceCount"] = 0, -["AnyTakenReflect"] = 0, -["InspirationCharges"] = 5, -["AbsorptionChargesMax"] = 0, -["LifePercentCost"] = 0, -["ReqInt"] = 257, -["ProjectileNotHitChance"] = 0, -["LifeCost"] = 0, -["ManaPercentCost"] = 0, -["ColdMinBase"] = 669.2, -["MaxManaLeechRate"] = 189.2, -["PhysicalTakenReflectMult"] = 0.97, -["LightningLightningBaseTakenHitMult"] = 0.24, -["SelfShockDuration"] = 100, -["ManaOnHit"] = 0, -["AfflictionChargesMax"] = 0, -["PhysicalProjectileDamageChance"] = 36.25, -["ManaCost"] = 45, -["DoubleDamageChance"] = 10, -["SpellSuppressionEffect"] = 50, -["BloodChargesMax"] = 5, -["FireMeleeDamageChance"] = 36.25, -["PhysicalGuardEffectiveLife"] = 69, -["ActiveTrapLimit"] = 15, -["PhysicalAegis"] = 0, -["EnergyShieldRegen"] = 0, -["LightningAegis"] = 0, -["SiphoningCharges"] = 0, -["RuthlessBlowEffect"] = 1, -["Cooldown"] = 0.132, -["PhysicalTakenHitMult"] = 0.97, -["ChaosDotEHP"] = 4786.4, -["ReqStr"] = 114, -["LightningGuardAbsorbRate"] = 0, -["MissingLightningResist"] = 0, -["MaxManaLeechInstance"] = 94.6, -["LightningGuardEffectivePool"] = 0, -["EnergyShieldOnBody Armour"] = 330, -["MaxEnergyShieldLeechRate"] = 295.7, -["EnergyShieldLeechInstanceRate"] = 118.28, -["PhysicalNumberOfHits"] = 8.6486, -["ChaosTakenHit"] = 1, -["FireFireBaseTakenHitMult"] = 0.2, -["CurrentShock"] = 0, -["PhysicalResist"] = 0, -["ColdSpellProjectileDamageChance"] = 25, -["FireResistOver75"] = 0, -["ColdResist"] = 75, -["Spec:EnergyShieldInc"] = 125, -["ScorchChanceOnHit"] = 0, -["PhysicalMinBase"] = 0, -["SpellProjectileBlockChance"] = 0, -["ColdTakenReflectMult"] = 0.25, -["Dex"] = 247, -["Spec:EvasionInc"] = 148, -["Spec:ArmourInc"] = 0, -["Spec:ManaInc"] = 8, -["Spec:LifeInc"] = 0, -["ExtraPoints"] = 2, -["KnockbackChanceOnHit"] = 0, -["TheoreticalOffensiveWarcryEffect"] = 1, -["IgniteChanceOnHit"] = 0, -["FullDPS"] = 0, -["PowerChargesMax"] = 6, -["EnergyShieldLeechInstantRate"] = 0, -["CullingDPS"] = 2819202.2946, -["ElusiveEffectMod"] = 169, -["TotalDotDPS"] = 0, -["SelfBleedDuration"] = 100, -["MaxOffensiveWarcryEffect"] = 1, -["WithIgniteDPS"] = 25372820.6514, -["PhysicalDamageReduction"] = 3, -["SelfChillEffect"] = 100, -["Str"] = 116, -["SpellDodgeChanceOverCap"] = 0, -["WithPoisonDPS"] = 25372820.6514, -["FireProjectileDamageChance"] = 36.25, -["LightningSpellProjectileDamageChance"] = 25, -["AttackDodgeChanceOverCap"] = 0, -["CombinedAvg"] = 25372820.6514, -["CombinedDPS"] = 28192022.946, -["TotalDot"] = 0, -["FireCritAverage"] = 0, -["AnyGuard"] = false, -["PhysicalTakenReflect"] = 1, -["MaximumScorch"] = 50, -["ShieldBlockChance"] = 0, -["EnemyStunDuration"] = 0.35, -["EnergyShieldLeechGainRate"] = 295.7, -["EnemyStunThresholdMod"] = 1, -["KnockbackChance"] = 0, -["SpellBlockChance"] = 0, -["PhysicalMindOverMatter"] = 0, -["FreezeDurationMod"] = 1.08, -["FreezeChance"] = 100, -["LightningManaEffectiveLife"] = 69, -["TriggerTime"] = 0.1325, -["LightningResistOver75"] = 1, -["ColdTakenReflect"] = 1, -["SpellBlockChanceMax"] = 75, -["ChaosEnergyShieldBypass"] = 0, -["EnergyShieldOnBoots"] = 75, -["impaleStoredHitAvg"] = 0, -["ChillEffectModDisplay"] = 0, -["ManaOnHitRate"] = 0, -["DamageTakenOnBlock"] = 0, -["ChillEffectMod"] = 1, -["EnergyShieldRechargeDelay"] = 1.8182, -["EnergyShieldRegenPercent"] = 0, -["ShockChance"] = 100, -["IgniteChance"] = 100, -["BlockChanceOverCap"] = 0, -["ChallengerCharges"] = 0, -["Int"] = 381, -["ColdEnergyShieldBypass"] = 0, -["CritIgniteDotMulti"] = 1.5, -["FireResistTotal"] = 145, -["FreezeAvoidChance"] = 100, -["IgniteDotMulti"] = 1, -["ChaosTakenHitMult"] = 1.25, -["LifeLeechRate"] = 269.6, -["BleedChanceOnHit"] = 0, -["IgniteFireMin"] = 0, -["AttackDodgeChance"] = 0, -["ImpaleChance"] = 0, -["EnergyShieldLeechDuration"] = 5, -["BrittleChanceOnHit"] = 0, -["ChillChanceOnHit"] = 0, -["FreezeChanceOnHit"] = 0, -["ReqDex"] = 212, -["ColdTakenHit"] = 1, -["ShockChanceOnHit"] = 0, -["LightningProjectileDamageChance"] = 36.25, -["PhysicalHitAverage"] = 0, -["ChillChance"] = 100, -["DoubleDamageChanceOnCrit"] = 10, -["BrutalChargesMin"] = 0, -["ChaosMindOverMatter"] = 0, -["PoisonChanceOnHit"] = 0, -["Armour"] = 164, -["KnockbackChanceOnCrit"] = 0, -["SapChanceOnCrit"] = 0, -["PoisonAvoidChance"] = 0, -["LightningResistTotal"] = 98, -["FireMinBase"] = 0, -["LightningMinBase"] = 0, -["FireDotEHP"] = 29915, -["CritChance"] = 100, -["ChillChanceOnCrit"] = 100, -["InterruptStunAvoidChance"] = 25, -["RuthlessBlowMaxCount"] = 0, -["ScaledDamageEffect"] = 1.1, -["AverageDamage"] = 305512.5906, -["ColdTakenHitMult"] = 0.25, -["PowerChargesMin"] = 1, -["Devotion"] = 0, -["MissingColdResist"] = 0, -["ChaosGuardAbsorbRate"] = 0, -["ShockChanceOnCrit"] = 100, -["IgniteChanceOnCrit"] = 100, -["PhysicalTakenHit"] = 1, -["ActionTriggerRate"] = 7.5758, -["PoisonChanceOnCrit"] = 0, -["BleedChanceOnCrit"] = 0, -["ManaLeechGainRate"] = 0, -["ColdGuardAbsorbRate"] = 0, -["LifeLeechInstances"] = 415.25, -["LifeUnreserved"] = 69, -["IgniteFireMax"] = 0, -["FireResist"] = 75, -["RemovableFrenzyCharges"] = 6, -["ManaLeechRate"] = 0, -["ChaosAegis"] = 0, -["ManaLeechInstanceRate"] = 18.92, -["EnergyShieldLeechPerHit"] = 591.4, -["EnergyShieldLeechRate"] = 295.7, -["PhysicalTotalPool"] = 5983, -["FreezeChanceOnCrit"] = 100, -["BlockDuration"] = 0.35, -["ManaLeechPerHit"] = 0, -["FrenzyChargesMax"] = 6, -["MissingChaosResist"] = 100, -["TotalDPS"] = 25372820.6514, -["AverageHit"] = 305512.5906, -["FireTakenHit"] = 0.8, -["EnergyShieldOnHitRate"] = 0, -["BleedAvoidChance"] = 0, -["AverageNotHitChance"] = 0, -["LifeOnHitRate"] = 0, -["EnergyShieldOnBlock"] = 0, -["EnergyShieldOnHit"] = 0, -["StunAvoidChance"] = 90, -["LifeOnHit"] = 0, -["ColdResistOverCap"] = 17, -["Life"] = 1348, -["DurationMod"] = 1, -["ManaLeechInstantRate"] = 0, -["EnduranceCharges"] = 0, -["ChainRemaining"] = 0, -["ShockAvoidChance"] = 0, -["ColdTakenDotMult"] = 0.25, -["ChaosAverageDamageChance"] = 30.625, -["ManaLeechInstances"] = 0, -["ChaosMaximumHitTaken"] = 4786.4, -["SapChanceOnHit"] = 0, -["PhysicalTotalEHP"] = 10660.2808, -["ESCost"] = 0, -["ManaUnreservedPercent"] = 9.9366, -["ColdMindOverMatter"] = 0, -["PhysicalGuardEffectivePool"] = 0, -["LifeLeechInstantRate"] = 0, -["MaximumShock"] = 50, -["LifeLeechDuration"] = 5, -["EnergyShieldLeechInstant"] = 0, -["SpellProjectileNotHitChance"] = 0, -["LifeRegenPercent"] = 0.1, -["LightningResist"] = 76, -["PhysicalSpellProjectileDamageChance"] = 25, -["LifeLeechGainRate"] = 269.6, -["SpellNotHitChance"] = 0, -["LifeReservedPercent"] = 94.8813, -["PhysicalMaximumHitTaken"] = 6168.0412, -["TotalMax"] = 61273.3825, -["WarcryPower"] = 20, -["ProjectileEvadeChance"] = 0, -["AbsorptionCharges"] = 0, -["FireMaxBase"] = 0, -["LightningCritAverage"] = 0, -["FireEnergyShieldBypass"] = 0, -["MaxEnergyShieldLeechInstance"] = 591.4, -["HexDoomLimit"] = 30, -["PhysicalSpellDamageChance"] = 25, -["EnergyShieldLeechInstances"] = 415.25, -["AvoidPhysicalDamageChance"] = 25, -["FireHitAverage"] = 0, -["ProjectileCount"] = 11, -["CullMultiplier"] = 1.1111, -["ColdHitAverage"] = 46444.8188, -["ChaosResistTotal"] = -25, -["CrabBarriers"] = 0, -["LightningResistOverCap"] = 22, -["FireNumberOfHits"] = 36.036, -["ChaosCritAverage"] = 22199.1963, -["EnergyShieldOnHelmet"] = 273, -["TotalDotInstance"] = 0, -["ManaReservedPercent"] = 90.0634, -["FireResistOverCap"] = 70, -["PhysicalCritAverage"] = 0, -["LightningTakenReflectMult"] = 0.24, -["AvoidChaosDamageChance"] = 25, -["allMult"] = 1.1, -["PhysicalTakenDotMult"] = 1, -["ManaLeech"] = 0, -["GhostShrouds"] = 0, -["LifeLeechInstant"] = 0, -["LowestOfMaximumLifeAndMaximumMana"] = 946, -["ColdDotEHP"] = 23932, -["LifeLeech"] = 134.8, -["SelfPoisonDuration"] = 100, -["ChaosMaxBase"] = 0, -["ColdResistTotal"] = 92, -["BrutalCharges"] = 0, -["ColdMaxBase"] = 1054.2, -["LightningMaxBase"] = 0, -["PhysicalMaxBase"] = 0, -["PhysicalGuardAbsorbRate"] = 0, -["InspirationChargesMax"] = 5, -["ChaosResist"] = -25, -["DoubleDamageEffect"] = 1.1, -["TripleDamageEffect"] = 1, -["PreEffectiveCritChance"] = 100, -["ManaUnreserved"] = 94, -["FireTakenReflect"] = 0.8, -["Accuracy"] = 4112.55, -["TripleDamageChanceOnCrit"] = 0, -["LifeLeechPerHit"] = 134.8, -["BonusCritDotMultiplier"] = 0, -["CritEffect"] = 6.1, -["WardRechargeDelay"] = 5, -["FireTakenReflectMult"] = 0.2, -["MaxLifeLeechInstance"] = 134.8, -["SpellSuppressionEffectiveChance"] = 0, -["EnduranceChargesMin"] = 0, -["ActiveGolemLimit"] = 1, -["FireManaEffectiveLife"] = 69, -["TripleDamageChance"] = 0, -["LifeUnreservedPercent"] = 5.1187, -["ScorchChanceOnCrit"] = 0, -["ShowBlockEffect"] = true, -["FistOfWarCooldown"] = 0, -["RuthlessBlowMultiplier"] = 1, -["FistOfWarAilmentEffect"] = 1, -["ServerTriggerRate"] = 7.55, -["BlockChanceMax"] = 75, -["RuthlessBlowChance"] = 0, -["LightRadiusMod"] = 1, -["FistOfWarHitEffect"] = 1, -["ExertedAttackUptimeRatio"] = 0, -["ManaRegen"] = 35.6, -["ChaosChaosBaseTakenHitMult"] = 1.25, -["AilmentWarcryEffect"] = 1, -["RallyingHitEffect"] = 1, -["SourceTriggerRate"] = 7.55, -["SeismicHitEffect"] = 1, -["TheoreticalMaxOffensiveWarcryEffect"] = 1, -["WithBleedDPS"] = 25372820.6514, -["OffensiveWarcryEffect"] = 1, -["AvoidLightningDamageChance"] = 25, -["Speed"] = 7.55, -["ColdColdBaseTakenHitMult"] = 0.25, -["SelfIgniteDuration"] = 100, -["AvoidFireDamageChance"] = 25, -["ChaosSpellProjectileDamageChance"] = 25, -["Time"] = 0.1325, -["FrenzyCharges"] = 6, -["TotalCharges"] = 12, -["ChaosTakenReflectMult"] = 1.25, -["RageCost"] = 0, -["LifeReserved"] = 1279, -["SpellSuppressionChance"] = 0, -["ProjectileSpeedMod"] = 1.86, -["FireSpellProjectileDamageChance"] = 25, -["PiercedCount"] = 0, -["PierceCountString"] = 0, -["ForkCountString"] = "0", -["Chain"] = 0, -["EnemyCurseLimit"] = 2, -["ChainMaxString"] = 0, -["LightningEnergyShieldBypass"] = 0, -["ChainMax"] = 0, -["ActiveMineLimit"] = 15, -["ColdTotalPool"] = 5983, -["LightningMindOverMatter"] = 0, -["ChaosTotalEHP"] = 7106.8539, -["ChaosNumberOfHits"] = 5.7658, -["FireSpellDamageChance"] = 25, -["LightningHitAverage"] = 0, -["ColdTotalEHP"] = 35534.2694, -["ColdNumberOfHits"] = 28.8288, -["CritExtraDamageReduction"] = 0, -["PhysicalResistWhenHit"] = 0, -["Gear:Ward"] = 0, -["BloodCharges"] = 5, -["ColdMaximumHitTaken"] = 23932, -["BlitzChargesMax"] = 0, -["LightningMaximumHitTaken"] = 24929.1667, -["LightningAverageDamageChance"] = 30.625, -["BrittleChanceOnCrit"] = 0, -["SelfFreezeDuration"] = 100, -["PhysicalDotEHP"] = 5983, -["ChaosGuardEffectiveLife"] = 69, -["ChaosSpellDamageChance"] = 25, -["MovementSpeedMod"] = 3.59, -["FireTotalPool"] = 5983, -["ColdProjectileDamageChance"] = 36.25, -["ChillAvoidChance"] = 100, -["ChaosMeleeDamageChance"] = 36.25, -["LowestAttribute"] = 116, -["EnduranceChargesMax"] = 3, -["ActionSpeedMod"] = 1.09, -["SpellBlockChanceOverCap"] = 0, -["MeleeEvadeChance"] = 0, -["FireAverageDamageChance"] = 30.625, -["ProjectileBlockChance"] = 15, -["FireTotalEHP"] = 44417.8368, -["RemovableEnduranceCharges"] = 0, -["ColdAverageDamageChance"] = 30.625, -["ColdAegis"] = 0, -["ChaosGuardEffectivePool"] = 0, -["ColdMeleeDamageChance"] = 36.25, -["LightningSpellDamageChance"] = 25, -["LightningMeleeDamageChance"] = 36.25, -["PhysicalAverageDamageChance"] = 30.625, -["Gear:EnergyShield"] = 880, -["EnergyShield"] = 5914, -["SelfShockEffect"] = 100, -["dontSplitEvade"] = true, -["ColdCritAverage"] = 283313.3944, -["ChallengerChargesMax"] = 0, -["LightningTakenHitMult"] = 0.24, -["StunDuration"] = 0.35, -["PhysicalMeleeDamageChance"] = 36.25, -["AverageBlockChance"] = 7.5, -["AnyMindOverMatter"] = false, -["ManaRegenInc"] = 115, -["SpellDodgeChance"] = 0, -["AfflictionChargesMin"] = 0, -["ChaosResistOver75"] = 0, -["LightningTakenReflect"] = 1, -["FireTakenHitMult"] = 0.2, -["LowestOfArmourAndEvasion"] = 45, -["EnergyShieldLeech"] = 591.4, -["ChaosMinBase"] = 0, -["FireMindOverMatter"] = 0, -["AnyAegis"] = false, -["ChaosHitAverage"] = 3639.2125, -["ArmourOnBoots"] = 164, -["AbsorptionChargesMin"] = 0, -["EvadeChance"] = 0, -["DamageReductionMax"] = 90, -["LifeLeechInstanceRate"] = 26.96, -["ColdResistOver75"] = 0, -["EnergyShieldRechargeAppliesToEnergyShield"] = true, -["ManaOnBlock"] = 0, -["MissingFireResist"] = 0, -["IgniteAvoidChance"] = 0, -["SiphoningChargesMax"] = 0, -["EnergyShieldRecharge"] = 3454, -["Gear:Armour"] = 164, -["BrutalChargesMax"] = 0, -["LightningTotalEHP"] = 37310.9829, -["ChaosProjectileDamageChance"] = 36.25, -["ManaLeechDuration"] = 0, -["SelfBlindDuration"] = 100, -["EffectiveMovementSpeedMod"] = 3.9131, -["MaxLifeLeechRate"] = 269.6, -["CurrentScorch"] = 0, -["SelfChillDuration"] = 100, -["BlockChance"] = 15, -["FireGuardAbsorbRate"] = 0, -["ChaosPoisonChance"] = 0, -["ChaosManaEffectiveLife"] = 69, -["PowerCharges"] = 6, -["AfflictionCharges"] = 0, -["TotalAttr"] = 744, -["FireAegis"] = 0, -["LifeOnBlock"] = 0, -["Evasion"] = 45, -["Gear:Evasion"] = 0, -["Mana"] = 946, -["EnergyShieldOnSpellBlock"] = 0, -["AvoidProjectilesChance"] = 0, -["ColdGuardEffectiveLife"] = 69, -["ColdSpellDamageChance"] = 25, -["FireGuardEffectivePool"] = 0, -["PhysicalEnergyShieldBypass"] = 0, -["LightningTakenDotMult"] = 0.24, -["TotalMin"] = 38894.68, -["ChaosTakenReflect"] = 1, -["CullPercent"] = 10, -["ColdGuardEffectivePool"] = 0, -["BlitzCharges"] = 0, -["PhysicalPhysicalBaseTakenHitMult"] = 0.97, -["LightningGuardEffectiveLife"] = 69, -["ChaosResistOverCap"] = 0, -["BlindAvoidChance"] = 0, -["FireMaximumHitTaken"] = 29915, -["Ward"] = 0, -["ManaRecoveryRateMod"] = 1, -["RemovablePowerCharges"] = 5, -["FireGuardEffectiveLife"] = 69, -["LifeRecoveryRateMod"] = 1, -["LightningNumberOfHits"] = 30.2703, -["CritMultiplier"] = 6.1, -["ManaReserved"] = 852, -["ChillDurationMod"] = 1, -["LifeRegen"] = 1.348, -["LightningTotalPool"] = 5983, -["ColdManaEffectiveLife"] = 69, -["AnyBypass"] = true, -["ChaosTotalPool"] = 5983, -["EnergyShieldRecoveryRateMod"] = 1, -["MeleeNotHitChance"] = 0, -["ManaLeechInstant"] = 0, -["PhysicalManaEffectiveLife"] = 69, -["ChaosTakenDotMult"] = 1.25, -["FireTakenDotMult"] = 0.2, -["LightningTakenHit"] = 1, -} - -} \ No newline at end of file diff --git a/spec/TestBuilds/3.13/Generals Perforate Zerker.lua b/spec/TestBuilds/3.13/Generals Perforate Zerker.lua deleted file mode 100644 index 491269fa053..00000000000 --- a/spec/TestBuilds/3.13/Generals Perforate Zerker.lua +++ /dev/null @@ -1,1611 +0,0 @@ -return { - xml = [[ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 8% increased maximum Life - Regenerate 1% of Life per second - - - 3% increased maximum Life - - - Gain 1 Endurance Charge every second if you've been Hit Recently - - - 20% increased Area of Effect of Aura Skills - 15% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - 2% increased Cast Speed - - - 4% increased maximum Mana - - - 4% increased Skill Effect Duration - - - 2% increased maximum Life - - - 3% increased maximum Energy Shield - - - 5% increased Area of Effect - - - +10% to Cold Resistance - - - +1% to maximum Fire Resistance - +20% to Fire Resistance - - - 15% increased effect of Non-Curse Auras from your Skills - - - Minions deal 80% increased Damage - - - 12% increased Fire Damage - - - 1% Chance to Block Spell Damage - - - 5% increased maximum Energy Shield - - - 10% increased maximum Life - Regenerate 1.1% of Life per second - - - +11% to Fire Resistance - - - 3% increased effect of Non-Curse Auras from your Skills - - - 5% increased Skill Effect Duration - - - 9% increased Evasion Rating - - - 3% increased Effect of your Curses - - - 10% increased Area Damage - - - 12% increased Mana Regeneration Rate - - - 10% increased Attack Damage - - - +8% to Chaos Resistance - - - +9% to Critical Strike Multiplier - - - 2% chance to deal Double Damage - 25% increased Physical Damage - - - 3% increased maximum Life - - - 3% increased Movement Speed - - - 3% increased Cast Speed - 11% increased Projectile Damage - 5% chance to Shock - 6% chance to Ignite - - - 12% increased Spell Damage - - - 1% chance to Dodge Attack Hits - - - 7% increased Projectile Speed - - - 3% increased Attack Speed - - - 2% increased maximum Life - - - 7% increased Physical Damage - - - +12% to Lightning Resistance - - - 7% increased Armour - - - 5% increased Effect of your Curses - - - 34% increased Fire Damage - Damage Penetrates 3% Fire Resistance - - - +12% to Fire Resistance - - - +12% to Cold Resistance - - - 12% increased Evasion Rating - - - 4% increased maximum Life - - - 12% increased Chaos Damage - - - 4% increased maximum Mana - - - 8% increased Attack Damage - - - 11% increased Area Damage - - - +10% to Fire Resistance - - - 7% increased Area Damage - - - 7% increased Spell Damage - - - +8% to Critical Strike Multiplier - - - 3% increased maximum Life - - - 10% increased Critical Strike Chance - - - 7% increased Fire Damage - 6% increased maximum Mana - +11% to Lightning Resistance - - - +7% to Chaos Resistance - - - 2% increased maximum Life - - - +1% to maximum Chaos Resistance - +17% to Chaos Resistance - - - 2% increased maximum Life - - - +8% to Chaos Resistance - - - +9% to Critical Strike Multiplier - - - 1% chance to Dodge Spell Hits - - - +10% to Fire Resistance - - - +8% to Critical Strike Multiplier - - - 8% increased Armour - - - 5% increased maximum Energy Shield - - - 3% increased maximum Life - - - 28% increased Cold Damage - 10% of Physical Damage Converted to Cold Damage - - - 7% increased maximum Life - 0.4% of Attack Damage Leeched as Life - - - 12% increased Area Damage - - - 7% increased Spell Damage - - - 10% increased Lightning Damage - - - +14% to Fire Resistance - - - 12% increased Physical Damage - - - 8% increased Chaos Damage - - - +8% to Critical Strike Multiplier - - - 33% increased Fire Damage - Damage Penetrates 2% Fire Resistance - - - 9% increased Chaos Damage - - - 9% increased Fire Damage - - - 1% chance to Dodge Spell Hits - - - 1% Chance to Block Spell Damage - - - 5% increased maximum Energy Shield - - - +9% to Critical Strike Multiplier - - - 4% chance to Freeze - - - 10% chance to gain a Frenzy Charge on Hit - - - 8% increased maximum Life - Regenerate 0.7% of Life per second - - - 9% increased Evasion Rating - - - 7% increased Projectile Damage - - - +11% to Fire Resistance - - - 10% increased Projectile Speed - - - 11% increased Fire Damage - - - +13% to Fire Resistance - - - 27% increased Spell Damage - 43% increased Critical Strike Chance for Spells - - - +9% to Critical Strike Multiplier - - - 3% increased effect of Non-Curse Auras from your Skills - - - 7% increased Spell Damage - - - 3% increased Movement Speed - - - 1% Chance to Block Spell Damage - - - 3% increased Movement Speed - - - 12% increased Chaos Damage - - - +12% to Lightning Resistance - - - +12% to Fire Resistance - - - 30% increased Chaos Damage - 25% chance to inflict Withered for 2 seconds on Hit - - - 10% increased Damage over Time - - - 10% increased Chaos Damage - - - +12% to Cold Resistance - - - 4% increased effect of Non-Curse Auras from your Skills - - - 3% increased Movement Speed - - - +6% to Chaos Resistance - - - +13% to Lightning Resistance - - - Minions deal 12% increased Damage - - - 2% increased maximum Life - - - 10% increased Fire Damage - - - 3% increased maximum Life - - - 5% increased Area of Effect - - - 6% increased Area of Effect - - - 20% increased Area of Effect of Aura Skills - 15% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - 24% increased Evasion Rating and Armour - 8% increased maximum Life - 10% chance to Intimidate Enemies for 4 seconds on Hit - - - - https://www.pathofexile.com/passive-skill-tree/AAAABAECAGMXNrHcMuxxwBrBBGVNG6o6kayJ7npaMrXyP_w1kteWXbApJH37CLHDaHfjPfyGYJhvehm_uL024e-SfRbpjM9fP8VTKWLvDhQgvJ826GGK3CNQR_cyBTx2rA48f-MUcXKpJDeE2YIHR365QlhjYVLiiMEHkw8Ju6s582_qGM9-2Xw6UjH79kjqEPPdtbd5aNyM-OtIeIjt5c9vOwHc135oWORRgy7oZmhleA34uQDg8OL6GL6n2L2YVxiRxthJ1ZcI0uOJ2CGQhY9Yr6lu - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Rarity: RARE -Entropy Shard -Crimson Jewel -Unique ID: 2149ce085ecc736f25f330a8bd01e9e791dfeaa15fd6a1c63dd5750ba4b0c1a7 -Item Level: 81 -Implicits: 0 -{fractured}20% increased Damage with Bleeding -+12% to Global Critical Strike Multiplier -+17% to Critical Strike Multiplier with One Handed Melee Weapons -7% increased maximum Life - - - Rarity: RARE -Glyph Star -Medium Cluster Jewel -Unique ID: 3f02b527d0acd77296a6cfe70494383e62a10b63beb78bf956fbc2c64ad59608 -Item Level: 82 -LevelReq: 54 -Implicits: 3 -{crafted}Adds 5 Passive Skills -{crafted}1 Added Passive Skill is a Jewel Socket -{crafted}Added Small Passive Skills grant: Exerted Attacks deal 20% increased Damage -Added Small Passive Skills also grant: +4% to Chaos Resistance -1 Added Passive Skill is Provocateur -1 Added Passive Skill is Warning Call - - - Rarity: RARE -Empyrean Hope -Medium Cluster Jewel -Unique ID: bf2fd407fedc650f2ed506f54e54303796afe501fa6dc63db75dec9ad0c1800a -Item Level: 83 -LevelReq: 40 -Implicits: 3 -{crafted}Adds 4 Passive Skills -{crafted}1 Added Passive Skill is a Jewel Socket -{crafted}Added Small Passive Skills grant: Exerted Attacks deal 20% increased Damage -Added Small Passive Skills also grant: +3% to Chaos Resistance -Added Small Passive Skills also grant: +2% to Elemental Resistance -1 Added Passive Skill is Lead By Example -1 Added Passive Skill is Provocateur - - - Rarity: RARE -Gale Shine -Crimson Jewel -Unique ID: 7705319d1a0bf63bfd2dfeeec0e107ef8d95f4fe17fbdf68815b0887d0f1afa3 -Item Level: 70 -Implicits: 0 -{fractured}7% increased maximum Life -17% increased Critical Strike Chance with Lightning Skills -+10% to Global Critical Strike Multiplier -+14% to Melee Critical Strike Multiplier - - - Rarity: RARE -Bramble Essence -Large Cluster Jewel -Unique ID: b5ac208d3d11677ea481f3453e35f1a646cabb7b4bbc6a1482a08485db042a54 -Item Level: 69 -LevelReq: 40 -Implicits: 3 -{crafted}Adds 8 Passive Skills -{crafted}2 Added Passive Skills are Jewel Sockets -{crafted}Added Small Passive Skills grant: 12% increased Attack Damage while holding a Shield -Added Small Passive Skills also grant: 1% increased Attack Speed -1 Added Passive Skill is Advance Guard -1 Added Passive Skill is Precise Retaliation -1 Added Passive Skill is Smite the Weak - - - Rarity: RARE -Sol Spark -Medium Cluster Jewel -Unique ID: 0030143e8dd7199ec1c7af0c49effa14f0e3a2eb2d4f0fc21c77349c4b5bdaae -Item Level: 84 -LevelReq: 54 -Implicits: 3 -{crafted}Adds 5 Passive Skills -{crafted}1 Added Passive Skill is a Jewel Socket -{crafted}Added Small Passive Skills grant: Exerted Attacks deal 20% increased Damage -Added Small Passive Skills also grant: +3 to All Attributes -1 Added Passive Skill is Provocateur -1 Added Passive Skill is Warning Call - - - Rarity: RARE -Pandemonium Glimmer -Medium Cluster Jewel -Unique ID: 432e757fa6482f31931266f5945c76490b4552399020dd6c8d62ae7d02c1395d -Item Level: 86 -LevelReq: 67 -Implicits: 4 -{crafted}Adds 5 Passive Skills -{crafted}1 Added Passive Skill is a Jewel Socket -{crafted}Added Small Passive Skills grant: Exerted Attacks deal 20% increased Damage -Overwhelm 2% Physical Damage Reduction -Added Small Passive Skills also grant: +7% to Fire Resistance -Added Small Passive Skills also grant: +2% to Lightning Resistance -1 Added Passive Skill is Haunting Shout -1 Added Passive Skill is Mob Mentality -Corrupted - - - Rarity: RARE -Bramble Ruin -Crimson Jewel -Unique ID: 2c413cb15fea655daef5d269d16ff1612f8c8326b8f94ca4c2267a3e7075e061 -Item Level: 85 -Implicits: 0 -+9% to Global Critical Strike Multiplier -+17% to Critical Strike Multiplier with One Handed Melee Weapons -7% increased maximum Life -+2 Life gained for each Enemy hit by your Attacks -Corrupted - - - Rarity: UNIQUE -Kitava's Teachings -Small Cluster Jewel -Unique ID: a9bf71a613bb826a7ba43214a9e47f736cc3fc479f9e794613b989564cbfa904 -Item Level: 73 -Implicits: 0 -Adds Disciple of Kitava -Corrupted - - - Rarity: RARE -Soul Cut -Large Cluster Jewel -Unique ID: 1b14022854ccc2851284554949c173bb9bbd62d49a54a412ff5434fce251791e -Item Level: 81 -LevelReq: 40 -Implicits: 3 -{crafted}Adds 8 Passive Skills -{crafted}2 Added Passive Skills are Jewel Sockets -{crafted}Added Small Passive Skills grant: 12% increased Physical Damage -Added Small Passive Skills also grant: +3 to Intelligence -1 Added Passive Skill is Furious Assault -1 Added Passive Skill is Iron Breaker -1 Added Passive Skill is Master the Fundamentals - - - Rarity: RARE -Eagle Sliver -Crimson Jewel -Unique ID: da54797312d94ef912f62704722457c84950ca7edf09e7edb7469c9dbce9c4f5 -Item Level: 82 -Implicits: 0 -+11% to Global Critical Strike Multiplier -+16% to Critical Strike Multiplier with One Handed Melee Weapons -6% increased maximum Life -10% increased Projectile Damage -Corrupted - - - Rarity: UNIQUE -Watcher's Eye -Prismatic Jewel -Unique ID: c9b89954dc9242248ee84b5f9a0f74f15a7c67f0356d34395c0d493777364873 -Item Level: 85 -Limited to: 1 -Implicits: 0 -6% increased maximum Energy Shield -6% increased maximum Life -5% increased maximum Mana -+28% to Critical Strike Multiplier while affected by Precision -48% increased Attack Physical Damage while using Pride - - - Rarity: UNIQUE -Hands of the High Templar -Crusader Gloves -Unique ID: 8d357b3a859e0454882e0c4130e6c66da5eb6d37727c8472e648f78229aa03ce -Item Level: 85 -Quality: 20 -Sockets: W-R-W-W -LevelReq: 66 -Implicits: 2 -Curse Enemies with Vulnerability on Hit, with 44% increased Effect -Attacks have +0.77% to Critical Strike Chance -Can be modified while Corrupted -Can have up to 5 Implicit Modifiers while Item has this Modifier -167% increased Armour and Energy Shield -12% increased maximum Life -+24% to Fire and Lightning Resistances -Corrupted - - - Rarity: UNIQUE -Paradoxica -Vaal Rapier -Unique ID: a0b72090b5d6e5d80eaaf47a3092626b8e949f8138e249770315e66c2ce0c5ff -Item Level: 83 -Quality: 48 -Sockets: G-G-R -LevelReq: 66 -Implicits: 1 -+25% to Global Critical Strike Multiplier -Attacks with this Weapon deal Double Damage -{crafted}91% increased Physical Damage -{crafted}16% increased Attack Speed -{crafted}+18% to Quality -{crafted}16% chance to Poison on Hit -Corrupted - - - Rarity: RARE -Beast Clasp -Turquoise Amulet -Unique ID: f998c984e54a12e9f21671ef9a1cafa725784a16aa20d3f2834e4bb59f23df6d -Item Level: 84 -LevelReq: 60 -Implicits: 2 -{crafted}Allocates Swift Skewering -+24 to Dexterity and Intelligence -+49 to Dexterity -Adds 14 to 27 Physical Damage to Attacks -20% increased Cold Damage -+15% to all Elemental Resistances - - - Rarity: RARE -Oblivion Cloak -Astral Plate -Unique ID: 883c8517cf572067e0aa54197388deee74333e3da0a387df83c235f661e76965 -Elder Item -Item Level: 100 -Quality: 30 -Sockets: W-W-W-W-W-W -LevelReq: 62 -Implicits: 4 -{crafted}Quality does not increase Defences -{crafted}Grants +1 to Maximum Life per 2% Quality -+12% to all Elemental Resistances -Item sells for much more to vendors -+122 to maximum Life -12% increased maximum Life -Regenerate 1.7 Life per second -+48% to Cold Resistance -Attacks have +1.17% to Critical Strike Chance -{crafted}32% chance to Avoid Elemental Ailments -{crafted}26% chance to Avoid being Stunned - - - Rarity: UNIQUE -Redblade Banner -Painted Tower Shield -Unique ID: 869845669596b94a3d02b23c6e91d262f890c61ae96bfffa08beea9660a8e6a8 -Item Level: 71 -Quality: 0 -Sockets: W W W -LevelReq: 35 -Implicits: 1 -+30 to maximum Life -93% increased Armour -+59 to maximum Life -20% increased Taunt Duration -+5% Chance to Block -50% increased Warcry Cooldown Recovery Rate -Warcries have infinite Power - - - Rarity: UNIQUE -Lion's Roar -Granite Flask -Unique ID: 192c8cbcb476f757313701cfb598049d64b65b8c731e3bd99c539baac4b0e2d9 -Item Level: 82 -Quality: 0 -LevelReq: 27 -Implicits: 0 -Adds Knockback to Melee Attacks during Flask effect -Knocks Back Enemies in an Area when you use a Flask -75% chance to cause Enemies to Flee on use -22% more Melee Physical Damage during effect - - - Rarity: RARE -Loath Road -Two-Toned Boots (Armour/Evasion) -Unique ID: 149ab64c5a5f2882a191f4fd9963b88abef84b6656080893b283a3e63a473a2d -Elder Item -Item Level: 84 -Quality: 0 -Sockets: W-B-G-G -LevelReq: 70 -Implicits: 1 -+12% to Fire and Cold Resistances -Socketed Gems are Supported by Level 20 Fortify -+42% to Fire Resistance -+41% to Lightning Resistance -30% increased Movement Speed -{crafted}+20% to Fire and Cold Resistances - - - Rarity: UNIQUE -Abyssus -Ezomyte Burgonet -Unique ID: e05ccf5cb05dfbd3510eb415159af2681966b957111be021358644f9e11f47a5 -Item Level: 73 -Quality: 20 -Sockets: R-R-R-G -LevelReq: 60 -Implicits: 1 -{crafted}General's Cry has +1 to maximum number of Mirage Warriors -+22 to all Attributes -Adds 40 to 60 Physical Damage to Attacks -+121% to Melee Critical Strike Multiplier -104% increased Armour -41% increased Physical Damage taken - - - Rarity: UNIQUE -Bottled Faith -Sulphur Flask -Unique ID: ac3558845a56bbdfe037f880e69281c9da896ffc00fb12f04d43d8716fc72411 -Item Level: 85 -Quality: 0 -LevelReq: 35 -Implicits: 1 -Creates Consecrated Ground on Use -44% increased Duration -Consecrated Ground created by this Flask has Tripled Radius -+1.79% to Critical Strike Chance against Enemies on Consecrated Ground during Effect -Consecrated Ground created during Effect applies 9% increased Damage taken to Enemies - - - Rarity: UNIQUE -The Hidden Blade -Ambusher -Unique ID: 94a61656ba3ff818d3932de4bd7806c643deb923aab04c5f574db2e94029d8a0 -Item Level: 84 -Quality: 0 -Sockets: G G G -LevelReq: 60 -Implicits: 1 -30% increased Global Critical Strike Chance -Trigger Level 20 Unseen Strike every 0.5 seconds while Phasing -+23 to Dexterity -233% increased Physical Damage -30% reduced Attack Speed while Phasing - - - Rarity: MAGIC -Ample Quicksilver Flask of Adrenaline -Unique ID: dca8161f5a90229f17e7d0500a7eadce6e4d6126c514cdb57268a5b4d2c042ee -Item Level: 42 -Quality: 0 -LevelReq: 4 -Implicits: 0 -+17 to Maximum Charges -29% increased Movement Speed during Flask effect - - - Rarity: MAGIC -Seething Divine Life Flask of Staunching -Unique ID: 65cf591c50c747bef1be3071e2b6feb16e25d6a5df698ab2830e715db7b63206 -Item Level: 70 -Quality: 0 -LevelReq: 60 -Implicits: 0 -66% reduced Amount Recovered -Instant Recovery -Immunity to Bleeding during Flask effect -Removes Bleeding on use - - - Rarity: MAGIC -Chemist's Diamond Flask of Heat -Unique ID: c7b914cd20712cc93b4e7207121bb41af113e9209e79e64edde5e790680de175 -Item Level: 54 -Quality: 0 -LevelReq: 27 -Implicits: 0 -22% reduced Charges used -Immunity to Freeze and Chill during Flask effect -Removes Freeze and Chill on use - - - Rarity: RARE -Blight Whorl -Steel Ring -Unique ID: 1bbf6988bc5ea8cdc04543f88d91a0f746aba548a0f7186ea939f394fb746827 -Item Level: 84 -LevelReq: 80 -Implicits: 2 -{crafted}Your Scout Towers have 25% increased Range -Adds 4 to 16 Physical Damage to Attacks -Adds 12 to 19 Physical Damage to Attacks -+78 to maximum Life -+9% to all Elemental Resistances -+39% to Lightning Resistance -{crafted}Channelling Skills have -3 to Total Mana Cost - - - Rarity: RARE -Blight Eye -Steel Ring -Unique ID: 241c4afd9fdad62137cb31f2a968c69f1e65fddaf619dd20bb9b31176e41b105 -Item Level: 83 -LevelReq: 80 -Implicits: 2 -{crafted}Your Scout Towers have 25% increased Range -Adds 4 to 16 Physical Damage to Attacks -+55 to Strength -+52 to Dexterity -Adds 6 to 14 Physical Damage to Attacks -+71 to maximum Life -11% increased Rarity of Items found -{crafted}+11% to all Elemental Resistances - - - Rarity: UNIQUE -The Iron Mass -Gladius -Unique ID: 44466a17300e5702c7e132e812b42e8df006493e9ce35c9368acf7f5f1a72558 -Item Level: 84 -Quality: 0 -Sockets: R -LevelReq: 60 -Implicits: 1 -40% increased Global Accuracy Rating -149% increased Physical Damage -14% increased Attack Speed -Unholy Might -22% chance to inflict Withered for 2 seconds on Hit with this Weapon -Summoned Skeleton Warriors wield a copy of this Weapon while in your Main Hand -Summoned Skeleton Warriors deal Triple Damage with this -Weapon if you've Hit with this Weapon Recently - - - Rarity: UNIQUE -Ryslatha's Coil -Studded Belt -Unique ID: 82cfd5fc6f9913353df16ff29264b0aefbb13c50b2684602ce663de625ea8929 -Item Level: 71 -LevelReq: 32 -Implicits: 1 -27% increased Stun Duration on Enemies -+30 to Strength -48% more Maximum Physical Attack Damage -36% less Minimum Physical Attack Damage -Adds 1 to 20 Physical Damage to Attacks -+83 to maximum Life -Gain 50 Life when you Stun an Enemy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]], - output = {["SpellSuppressionChanceOverCap"] = 0, -["FrenzyChargesMin"] = 0, -["EnergyShieldOnGloves"] = 69, -["HitChance"] = 99, -["LightningDotEHP"] = 38120.7632, -["CrabBarriersMax"] = 0, -["ShockAvoidChance"] = 32, -["ActiveTotemLimit"] = 1, -["AvoidColdDamageChance"] = 0, -["AnyTakenReflect"] = 0, -["InspirationCharges"] = 5, -["AbsorptionChargesMax"] = 0, -["LifePercentCost"] = 0, -["ReqInt"] = 96, -["ProjectileNotHitChance"] = 0, -["LifeCost"] = 0, -["ManaPercentCost"] = 0, -["MaxManaLeechRate"] = 134.4, -["PhysicalTakenReflectMult"] = 0.126, -["LightningLightningBaseTakenHitMult"] = 0.1782, -["SelfShockDuration"] = 100, -["ManaOnHit"] = 0, -["AfflictionChargesMax"] = 0, -["PhysicalProjectileDamageChance"] = 30, -["ManaCost"] = 18, -["SpellSuppressionEffect"] = 50, -["BloodChargesMax"] = 5, -["FireMeleeDamageChance"] = 30, -["PhysicalGuardEffectiveLife"] = 8405.4, -["ActiveTrapLimit"] = 15, -["PhysicalAegis"] = 0, -["EnergyShieldRegen"] = 0, -["LightningAegis"] = 0, -["SiphoningCharges"] = 0, -["PhysicalTakenHitMult"] = 0.126, -["ChaosDotEHP"] = 6165.7974, -["Gear:Ward"] = 0, -["LightningGuardAbsorbRate"] = 75, -["MissingLightningResist"] = 0, -["AverageBlockChance"] = 15, -["LightningGuardEffectivePool"] = 0, -["BleedDuration"] = 4.5872, -["MaxEnergyShieldLeechRate"] = 8.6, -["EnergyShieldLeechInstanceRate"] = 1.72, -["PhysicalNumberOfHits"] = 64.7059, -["ChaosTakenHit"] = 0.7128, -["CritExtraDamageReduction"] = 0, -["CurrentShock"] = 0, -["PhysicalResist"] = 12, -["ColdSpellProjectileDamageChance"] = 0, -["FireResistOver75"] = 1, -["ColdResist"] = 75, -["SpellProjectileBlockChance"] = 0, -["ColdTakenReflectMult"] = 0.1782, -["Dex"] = 224, -["TheoreticalOffensiveWarcryEffect"] = 1, -["PowerChargesMax"] = 3, -["SelfBleedDuration"] = 100, -["PhysicalDamageReduction"] = 86, -["SelfChillEffect"] = 100, -["Str"] = 422, -["SpellDodgeChanceOverCap"] = 0, -["FireProjectileDamageChance"] = 30, -["ArmourOnHelmet"] = 775, -["AttackDodgeChanceOverCap"] = 0, -["AnyGuard"] = true, -["PhysicalTakenReflect"] = 0.9002, -["MaximumScorch"] = 50, -["ShieldBlockChance"] = 30, -["EnergyShieldLeechGainRate"] = 0, -["SpellBlockChance"] = 0, -["PhysicalMindOverMatter"] = 0, -["LightningManaEffectiveLife"] = 8405.4, -["ArmourOnGloves"] = 347, -["LightningResistOver75"] = 0, -["ColdTakenReflect"] = 0.7128, -["SpellBlockChanceMax"] = 75, -["ChaosEnergyShieldBypass"] = 100, -["ManaOnHitRate"] = 0, -["DamageTakenOnBlock"] = 0, -["EvasionOnBoots"] = 126, -["BlockChanceOverCap"] = 0, -["ChallengerCharges"] = 0, -["Int"] = 96, -["ColdEnergyShieldBypass"] = 0, -["FireResistTotal"] = 117, -["FreezeAvoidChance"] = 100, -["ChaosTakenDotMult"] = 1.3632, -["AttackDodgeChance"] = 0, -["ReqDex"] = 212, -["ColdTakenHit"] = 0.7128, -["Spec:EnergyShieldInc"] = 0, -["LightningProjectileDamageChance"] = 30, -["Spec:EvasionInc"] = 24, -["Spec:ArmourInc"] = 114, -["BrutalChargesMin"] = 0, -["ChaosMindOverMatter"] = 0, -["BleedChance"] = 9, -["Armour"] = 17222, -["Spec:ManaInc"] = 0, -["Spec:LifeInc"] = 107, -["PoisonAvoidChance"] = 0, -["LightningResistTotal"] = 110, -["ExtraPoints"] = 2, -["FullDPS"] = 0, -["MirageDPS"] = 134540497.4084, -["WithImpaleDPS"] = 19730363.201, -["InterruptStunAvoidChance"] = 0, -["ImpaleDPS"] = 9151079.9833, -["ImpaleHit"] = 585837.4997, -["AverageDamage"] = 579979.1247, -["ColdTakenHitMult"] = 0.1782, -["PowerChargesMin"] = 0, -["Devotion"] = 0, -["MissingColdResist"] = 0, -["ChaosGuardAbsorbRate"] = 75, -["TotalDotDPS"] = 7829.9825, -["WithIgniteDPS"] = 10579283.2177, -["PhysicalTakenHit"] = 0.9002, -["WithPoisonDPS"] = 10579283.2177, -["CombinedAvg"] = 10579283.2177, -["CombinedDPS"] = 154268750.8585, -["TotalDot"] = 0, -["ColdGuardAbsorbRate"] = 75, -["ManaLeechGainRate"] = 134.4, -["LightningGuardAbsorb"] = 3444.4, -["FireResist"] = 76, -["RemovableFrenzyCharges"] = 3, -["ImpaleModifier"] = 1.865, -["ChaosAegis"] = 0, -["ImpaleStoredDamage"] = 17.3, -["ImpaleChance"] = 100, -["PhysicalTotalPool"] = 8491.4, -["RageCost"] = 0, -["BlockDuration"] = 0.35, -["ManaLeechPerHit"] = 67.2, -["ColdMeleeDamageChance"] = 30, -["MissingChaosResist"] = 128, -["TotemsSummoned"] = 1, -["FireTakenHit"] = 0.7128, -["BleedDPS"] = 0, -["BleedAvoidChance"] = 100, -["AverageNotHitChance"] = 0, -["EnergyShieldOnBlock"] = 0, -["StunAvoidChance"] = 26, -["FreezeChance"] = 92.2633, -["DamageReductionMax"] = 90, -["Life"] = 4961, -["DurationMod"] = 1, -["MaxLifeLeechRate"] = 992.2, -["EnduranceCharges"] = 3, -["ShockChance"] = 92.2633, -["ColdManaEffectiveLife"] = 8405.4, -["ColdTakenDotMult"] = 0.2228, -["ChaosAverageDamageChance"] = 15, -["ChaosMaximumHitTaken"] = 7707.2468, -["PhysicalTotalEHP"] = 79756.1452, -["ESCost"] = 0, -["PowerCharges"] = 3, -["ColdMindOverMatter"] = 0, -["PhysicalGuardEffectivePool"] = 0, -["OffensiveWarcryEffect"] = 1, -["ChallengerChargesMax"] = 0, -["EnergyShieldLeechInstant"] = 0, -["SpellProjectileNotHitChance"] = 0, -["LifeRegenPercent"] = 7.8, -["LightningResist"] = 75, -["PhysicalSpellProjectileDamageChance"] = 0, -["LifeLeechGainRate"] = 1028.3168, -["SpellNotHitChance"] = 0, -["LifeReservedPercent"] = 0, -["PhysicalMaximumHitTaken"] = 67376.9711, -["ManaUnreservedPercent"] = 12.5, -["ProjectileEvadeChance"] = 0, -["AbsorptionCharges"] = 0, -["ImpaleStacks"] = 5, -["ImpaleStacksMax"] = 5, -["MaxEnergyShieldLeechInstance"] = 8.6, -["HexDoomLimit"] = 30, -["PhysicalSpellDamageChance"] = 0, -["EnergyShieldLeechInstances"] = 0, -["AvoidPhysicalDamageChance"] = 0, -["BleedStacks"] = 1, -["BleedStacksMax"] = 1, -["CullMultiplier"] = 1, -["BleedDamage"] = 35917.351, -["ChaosResistTotal"] = -53, -["CrabBarriers"] = 0, -["LightningResistOverCap"] = 35, -["BleedEffMult"] = 1.7792, -["PhysicalTakenDotMult"] = 1.0763, -["BleedDotMulti"] = 1, -["TotalDotInstance"] = 0, -["ManaReservedPercent"] = 87.5, -["ManaLeechRate"] = 134.4, -["ManaLeechInstanceRate"] = 13.44, -["LightningTakenReflectMult"] = 0.1782, -["AvoidChaosDamageChance"] = 0, -["EnergyShieldLeechPerHit"] = 0, -["EnergyShieldLeechRate"] = 0, -["LifeLeechInstantRate"] = 0, -["ArmourOnWeapon 2"] = 419, -["LifeLeechRate"] = 992.2, -["LowestOfMaximumLifeAndMaximumMana"] = 672, -["ColdDotEHP"] = 38120.7632, -["EvadeChance"] = 0, -["SelfPoisonDuration"] = 100, -["EnergyShieldOnHitRate"] = 0, -["PhysicalGuardAbsorb"] = 3444.4, -["BrutalCharges"] = 0, -["EnergyShieldOnHit"] = 0, -["LifeOnHitRate"] = 36.1168, -["LifeOnHit"] = 2, -["ManaLeechInstantRate"] = 0, -["InspirationChargesMax"] = 5, -["ChaosResist"] = -53, -["ChaosGuardEffectivePool"] = 0, -["ManaLeechInstances"] = 90.292, -["SiphoningChargesMax"] = 0, -["ManaUnreserved"] = 84, -["FireTakenReflect"] = 0.7128, -["EnergyShieldLeechInstantRate"] = 0, -["EnergyShieldLeechDuration"] = 0, -["LifeLeechPerHit"] = 644.93, -["LifeLeechInstant"] = 0, -["LifeLeechInstances"] = 90.292, -["WardRechargeDelay"] = 5, -["LifeRegen"] = 388.658, -["MaxLifeLeechInstance"] = 496.1, -["SpellSuppressionEffectiveChance"] = 0, -["EnduranceChargesMin"] = 0, -["ActiveGolemLimit"] = 1, -["LifeLeechDuration"] = 5, -["TotalDPS"] = 10579283.2177, -["LifeUnreservedPercent"] = 100, -["BlockEffect"] = 100, -["ShowBlockEffect"] = true, -["CritChance"] = 92.2633, -["PreEffectiveCritChance"] = 93.1953, -["FireEnergyShieldBypass"] = 0, -["FistOfWarCooldown"] = 0, -["BlockChanceMax"] = 75, -["ExertedAttackUptimeRatio"] = 0, -["LightRadiusMod"] = 1, -["AilmentWarcryEffect"] = 1, -["RallyingHitEffect"] = 1, -["ManaRegen"] = 11.8, -["ChaosChaosBaseTakenHitMult"] = 1.0906, -["SeismicHitEffect"] = 1, -["TheoreticalMaxOffensiveWarcryEffect"] = 1, -["MaxOffensiveWarcryEffect"] = 1, -["Time"] = 0.4386, -["WithBleedDPS"] = 10587113.2002, -["Speed"] = 2.2801, -["AvoidLightningDamageChance"] = 0, -["ColdColdBaseTakenHitMult"] = 0.1782, -["SelfIgniteDuration"] = 100, -["AvoidFireDamageChance"] = 0, -["ChaosSpellProjectileDamageChance"] = 0, -["FrenzyCharges"] = 3, -["TotalCharges"] = 9, -["ChaosTakenReflectMult"] = 1.0906, -["AreaOfEffectRadius"] = 8, -["LifeReserved"] = 0, -["SpellSuppressionChance"] = 0, -["AreaOfEffectMod"] = 1.27, -["FireSpellProjectileDamageChance"] = 0, -["ActiveMineLimit"] = 15, -["ChaosTotalEHP"] = 10150.7821, -["ChaosNumberOfHits"] = 8.2353, -["LightningMeleeDamageChance"] = 30, -["EnemyCurseLimit"] = 1, -["FireNumberOfHits"] = 48.2353, -["LightningEnergyShieldBypass"] = 0, -["ColdTotalEHP"] = 56554.3575, -["ColdNumberOfHits"] = 45.8824, -["ColdTotalPool"] = 8491.4, -["LightningMindOverMatter"] = 0, -["LightningGuardEffectiveLife"] = 8405.4, -["ChaosGuardAbsorb"] = 3444.4, -["ColdGuardAbsorb"] = 3444.4, -["ColdMaximumHitTaken"] = 47650.954, -["LightningMaximumHitTaken"] = 47650.954, -["FireDotEHP"] = 39709.1283, -["PhysicalDotEHP"] = 7889.2308, -["PhysicalResistWhenHit"] = 12, -["ChaosSpellDamageChance"] = 0, -["LifeOnBlock"] = 0, -["ChaosMeleeDamageChance"] = 30, -["BlitzChargesMax"] = 0, -["FireAverageDamageChance"] = 15, -["LightningAverageDamageChance"] = 15, -["FireSpellDamageChance"] = 0, -["BloodCharges"] = 5, -["ColdAverageDamageChance"] = 15, -["ChaosGuardEffectiveLife"] = 8405.4, -["SelfFreezeDuration"] = 100, -["MovementSpeedMod"] = 2.0839, -["FireTotalPool"] = 8491.4, -["ColdProjectileDamageChance"] = 30, -["LightningSpellProjectileDamageChance"] = 0, -["LowestAttribute"] = 96, -["EnduranceChargesMax"] = 3, -["ActionSpeedMod"] = 1, -["SpellBlockChanceOverCap"] = 0, -["MeleeEvadeChance"] = 0, -["LightningSpellDamageChance"] = 0, -["ProjectileBlockChance"] = 30, -["FireTotalEHP"] = 59454.5809, -["RemovableEnduranceCharges"] = 3, -["PhysicalAverageDamageChance"] = 15, -["CritBleedDotMulti"] = 1.5, -["ColdResistOver75"] = 0, -["ChaosTotalPool"] = 8405.4, -["ChaosTakenHitMult"] = 1.0906, -["FireTakenReflectMult"] = 0.1711, -["FireTakenHitMult"] = 0.1711, -["Gear:EnergyShield"] = 69, -["FireFireBaseTakenHitMult"] = 0.1711, -["SelfShockEffect"] = 100, -["FireResistOverCap"] = 41, -["MaximumShock"] = 50, -["ManaOnBlock"] = 0, -["LightningTakenHitMult"] = 0.1782, -["StunDuration"] = 0.35, -["PhysicalMeleeDamageChance"] = 30, -["ColdResistOverCap"] = 9, -["AnyMindOverMatter"] = false, -["ManaRegenInc"] = 0, -["MissingFireResist"] = 0, -["AfflictionChargesMin"] = 0, -["LowestOfArmourAndEvasion"] = 238, -["LightningTakenReflect"] = 0.7128, -["EnergyShieldOnSpellBlock"] = 0, -["ChaosResistOver75"] = 0, -["GhostShrouds"] = 0, -["MaximumRage"] = 50, -["RemovablePowerCharges"] = 3, -["FireMindOverMatter"] = 0, -["ReqStr"] = 180, -["ColdResistTotal"] = 84, -["dontSplitEvade"] = true, -["Gear:Armour"] = 2378, -["ChaosResistOverCap"] = 0, -["LifeLeechInstanceRate"] = 128.986, -["WarcryPower"] = 50, -["EnergyShieldRechargeAppliesToEnergyShield"] = true, -["SelfBlindDuration"] = 100, -["ArmourOnBody Armour"] = 711, -["IgniteAvoidChance"] = 32, -["LifeUnreserved"] = 4961, -["AbsorptionChargesMin"] = 0, -["ColdAegis"] = 0, -["BrutalChargesMax"] = 0, -["LightningTotalEHP"] = 56554.3575, -["ChaosProjectileDamageChance"] = 30, -["ManaLeechDuration"] = 5, -["EnergyShieldRechargeDelay"] = 2, -["EnergyShieldRecoveryRateMod"] = 1, -["EnergyShieldRegenPercent"] = 0, -["CurrentScorch"] = 0, -["SelfChillDuration"] = 100, -["BlockChance"] = 30, -["FireGuardAbsorbRate"] = 75, -["MaxManaLeechInstance"] = 67.2, -["ChaosManaEffectiveLife"] = 8405.4, -["AfflictionCharges"] = 0, -["EnergyShieldRecharge"] = 28, -["TotalAttr"] = 742, -["FireAegis"] = 0, -["EffectiveMovementSpeedMod"] = 2.0839, -["Evasion"] = 238, -["Gear:Evasion"] = 126, -["Mana"] = 672, -["ChillAvoidChance"] = 100, -["AvoidProjectilesChance"] = 0, -["ColdGuardEffectiveLife"] = 8405.4, -["ColdSpellDamageChance"] = 0, -["LightningTakenDotMult"] = 0.2228, -["PhysicalEnergyShieldBypass"] = 0, -["BlitzCharges"] = 0, -["ChaosTakenReflect"] = 0.7128, -["CullPercent"] = 0, -["ColdGuardEffectivePool"] = 0, -["PhysicalGuardAbsorbRate"] = 75, -["PhysicalPhysicalBaseTakenHitMult"] = 0.126, -["FrenzyChargesMax"] = 3, -["ArmourOnBoots"] = 126, -["BlindAvoidChance"] = 0, -["FireMaximumHitTaken"] = 49636.4104, -["Ward"] = 0, -["ManaRecoveryRateMod"] = 1, -["FireGuardAbsorb"] = 3444.4, -["FireGuardEffectiveLife"] = 8405.4, -["LifeRecoveryRateMod"] = 1, -["LightningNumberOfHits"] = 45.8824, -["CritMultiplier"] = 6.25, -["ManaReserved"] = 588, -["FireManaEffectiveLife"] = 8405.4, -["AnyAegis"] = false, -["FireGuardEffectivePool"] = 0, -["AnyBypass"] = false, -["LightningTotalPool"] = 8491.4, -["SpellDodgeChance"] = 0, -["MeleeNotHitChance"] = 0, -["ManaLeechInstant"] = 0, -["PhysicalManaEffectiveLife"] = 8405.4, -["EnergyShield"] = 86, -["FireTakenDotMult"] = 0.2138, -["LightningTakenHit"] = 0.7128, -} - -} \ No newline at end of file diff --git a/spec/TestBuilds/3.13/Mirage Archer Toxic Rain.lua b/spec/TestBuilds/3.13/Mirage Archer Toxic Rain.lua deleted file mode 100644 index c23245aec39..00000000000 --- a/spec/TestBuilds/3.13/Mirage Archer Toxic Rain.lua +++ /dev/null @@ -1,1717 +0,0 @@ -return { - xml = [[ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - https://www.pathofexile.com/passive-skill-tree/AAAABAYCACpNotl1nvmktzCJ4I19tNEWvzfUoJ81kqOj_o9irH1bbIw64SaVBuc6QsLsSsibtYTFjb9cQIMJ51TIFGqM9W9NkhQJzxUOSInTUUfaO4w2h8u1SCP28NU51ElRkUfDOhNt3ahRTHaClS65Ao_6MHEwfAce2L2dqm_yz93xitQjJP2kBVVLJohuqpMf5li18j8nsNg2PWHifyski3BSEZZLeDOjD6vtP3DUrEdJE6IudvdvnhvIykoFtTH6tMVfsKZXTeM8tsgMUELyRf4Kp5uAsw== - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - https://www.pathofexile.com/passive-skill-tree/AAAABAICABzcfTWdYxR1CPRbr1VL2cYzh7XytNEqTfnoakOiAMEzPyegnzWSX5inCErIfVuv626qMpQqC9QjwGYdvnfX51QmlVNSWW23PjwFLJy4k5u1A-5FRxmKUlNNEonTUUd3B-98QYcfQQSzPV8YPNi9b_LPMh9MfwJh4rzqOdSa4HyDXwR_K5ykwzqCx70npuARLYcTMHxFnZYyl_SXdJeV6NaXBm0Z8bMi6shbwOOdrlFMFbj-CufqA3Uy0Q-rS1cki3BSkzr5M1-wjDZW-pUFrEdM_5hTdvdvniT9MfrKSgW1CGdd8p_fIXYo-k4qyAzDeY2_6-4Wvw== - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 8% increased maximum Life - Regenerate 1% of Life per second - - - 3% increased maximum Life - - - Gain 1 Endurance Charge every second if you've been Hit Recently - - - 24% increased Evasion Rating and Armour - 8% increased maximum Life - 10% chance to Intimidate Enemies for 4 seconds on Hit - - - 2% increased Cast Speed - - - 4% increased maximum Mana - - - 4% increased Skill Effect Duration - - - +1% to maximum Fire Resistance - +20% to Fire Resistance - - - 3% increased maximum Energy Shield - - - +10% to Cold Resistance - - - 5% increased Area of Effect - - - 2% increased maximum Life - - - Minions deal 80% increased Damage - - - 15% increased effect of Non-Curse Auras from your Skills - - - 12% increased Fire Damage - - - 1% Chance to Block Spell Damage - - - 5% increased maximum Energy Shield - - - 10% increased maximum Life - Regenerate 1.1% of Life per second - - - +11% to Fire Resistance - - - 3% increased effect of Non-Curse Auras from your Skills - - - 3% increased Effect of your Curses - - - 9% increased Evasion Rating - - - 5% increased Skill Effect Duration - - - 10% increased Area Damage - - - 12% increased Mana Regeneration Rate - - - 10% increased Attack Damage - - - +8% to Chaos Resistance - - - +9% to Critical Strike Multiplier - - - 2% chance to deal Double Damage - 25% increased Physical Damage - - - 3% increased maximum Life - - - 3% increased Movement Speed - - - 3% increased Cast Speed - 11% increased Projectile Damage - 5% chance to Shock - 6% chance to Ignite - - - 12% increased Spell Damage - - - 1% chance to Dodge Attack Hits - - - 7% increased Projectile Speed - - - 3% increased Attack Speed - - - 5% increased Effect of your Curses - - - 7% increased Physical Damage - - - 7% increased Armour - - - +12% to Lightning Resistance - - - 2% increased maximum Life - - - 10% increased Fire Damage - - - 11% increased Area Damage - - - +10% to Fire Resistance - - - 7% increased Area Damage - - - 7% increased Fire Damage - 6% increased maximum Mana - +11% to Lightning Resistance - - - +8% to Critical Strike Multiplier - - - 10% increased Critical Strike Chance - - - 3% increased maximum Life - - - 7% increased Spell Damage - - - 20% increased Area of Effect of Aura Skills - 15% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - +9% to Critical Strike Multiplier - - - 1% chance to Dodge Spell Hits - - - +10% to Fire Resistance - - - +8% to Critical Strike Multiplier - - - 8% increased Armour - - - 5% increased maximum Energy Shield - - - 3% increased maximum Life - - - 28% increased Cold Damage - 10% of Physical Damage Converted to Cold Damage - - - 7% increased maximum Life - 0.4% of Attack Damage Leeched as Life - - - 12% increased Area Damage - - - 7% increased Spell Damage - - - +8% to Critical Strike Multiplier - - - +14% to Fire Resistance - - - 8% increased Chaos Damage - - - 12% increased Physical Damage - - - 10% increased Lightning Damage - - - 3% increased maximum Life - - - 5% increased Area of Effect - - - 6% increased Area of Effect - - - 10% chance to gain a Frenzy Charge on Hit - - - 8% increased maximum Life - Regenerate 0.7% of Life per second - - - 9% increased Evasion Rating - - - +13% to Fire Resistance - - - +11% to Fire Resistance - - - 11% increased Fire Damage - - - 10% increased Projectile Speed - - - 7% increased Projectile Damage - - - 20% increased Area of Effect of Aura Skills - 15% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - 4% increased effect of Non-Curse Auras from your Skills - - - 3% increased Movement Speed - - - Minions deal 12% increased Damage - - - 2% increased maximum Life - - - +13% to Lightning Resistance - - - +6% to Chaos Resistance - - - +12% to Lightning Resistance - - - +12% to Fire Resistance - - - +12% to Cold Resistance - - - 10% increased Damage over Time - - - 10% increased Chaos Damage - - - 30% increased Chaos Damage - 25% chance to inflict Withered for 2 seconds on Hit - - - 27% increased Spell Damage - 43% increased Critical Strike Chance for Spells - - - +9% to Critical Strike Multiplier - - - 3% increased effect of Non-Curse Auras from your Skills - - - 12% increased Chaos Damage - - - 3% increased Movement Speed - - - 3% increased Movement Speed - - - 1% Chance to Block Spell Damage - - - 7% increased Spell Damage - - - 33% increased Fire Damage - Damage Penetrates 2% Fire Resistance - - - 9% increased Chaos Damage - - - 9% increased Fire Damage - - - 4% chance to Freeze - - - 1% Chance to Block Spell Damage - - - +9% to Critical Strike Multiplier - - - 5% increased maximum Energy Shield - - - 1% chance to Dodge Spell Hits - - - +7% to Chaos Resistance - - - 2% increased maximum Life - - - +1% to maximum Chaos Resistance - +17% to Chaos Resistance - - - 2% increased maximum Life - - - +8% to Chaos Resistance - - - 34% increased Fire Damage - Damage Penetrates 3% Fire Resistance - - - +12% to Fire Resistance - - - +12% to Cold Resistance - - - 8% increased Attack Damage - - - 4% increased maximum Life - - - 4% increased maximum Mana - - - 12% increased Chaos Damage - - - 12% increased Evasion Rating - - - - https://www.pathofexile.com/passive-skill-tree/AAAABAICACpN_EdBh7cwVeC00fnoLOnPXl-YdoJhEAbBcaE64aOKWFodvgPuWNwTbR9BDkhRR7VII_bsGAOiFAldaOjWCC4mOn_Gg9npvRHdWybowTNy037KqV3ypldN4_JFJT9W-oazjX3veha_SAQ1kv6PAF4IiW6qwcVtbAs4f_ua8SZFtz4M7UrIgsePT02S7g7YvSaIzzK1CBUgWURSKf4Km402PVltGv618hGWH0zUI-2DGGobyDlSMHyYUxmOPyfndJwCBbXWVBVDWAcajY2_yAwA7lqBM4eVBfaj - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Rarity: UNIQUE -Witchfire Brew -Stibnite Flask -Unique ID: 5686991f93a2a58594a876df7586ebe70272c3d755fbac7cf825f7ddc9b022d1 -Item Level: 78 -Quality: 0 -LevelReq: 48 -Implicits: 1 -Creates a Smoke Cloud on Use -50% increased Charges used -39% increased Damage Over Time during Flask Effect -Grants Level 21 Despair Curse Aura during Flask Effect - - - Rarity: NORMAL -Unset Ring -Elder Item -Sockets: G -LevelReq: 24 -Implicits: 1 -Has 1 Socket -Curse Enemies with Socketed Hex Curse Gem on Hit -+107% to Chaos Damage over Time Multiplier -40% increased Skill Effect Duration - - - Rarity: RARE -New Item -Thicket Bow -Shaper Item -Crafted: true -Prefix: {range:1}ChanceToGainFrenzyChargeOnKillUberShaper2_ -Prefix: {range:0.5}LocalIncreaseSocketedGemLevel1 -Prefix: {range:1}LocalIncreaseSocketedBowGemLevel2 -Suffix: {range:1}GlobalDamageOverTimeMultiplier2h3___ -Suffix: {range:0.5}MaximumFrenzyChargeUber1 -Suffix: {range:1}LocalIncreasedAttackSpeedRangedDoubleDamageUber2 -Quality: 20 -Sockets: G-G-G-G-G-G -LevelReq: 67 -Implicits: 2 -{range:1}(3-5)% increased Attack Speed -Socketed Gems are Supported by Level 10 Onslaught -+1 to Level of Socketed Gems -+2 to Level of Socketed Bow Gems -+35% to Damage over Time Multiplier -12% increased Attack Speed -+1 to Maximum Frenzy Charges -10% chance to gain a Frenzy Charge on Kill -6% chance to deal Double Damage -Corrupted - - - - Rarity: RARE -New Item -Sharktooth Arrow Quiver -Elder Item -Crafted: true -Prefix: {range:1}IncreasedLife9 -Prefix: {range:1}AreaOfEffectUber3_ -Prefix: {range:1}DelveShieldPhysicalDamageReductionRating1 -Suffix: {range:1}GlobalDamageOverTimeMultiplier1h3 -Suffix: {range:1}IncreasedAttackSpeed3 -Suffix: {range:1}FrenzyChargeOnHittingRareOrUniqueUber1 -Quality: 0 -LevelReq: 65 -Implicits: 1 -{tags:resource,life,attack}{range:1}+(3-4) Life gained for each Enemy hit by your Attacks -+18% to Damage over Time Multiplier -13% increased Attack Speed -+99 to maximum Life -15% increased Area of Effect -5% additional Physical Damage Reduction -5% chance to gain a Frenzy Charge when you Hit a Rare or Unique Enemy - - - - Rarity: RARE -New Item -Large Cluster Jewel -Crafted: true -Prefix: {range:0.5}AfflictionNotableWickedPall_ -Prefix: {range:0.5}AfflictionNotableMiseryEverlasting -Suffix: {range:0.5}AfflictionNotableUnholyGrace_ -Suffix: None -Cluster Jewel Skill: affliction_chaos_damage -Cluster Jewel Node Count: 8 -Quality: 0 -LevelReq: 40 -Implicits: 3 -{crafted}Adds 8 Passive Skills -{crafted}2 Added Passive Skills are Jewel Sockets -{crafted}Added Small Passive Skills grant: 12% increased Chaos Damage -1 Added Passive Skill is Misery Everlasting -1 Added Passive Skill is Unholy Grace -1 Added Passive Skill is Wicked Pall - - - Rarity: RARE -New Item -Medium Cluster Jewel -Crafted: true -Prefix: {range:0.5}AfflictionNotableBrushwithDeath -Prefix: {range:0.5}AfflictionNotableExposureTherapy_ -Suffix: None -Suffix: None -Cluster Jewel Skill: affliction_damage_over_time_multiplier -Cluster Jewel Node Count: 4 -Quality: 0 -LevelReq: 54 -Implicits: 3 -{crafted}Adds 4 Passive Skills -{crafted}1 Added Passive Skill is a Jewel Socket -{crafted}Added Small Passive Skills grant: +4% to Damage over Time Multiplier -1 Added Passive Skill is Brush with Death -1 Added Passive Skill is Exposure Therapy - - - Rarity: RARE -New Item -Large Cluster Jewel -Crafted: true -Prefix: {range:0.5}AfflictionNotableWickedPall_ -Prefix: {range:0.5}AfflictionNotableMiseryEverlasting -Suffix: {range:0.5}AfflictionNotableUnspeakableGifts -Suffix: None -Cluster Jewel Skill: affliction_chaos_damage -Cluster Jewel Node Count: 8 -Quality: 0 -LevelReq: 60 -Implicits: 3 -{crafted}Adds 8 Passive Skills -{crafted}2 Added Passive Skills are Jewel Sockets -{crafted}Added Small Passive Skills grant: 12% increased Chaos Damage -1 Added Passive Skill is Misery Everlasting -1 Added Passive Skill is Unspeakable Gifts -1 Added Passive Skill is Wicked Pall - - - Rarity: RARE -New Item -Small Cluster Jewel -Crafted: true -Prefix: {range:0.5}AfflictionNotableBrushwithDeath -Prefix: None -Suffix: None -Suffix: None -Cluster Jewel Skill: affliction_maximum_life -Cluster Jewel Node Count: 2 -Quality: 0 -LevelReq: 54 -Implicits: 2 -{crafted}Adds 2 Passive Skills -{crafted}Added Small Passive Skills grant: 4% increased maximum Life -1 Added Passive Skill is Brush with Death - - - Rarity: UNIQUE -Ondar's Clasp -Wrapped Mitts -Variant: Pre 1.1.0 -Variant: Current -Selected Variant: 2 -Wrapped Mitts -Quality: 20 -Sockets: G-G-G-G -LevelReq: 5 -Implicits: 1 -{range:1}(8-10)% increased Attack Speed -{variant:1}20% increased Attack Speed when on Full Life -{variant:2}30% increased Attack Speed when on Full Life -Adds 1 to 13 Lightning Damage to Attacks -{range:0.5}+(50-80) to Accuracy Rating -{variant:1}{range:0.5}(10-15)% increased Movement Speed when on Low Life -{variant:2}20% increased Movement Speed when on Low Life -Corrupted - - - - - - Rarity: RARE -New Item -Amethyst Ring -Elder Item -Crafted: true -Prefix: {range:1}IncreasedLife7 -Prefix: {range:0.5}DelveRingChaosLeech1 -Prefix: {range:0.5}DelveRingPhysicalLeech1 -Suffix: {range:1}CurseOnHitPoachersMarkNewUber2__ -Suffix: {range:1}IncreasedAttackSpeed1 -Suffix: {range:1}AllResistances5 -Quality: 0 -LevelReq: 64 -Implicits: 1 -{tags:chaos,resistance}{range:1}+(9-13)% to Chaos Resistance -Trigger Level 12 Poacher's Mark when you Hit a Rare or Unique Enemy -7% increased Attack Speed -+79 to maximum Life -+16% to all Elemental Resistances -0.2% of Physical Damage Leeched as Life -0.2% of Chaos Damage Leeched as Life - - - - Rarity: UNIQUE -Windscream -Reinforced Greaves -Variant: Pre 2.6.0 -Variant: Current -Selected Variant: 2 -Reinforced Greaves -Quality: 20 -Sockets: R-R-R-R -LevelReq: 33 -Implicits: 2 -{crafted}16% increased Attack and Cast Speed if you've Killed Recently -{range:1}(6-10)% chance to Dodge Spell Hits while moving -{range:1}(50-80)% increased Armour -{range:1}+(10-15)% to all Elemental Resistances -{variant:1}10% increased Movement Speed -{variant:2}15% increased Movement Speed -{variant:1}10% increased Elemental Damage -{variant:2}{range:1}(10-20)% increased Elemental Damage -Enemies can have 1 additional Curse -Corrupted - - - - - - - Rarity: UNIQUE -Ungil's Harmony -Turquoise Amulet -Variant: Pre 3.11.0 -Variant: Current -Selected Variant: 2 -Turquoise Amulet -LevelReq: 23 -Implicits: 1 -{range:1}(8-10)% increased Attack Speed -{variant:1}100% increased Global Critical Strike Chance -{variant:2}{range:1}(250-350)% increased Global Critical Strike Chance -{tags:life}{range:1}+(30-50) to maximum Life -{tags:mana}{range:1}+(30-50) to maximum Mana -40% increased Stun and Block Recovery -Your Critical Strikes do not deal extra Damage -Corrupted - - - - - - - Rarity: MAGIC -Alchemist's Sulphur Flask of Acceleration -Crafted: true -Prefix: {range:0.5}FlaskEffectReducedDuration1 -Suffix: {range:1}FlaskBuffAttackSpeedWhileHealing1 -Quality: 20 -LevelReq: 35 -Implicits: 1 -{tags:flask}Creates Consecrated Ground on Use -12% increased Attack Speed during Flask effect -25% increased effect -33% reduced Duration - - - Rarity: RARE -New Item -Lion Pelt -Hunter Item -Crafted: true -Prefix: {range:1}IncreasedLife9 -Prefix: {range:1}LocalBaseEvasionRatingAndLife3 -Prefix: {range:1}LocalIncreasedEvasionRatingPercent7 -Suffix: {range:1}EnemyChaosResistanceAuraInfluence1_ -Suffix: {range:1}LightningResist8 -Suffix: {range:1}ColdResist8 -CatalystQuality: 20 -Quality: 20 -Sockets: G-G-G-G -LevelReq: 70 -Implicits: 3 -{crafted}Toxic Rain deals 40% increased Damage -{range:1}(4-6)% increased maximum Life -{range:1}Regenerate (1.6-2)% of Life per second -+95 to Evasion Rating -100% increased Evasion Rating -+132 to maximum Life -+48% to Cold Resistance -+48% to Lightning Resistance --9% to Chaos Resistance -Nearby Enemies have -9% to Chaos Resistance -Corrupted - - - - - Rarity: RARE -New Item -Zodiac Leather -Crafted: true -Prefix: {range:1}LocalBaseEvasionRatingAndLife4 -Prefix: {range:1}IncreasedLife12 -Prefix: {range:1}LocalIncreasedEvasionRatingPercent8 -Suffix: {range:1}LightningResist8 -Suffix: {range:1}FireResist8 -Suffix: {range:1}ColdResist8 -Quality: 20 -Sockets: G-G-G-G-G-G -LevelReq: 68 -Implicits: 2 -+1% to all maximum Resistances -{range:1}(40-50)% increased Damage -+120 to Evasion Rating -110% increased Evasion Rating -+167 to maximum Life -+48% to Fire Resistance -+48% to Cold Resistance -+48% to Lightning Resistance -Corrupted - - - - Rarity: RARE -New Item -Micro-Distillery Belt -Crafted: true -Prefix: {range:1}DelveJewelryChaosDamage1 -Prefix: {range:1}IncreasedLife9 -Prefix: {range:1}IncreasedPhysicalDamageReductionRating8_ -Suffix: {range:1}FireResist8 -Suffix: {range:1}ChaosResist6 -Suffix: {range:1}Strength10 -Quality: 0 -LevelReq: 68 -Implicits: 2 -Flasks applied to you have 20% increased Effect -Can't use Flask in Fifth Slot -+60 to Strength -30% increased Chaos Damage -+540 to Armour -+99 to maximum Life -+48% to Fire Resistance -+35% to Chaos Resistance - - - Rarity: RARE -New Item -Lapis Amulet -Elder Item -Crafted: true -Prefix: {range:1}DelveJewelryChaosDamage1 -Prefix: {range:1}AreaOfEffectUber3_ -Prefix: {range:1}IncreasedLife8 -Suffix: {range:1}ChaosNonAilmentDamageOverTimeMultiplierUber2 -Suffix: {range:1}IncreasedAttackSpeedAmuletUber1 -Suffix: {range:1}IncreasedAccuracyNew5_ -Quality: 0 -LevelReq: 65 -Implicits: 3 -{crafted}Allocates Corruption -{range:1}(8-10)% increased Attack Speed -{range:1}Malevolence has (15-20)% increased Aura Effect -+16% to Chaos Damage over Time Multiplier -30% increased Chaos Damage -13% increased Attack Speed -+480 to Accuracy Rating -+89 to maximum Life -15% increased Area of Effect -Corrupted - - - - - Rarity: MAGIC -Alchemist's Quartz Flask of Grounding -Crafted: true -Prefix: {range:0.5}FlaskEffectReducedDuration1 -Suffix: {range:0.5}FlaskRemovesShock1 -Quality: 20 -LevelReq: 27 -Implicits: 0 -Immunity to Shock during Flask effect -Removes Shock on use -25% increased effect -33% reduced Duration - - - Rarity: UNIQUE -The Writhing Jar -Hallowed Hybrid Flask -Quality: 20 -LevelReq: 60 -Implicits: 0 -{range:0.5}(75-65)% reduced Amount Recovered -Instant Recovery -2 Enemy Writhing Worms escape the Flask when used -{range:0.5}(20-10)% reduced Charges used - - - - - Rarity: RARE -New Item -Medium Cluster Jewel -Crafted: true -Prefix: {range:0.5}AfflictionNotableBrushwithDeath -Prefix: {range:0.5}AfflictionNotableExposureTherapy_ -Suffix: None -Suffix: None -Cluster Jewel Skill: affliction_chaos_damage_over_time_multiplier -Cluster Jewel Node Count: 6 -Quality: 0 -LevelReq: 54 -Implicits: 3 -{crafted}Adds 6 Passive Skills -{crafted}1 Added Passive Skill is a Jewel Socket -{crafted}Added Small Passive Skills grant: +4% to Chaos Damage over Time Multiplier -1 Added Passive Skill is Brush with Death -1 Added Passive Skill is Exposure Therapy - - - Rarity: RARE -New Item -Medium Cluster Jewel -Crafted: true -Prefix: {range:0.5}AfflictionNotableBrushwithDeath -Prefix: {range:0.5}AfflictionNotableExposureTherapy_ -Suffix: None -Suffix: None -Cluster Jewel Skill: affliction_chaos_damage_over_time_multiplier -Cluster Jewel Node Count: 5 -Quality: 0 -LevelReq: 54 -Implicits: 3 -{crafted}Adds 5 Passive Skills -{crafted}1 Added Passive Skill is a Jewel Socket -{crafted}Added Small Passive Skills grant: +4% to Chaos Damage over Time Multiplier -1 Added Passive Skill is Brush with Death -1 Added Passive Skill is Exposure Therapy - - - Rarity: RARE -New Item -Cobalt Jewel -Crafted: true -Prefix: {range:1}PercentIncreasedLifeJewel -Prefix: {range:1}ChaosDamageJewel -Suffix: {range:1}DamageOverTimeJewel -Suffix: {range:1}JewelChaosNonAilmentDamageOverTimeMultiplier2 -Quality: 0 -LevelReq: 0 -Implicits: 0 -12% increased Damage over Time -+4% to Chaos Damage over Time Multiplier -13% increased Chaos Damage -7% increased maximum Life - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]], - output = {["SpellSuppressionChanceOverCap"] = 0, -["FrenzyChargesMin"] = 0, -["EnergyShieldOnGloves"] = 4, -["HitChance"] = 91, -["LightningDotEHP"] = 33673.7113, -["CrabBarriersMax"] = 0, -["BlockEffect"] = 100, -["ActiveTotemLimit"] = 1, -["AvoidColdDamageChance"] = 0, -["PierceCount"] = 0, -["AnyTakenReflect"] = 0, -["InspirationCharges"] = 5, -["AbsorptionChargesMax"] = 0, -["LifePercentCost"] = 0, -["ReqInt"] = 103, -["ProjectileNotHitChance"] = 90.76, -["LifeCost"] = 0, -["ManaPercentCost"] = 0, -["EvasionOnGloves"] = 13, -["MaxManaLeechRate"] = 148.2, -["PhysicalTakenReflectMult"] = 0.4558, -["LightningLightningBaseTakenHitMult"] = 0.1243, -["SelfShockDuration"] = 70, -["ManaOnHit"] = 33, -["AfflictionChargesMax"] = 0, -["PhysicalProjectileDamageChance"] = 0, -["ManaCost"] = 48, -["SpellSuppressionEffect"] = 50, -["BloodChargesMax"] = 5, -["FireMeleeDamageChance"] = 0, -["PhysicalGuardEffectiveLife"] = 3974, -["ActiveTrapLimit"] = 15, -["PhysicalAegis"] = 0, -["EnergyShieldRegen"] = 0, -["LightningAegis"] = 0, -["SiphoningCharges"] = 0, -["PhysicalTakenHitMult"] = 0.4558, -["ChaosDotEHP"] = 5213.1707, -["ReqStr"] = 114, -["LightningGuardAbsorbRate"] = 0, -["MissingLightningResist"] = 0, -["AverageBlockChance"] = 0, -["LightningGuardEffectivePool"] = 0, -["MaxEnergyShieldLeechRate"] = 0.3, -["EnergyShieldLeechInstanceRate"] = 0.06, -["PhysicalNumberOfHits"] = 27.9525, -["ChaosTakenHit"] = 0.665, -["FireFireBaseTakenHitMult"] = 0.1243, -["CurrentShock"] = 0, -["PhysicalResist"] = 5, -["ColdSpellProjectileDamageChance"] = 0, -["FireResistOver75"] = 1, -["ColdResist"] = 76, -["SpellProjectileBlockChance"] = 0, -["ColdTakenReflectMult"] = 0.1243, -["Dex"] = 262, -["TheoreticalOffensiveWarcryEffect"] = 1, -["PowerChargesMax"] = 3, -["SelfBleedDuration"] = 100, -["PhysicalDamageReduction"] = 12, -["SelfChillEffect"] = 100, -["Str"] = 124, -["SpellDodgeChanceOverCap"] = 0, -["FireProjectileDamageChance"] = 0, -["LightningSpellProjectileDamageChance"] = 10, -["AttackDodgeChanceOverCap"] = 0, -["AnyGuard"] = false, -["PhysicalTakenReflect"] = 0.518, -["MaximumScorch"] = 50, -["ShieldBlockChance"] = 0, -["EnergyShieldLeechGainRate"] = 0.3, -["SpellBlockChance"] = 0, -["PhysicalMindOverMatter"] = 0, -["LightningManaEffectiveLife"] = 3974, -["ManaLeechInstances"] = 0, -["LightningResistOver75"] = 1, -["ColdTakenReflect"] = 0.518, -["SpellBlockChanceMax"] = 75, -["ChaosEnergyShieldBypass"] = 100, -["ManaOnHitRate"] = 922.8099, -["DamageTakenOnBlock"] = 0, -["EnergyShieldRechargeDelay"] = 2, -["BlockChanceOverCap"] = 0, -["ChallengerCharges"] = 0, -["Int"] = 104, -["ColdEnergyShieldBypass"] = 0, -["FireResistTotal"] = 77, -["FreezeAvoidChance"] = 0, -["ChaosTakenHitMult"] = 0.8046, -["AttackDodgeChance"] = 72, -["ReqDex"] = 197, -["ColdTakenHit"] = 0.518, -["LightningProjectileDamageChance"] = 10, -["BrutalChargesMin"] = 0, -["ChaosMindOverMatter"] = 0, -["Armour"] = 470, -["PoisonAvoidChance"] = 0, -["LightningResistTotal"] = 77, -["Spec:EnergyShieldInc"] = 0, -["InterruptStunAvoidChance"] = 0, -["Spec:EvasionInc"] = 157, -["Spec:ArmourInc"] = 24, -["AverageDamage"] = 2468.3806, -["ColdTakenHitMult"] = 0.1243, -["PowerChargesMin"] = 0, -["Devotion"] = 0, -["MissingColdResist"] = 0, -["ChaosGuardAbsorbRate"] = 0, -["Spec:ManaInc"] = 8, -["Spec:LifeInc"] = 86, -["PhysicalTakenHit"] = 0.518, -["ExtraPoints"] = 2, -["FullDPS"] = 0, -["MirageDPS"] = 13385830.3612, -["TotalDotDPS"] = 11807832.8408, -["ColdGuardAbsorbRate"] = 0, -["RageCost"] = 0, -["WithIgniteDPS"] = 75852.3487, -["FireResist"] = 76, -["RemovableFrenzyCharges"] = 4, -["WithPoisonDPS"] = 75852.3487, -["ChaosAegis"] = 0, -["WithDotDPS"] = 11883685.1895, -["CombinedAvg"] = 75852.3487, -["PhysicalTotalPool"] = 3977, -["CombinedDPS"] = 25269515.5507, -["BlockDuration"] = 0.35, -["ManaLeechPerHit"] = 0, -["TotalDot"] = 11807832.8408, -["MissingChaosResist"] = 97, -["ChaosDot"] = 122372.4461, -["TotemsSummoned"] = 1, -["FireTakenHit"] = 0.518, -["ChaosDotEffMult"] = 1.5842, -["BleedAvoidChance"] = 0, -["AverageNotHitChance"] = 71.38, -["ManaLeechGainRate"] = 922.8099, -["EnergyShieldOnBlock"] = 0, -["StunAvoidChance"] = 0, -["EvadeChance"] = 67, -["Life"] = 3974, -["DurationMod"] = 3.14, -["ImpaleChance"] = 0, -["EnduranceCharges"] = 0, -["ChainRemaining"] = 0, -["AreaOfEffectMod"] = 1.5, -["ColdTakenDotMult"] = 0.1181, -["ChaosAverageDamageChance"] = 0, -["FireAverageDamageChance"] = 0, -["ChaosMaximumHitTaken"] = 4938.7933, -["PhysicalTotalEHP"] = 34454.0872, -["ESCost"] = 0, -["FreezeChance"] = 4.55, -["ColdMindOverMatter"] = 0, -["PhysicalGuardEffectivePool"] = 0, -["EnergyShieldOnSpellBlock"] = 0, -["MaximumShock"] = 50, -["ShockChance"] = 4.55, -["EnergyShieldLeechInstant"] = 0, -["SpellProjectileNotHitChance"] = 52, -["LifeRegenPercent"] = 9.4, -["LightningResist"] = 76, -["PhysicalSpellProjectileDamageChance"] = 0, -["LifeLeechGainRate"] = 2053.2523, -["SpellNotHitChance"] = 52, -["LifeReservedPercent"] = 0, -["PhysicalMaximumHitTaken"] = 8724.5525, -["ColdManaEffectiveLife"] = 3974, -["ManaUnreservedPercent"] = 19.2982, -["ProjectileEvadeChance"] = 67, -["AbsorptionCharges"] = 0, -["MaxEnergyShieldLeechInstance"] = 0.3, -["HexDoomLimit"] = 30, -["PhysicalSpellDamageChance"] = 0, -["EnergyShieldLeechInstances"] = 139.8197, -["AvoidPhysicalDamageChance"] = 0, -["ColdResistOverCap"] = 1, -["ProjectileCount"] = 5, -["CullMultiplier"] = 1, -["Speed"] = 6.1459, -["ChaosResistTotal"] = -21, -["CrabBarriers"] = 0, -["LightningResistOverCap"] = 1, -["TotalDotInstance"] = 122372.4461, -["LightningTotalPool"] = 3977, -["ManaLeechRate"] = 0, -["ManaLeechInstanceRate"] = 14.82, -["LightningTakenReflectMult"] = 0.1243, -["AvoidChaosDamageChance"] = 0, -["EnergyShieldLeechPerHit"] = 0.3, -["EnergyShieldLeechRate"] = 0.3, -["LifeLeechDuration"] = 0.0683, -["LifeLeechRate"] = 151.7047, -["dontSplitEvade"] = true, -["LowestOfMaximumLifeAndMaximumMana"] = 741, -["ColdDotEHP"] = 33673.7113, -["EnergyShieldOnHitRate"] = 0, -["SelfPoisonDuration"] = 100, -["EnergyShieldOnHit"] = 0, -["LifeOnHitRate"] = 1901.5476, -["BrutalCharges"] = 0, -["LifeOnHit"] = 68, -["ManaLeechInstantRate"] = 0, -["LifeRegen"] = 373.556, -["ManaRecoveryRateMod"] = 1, -["InspirationChargesMax"] = 5, -["ChaosResist"] = -21, -["EnergyShieldLeechInstantRate"] = 0, -["EnergyShieldLeechDuration"] = 5, -["LifeLeechInstantRate"] = 0, -["ManaUnreserved"] = 143, -["FireTakenReflect"] = 0.518, -["LifeLeechInstant"] = 0, -["LifeLeechInstances"] = 1.9087, -["LifeLeechPerHit"] = 5.425, -["TotalDPS"] = 75852.3487, -["RemovablePowerCharges"] = 0, -["WardRechargeDelay"] = 5, -["FireTakenReflectMult"] = 0.1243, -["MaxLifeLeechInstance"] = 397.4, -["SpellSuppressionEffectiveChance"] = 0, -["EnduranceChargesMin"] = 0, -["ActiveGolemLimit"] = 1, -["CritChance"] = 4.55, -["PreEffectiveCritChance"] = 5, -["LifeUnreservedPercent"] = 100, -["LightningTakenDotMult"] = 0.1181, -["ShowBlockEffect"] = true, -["FistOfWarCooldown"] = 0, -["ExertedAttackUptimeRatio"] = 0, -["AilmentWarcryEffect"] = 1, -["RallyingHitEffect"] = 1, -["BlockChanceMax"] = 75, -["SeismicHitEffect"] = 1, -["LightRadiusMod"] = 1, -["TheoreticalMaxOffensiveWarcryEffect"] = 1, -["MaxOffensiveWarcryEffect"] = 1, -["ManaRegen"] = 65.6, -["ChaosChaosBaseTakenHitMult"] = 0.8046, -["OffensiveWarcryEffect"] = 1, -["Time"] = 0.1627, -["WithBleedDPS"] = 75852.3487, -["Duration"] = 3.14, -["AvoidLightningDamageChance"] = 10, -["AreaOfEffectRadius"] = 21, -["ColdColdBaseTakenHitMult"] = 0.1243, -["SelfIgniteDuration"] = 100, -["AvoidFireDamageChance"] = 0, -["ChaosSpellProjectileDamageChance"] = 0, -["FrenzyCharges"] = 4, -["TotalCharges"] = 4, -["ChaosTakenReflectMult"] = 0.8046, -["ProjectileSpeedMod"] = 1.4, -["LifeReserved"] = 0, -["SpellSuppressionChance"] = 0, -["PierceCountString"] = "Cannot pierce", -["FireSpellProjectileDamageChance"] = 0, -["ForkCountString"] = "0", -["Chain"] = 0, -["ChainMaxString"] = 0, -["ChainMax"] = 0, -["EnemyCurseLimit"] = 3, -["ActiveMineLimit"] = 15, -["LightningEnergyShieldBypass"] = 0, -["ChaosTotalEHP"] = 21533.8045, -["ChaosNumberOfHits"] = 17.4703, -["ColdTotalPool"] = 3977, -["LightningMindOverMatter"] = 0, -["FrenzyChargesMax"] = 4, -["FireNumberOfHits"] = 90.8456, -["ColdTotalEHP"] = 111975.7835, -["ColdNumberOfHits"] = 90.8456, -["BlindEffectMod"] = 100, -["FireGuardEffectiveLife"] = 3974, -["FireEnergyShieldBypass"] = 0, -["PhysicalResistWhenHit"] = 5, -["ColdMaximumHitTaken"] = 31990.0257, -["LightningMaximumHitTaken"] = 31990.0257, -["FireDotEHP"] = 33673.7113, -["BlitzChargesMax"] = 0, -["PhysicalDotEHP"] = 8507.0429, -["LightningAverageDamageChance"] = 10, -["ChaosSpellDamageChance"] = 0, -["BloodCharges"] = 5, -["TotalAttr"] = 490, -["ChaosGuardEffectiveLife"] = 3974, -["ChaosMeleeDamageChance"] = 0, -["MovementSpeedMod"] = 1.93, -["FireTotalPool"] = 3977, -["ColdProjectileDamageChance"] = 0, -["FireSpellDamageChance"] = 0, -["LowestAttribute"] = 104, -["EnduranceChargesMax"] = 3, -["ActionSpeedMod"] = 1.2, -["SpellBlockChanceOverCap"] = 0, -["MeleeEvadeChance"] = 67, -["ColdAverageDamageChance"] = 0, -["ProjectileBlockChance"] = 0, -["FireTotalEHP"] = 111975.7835, -["RemovableEnduranceCharges"] = 0, -["ColdMeleeDamageChance"] = 0, -["LightningSpellDamageChance"] = 10, -["ChaosGuardEffectivePool"] = 0, -["LightningMeleeDamageChance"] = 10, -["PhysicalAverageDamageChance"] = 0, -["MissingFireResist"] = 0, -["FireResistOverCap"] = 1, -["Gear:EnergyShield"] = 4, -["ChallengerChargesMax"] = 0, -["SelfShockEffect"] = 70, -["ManaReservedPercent"] = 80.7018, -["PhysicalTakenDotMult"] = 0.4675, -["ChaosTakenDotMult"] = 0.7623, -["LightningTakenHitMult"] = 0.1243, -["StunDuration"] = 0.35, -["PhysicalMeleeDamageChance"] = 0, -["DamageReductionMax"] = 90, -["AnyMindOverMatter"] = false, -["ManaRegenInc"] = 60, -["LowestOfArmourAndEvasion"] = 470, -["AfflictionChargesMin"] = 0, -["Gear:Ward"] = 0, -["LightningTakenReflect"] = 0.518, -["FireTakenHitMult"] = 0.1243, -["ChaosResistOver75"] = 0, -["SiphoningChargesMax"] = 0, -["CritExtraDamageReduction"] = 0, -["PowerCharges"] = 0, -["FireMindOverMatter"] = 0, -["ColdResistTotal"] = 77, -["AbsorptionChargesMin"] = 0, -["ChaosResistOverCap"] = 0, -["PhysicalEnergyShieldBypass"] = 0, -["ColdResistOver75"] = 1, -["LifeLeechInstanceRate"] = 79.48, -["ManaOnBlock"] = 0, -["EnergyShieldRechargeAppliesToEnergyShield"] = true, -["WarcryPower"] = 20, -["BlitzCharges"] = 0, -["IgniteAvoidChance"] = 0, -["ChaosTotalPool"] = 3974, -["LifeOnBlock"] = 0, -["PhysicalGuardAbsorbRate"] = 0, -["BrutalChargesMax"] = 0, -["LightningTotalEHP"] = 124417.5372, -["ChaosProjectileDamageChance"] = 0, -["ManaLeechDuration"] = 0, -["LifeUnreserved"] = 3974, -["EnergyShieldRecoveryRateMod"] = 1, -["EnergyShieldRegenPercent"] = 0, -["CurrentScorch"] = 0, -["SelfChillDuration"] = 100, -["BlockChance"] = 0, -["FireGuardAbsorbRate"] = 0, -["MaxManaLeechInstance"] = 74.1, -["ChaosManaEffectiveLife"] = 3974, -["AfflictionCharges"] = 0, -["EnergyShieldRecharge"] = 1, -["EvasionOnBody Armour"] = 2240, -["FireAegis"] = 0, -["Gear:Armour"] = 218, -["Evasion"] = 13460, -["Gear:Evasion"] = 3298, -["Mana"] = 741, -["EffectiveMovementSpeedMod"] = 2.316, -["AvoidProjectilesChance"] = 0, -["ColdGuardEffectiveLife"] = 3974, -["ColdSpellDamageChance"] = 0, -["ColdAegis"] = 0, -["SelfFreezeDuration"] = 100, -["MaxLifeLeechRate"] = 794.8, -["ChaosTakenReflect"] = 0.665, -["CullPercent"] = 0, -["ColdGuardEffectivePool"] = 0, -["GhostShrouds"] = 0, -["PhysicalPhysicalBaseTakenHitMult"] = 0.4558, -["EvasionOnHelmet"] = 1045, -["ArmourOnBoots"] = 218, -["BlindAvoidChance"] = 0, -["FireMaximumHitTaken"] = 31990.0257, -["Ward"] = 0, -["ChillAvoidChance"] = 0, -["SelfBlindDuration"] = 100, -["LightningGuardEffectiveLife"] = 3974, -["LifeRecoveryRateMod"] = 1, -["LightningNumberOfHits"] = 100.9395, -["CritMultiplier"] = 1.5, -["ManaReserved"] = 598, -["FireManaEffectiveLife"] = 3974, -["ShockAvoidChance"] = 100, -["AnyAegis"] = false, -["AnyBypass"] = false, -["FireGuardEffectivePool"] = 0, -["SpellDodgeChance"] = 52, -["MeleeNotHitChance"] = 90.76, -["ManaLeechInstant"] = 0, -["PhysicalManaEffectiveLife"] = 3974, -["EnergyShield"] = 3, -["FireTakenDotMult"] = 0.1181, -["LightningTakenHit"] = 0.518, -} - -} \ No newline at end of file diff --git a/spec/TestBuilds/3.13/OccVortex.lua b/spec/TestBuilds/3.13/OccVortex.lua deleted file mode 100644 index 93d1c0e35a3..00000000000 --- a/spec/TestBuilds/3.13/OccVortex.lua +++ /dev/null @@ -1,1064 +0,0 @@ -return { - xml = [[ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - https://www.pathofexile.com/passive-skill-tree/AAAABAMBABzcEFiexAj0tzCvm7zq73x-WXaCwGaYrTrhj6Yi9LiT74hUR-_roS8TbR9BBLM9X1VLjDbjVrVISVGRB0J618-VLhQJvopFnX_Gl_QaOIKbBAekBQ18ug4RLTLRK5ph4jwFUrJd8lJTpldN44IQ6-6TJ0Srpr4igWpDogA1kvDVbAsG57c-TC0snDD4gsfwH9Wm0eR8g1ZIJohMs0mxaPKP-o48Bx6PGqcIl5XQ0FXGg9vyRY2Crv862KjqKPrbeg5IEQ86WFZKrJj-jxdU_goRlvnokFX5N2nYbRl88N-wmFNTUtAf2CRVrprgU9RFR58BJy9XyX6hyAxBh56hJpV6cNi9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Rarity: RARE -Loath Sanctuary -Vaal Spirit Shield -Unique ID: fc24691eb70b5a54708e71b8142ebbbc86143ec938445222927b525295777c27 -Item Level: 83 -Quality: 0 -Sockets: B-B-B -LevelReq: 70 -Implicits: 1 -9% increased Spell Damage -+54 to Intelligence -30% increased Energy Shield -+87 to maximum Life -+1 to Level of all Cold Spell Skill Gems -+11% to all Elemental Resistances -+43% to Cold Resistance -Corrupted - - - Rarity: RARE -Apocalypse Noose -Citrine Amulet -Unique ID: f6eb3e5726a37508693267904e020215c25f9267e1fe4df45f2455e2220808c9 -Item Level: 83 -LevelReq: 59 -Implicits: 2 -{crafted}Allocates Prodigal Perfection -+16 to Strength and Dexterity -+43 to Strength -+44 to maximum Energy Shield -+9% to all Elemental Resistances -+11% to Fire Resistance -{crafted}+46 to maximum Life - - - Rarity: RARE -Maelstrom Cry -Imbued Wand -Unique ID: ced098a69068af80586640953702e39c51e8ab027e80b7b3a9097b446b93cc06 -Item Level: 71 -Quality: 0 -Sockets: B-B-B -LevelReq: 70 -Implicits: 1 -37% increased Spell Damage -+9% to Damage over Time Multiplier -Adds 8 to 12 Fire Damage to Spells -5% increased Cast Speed -+1 to Level of all Cold Spell Skill Gems -+6 Life gained on Kill -{crafted}+19% to Cold Damage over Time Multiplier - - - Rarity: RARE -Kraken Snare -Studded Belt -Unique ID: 2165cbcab4ec4a110e9cbec3c6d71e96767fdc39acf5849465e0623b95fb4032 -Item Level: 75 -LevelReq: 64 -Implicits: 1 -23% increased Stun Duration on Enemies -+317 to Armour -+46 to maximum Energy Shield -+92 to maximum Life -+29% to Chaos Resistance -{crafted}+14% to Lightning and Chaos Resistances - - - Rarity: RARE -Hate Band -Paua Ring -Unique ID: 46e05e600e119a447a18a720e9e49cf1132316c9125b7ad434971194b11d7182 -Item Level: 72 -LevelReq: 64 -Implicits: 1 -+29 to maximum Mana -+14 to all Attributes -+68 to Evasion Rating -+31 to maximum Energy Shield -+78 to maximum Life -+41% to Lightning Resistance -{crafted}+13% to Fire and Chaos Resistances - - - Rarity: RARE -Gloom Hold -Coral Ring -Unique ID: efc86ac7b5df717bfdbaea47dd45f77c40526efae46a3900b62c776bb4d6e160 -Item Level: 63 -LevelReq: 64 -Implicits: 1 -+30 to maximum Life -+7 to maximum Energy Shield -+78 to maximum Life -Regenerate 13.4 Life per second -+23 to maximum Mana -+23% to Cold Resistance -{crafted}+15% to Fire and Chaos Resistances - - - Rarity: RARE -Woe Caress -Fingerless Silk Gloves -Unique ID: 281a01ce242357b1e05cc57bfbee1cbb543a49f582b2aa4b4b432efcb4506270 -Item Level: 78 -Quality: 0 -Sockets: R-G-B-B -LevelReq: 70 -Implicits: 1 -16% increased Spell Damage -Adds 1 to 23 Lightning Damage to Attacks -+92 to maximum Life -+24% to Fire Resistance -+2 Life gained for each Enemy hit by your Attacks -{crafted}+15% to Fire and Chaos Resistances - - - Rarity: RARE -Invasion Road -Hydrascale Boots -Unique ID: 7fca9e5aeb030c8de363c489795235118fa08ffd60e0b0805509be8864893d09 -Item Level: 80 -Quality: 20 -Sockets: G-R-R-G -LevelReq: 70 -Implicits: 0 -+11 to Dexterity -47% increased Armour and Evasion -+88 to maximum Life -+27% to Chaos Resistance -30% increased Movement Speed -{crafted}+15% to Fire and Chaos Resistances - - - Rarity: RARE -Gale Ward -Quilted Jacket -Unique ID: dafc394c025c87f7df806c8c92c938c8125b923c3db138e39f82e8503e932a50 -Item Level: 61 -Quality: 20 -Sockets: G-B-G-B-B-B -LevelReq: 72 -Implicits: 0 -32% reduced Attribute Requirements -+124 to maximum Life -+58 to maximum Mana -+33% to Cold Resistance -+40% to Lightning Resistance -Reflects 10 Physical Damage to Melee Attackers - - - Rarity: UNIQUE -Heretic's Veil -Deicide Mask -Unique ID: 9441019ae9c688a0c2be333c1c14d036ee380552ff7b1aa9302da663729aa481 -Item Level: 70 -Quality: 20 -Sockets: R-B-G-B -LevelReq: 67 -Implicits: 1 -{crafted}24% increased Earthquake Area of Effect -+1 to Level of Socketed Curse Gems -Socketed Gems are Supported by Level 22 Blasphemy -Socketed Curse Gems have 12% reduced Mana Reservation -110% increased Evasion and Energy Shield -+44 to maximum Energy Shield - - - Rarity: MAGIC -Perpetual Quicksilver Flask of Staunching -Unique ID: eaed046cc0971c1090c2146e62ef5b9443b8cbab6b7adceaf0a5e6d5dea722c7 -Item Level: 3 -Quality: 0 -LevelReq: 6 -Implicits: 0 -31% increased Charge Recovery -Immunity to Bleeding during Flask effect -Removes Bleeding on use - - - Rarity: MAGIC -Chemist's Granite Flask of Heat -Unique ID: 9267e88908433221dd05de9fcc775d17d157db91cd8333aa36bca2cd2d7bdaa5 -Item Level: 54 -Quality: 20 -LevelReq: 27 -Implicits: 0 -21% reduced Charges used -Immunity to Freeze and Chill during Flask effect -Removes Freeze and Chill on use - - - Rarity: MAGIC -Perpetual Silver Flask of Curing -Unique ID: d5deeb09581ef0ce0d16f4a50014148dde90a9290c5de94d113bfcb3133f7293 -Item Level: 31 -Quality: 0 -LevelReq: 22 -Implicits: 0 -25% increased Charge Recovery -Immune to Poison during Flask Effect -Removes Poison on use - - - Rarity: MAGIC -Bubbling Eternal Life Flask of Acceleration -Unique ID: 2d887378e1162109008ca16d742df9828074f9901adfd8ccd69503c1aa36d391 -Item Level: 65 -Quality: 0 -LevelReq: 65 -Implicits: 0 -50% reduced Amount Recovered -135% increased Recovery rate -50% of Recovery applied Instantly -11% increased Attack Speed during Flask effect - - - Rarity: MAGIC -Enduring Divine Mana Flask of Warding -Unique ID: 02765758e562eb2fad64ec7f02e23d8a2d911bed4a7c72d38e17ec0cc8b20253 -Item Level: 73 -Quality: 20 -LevelReq: 60 -Implicits: 0 -30% reduced Amount Recovered -Immune to Curses during Flask effect -Removes Curses on use -30% reduced Duration -Flask Effect is not removed at Full Mana -Flask Effect does not Queue - - - Rarity: RARE -Cataclysm Stone -Cobalt Jewel -Unique ID: 949f96690b56595beceb512b5d9977d4fffd742690bc631defc0187caa6d8640 -Item Level: 72 -Implicits: 0 -+4% to Cold Damage over Time Multiplier -7% increased maximum Life -3% reduced Mana Cost of Skills - - - Rarity: RARE -Pandemonium Joy -Viridian Jewel -Unique ID: 8ff6536191b464f5299f5cb13f9dd5c072df47205015bd9970562bfbd2a6ec00 -Item Level: 71 -Implicits: 1 -1% of Damage taken Recouped as Mana -+3% to Cold Damage over Time Multiplier -6% increased maximum Life -13% increased Mana Regeneration Rate -+10% to all Elemental Resistances - - - Rarity: RARE -Honour Vessel -Cobalt Jewel -Unique ID: effce7692e503b9cb919ee1cc722ce729e5a4ef09b6c309c8722b736f9cc7b1a -Item Level: 68 -Implicits: 0 -+4% to Cold Damage over Time Multiplier -5% increased Cast Speed with Lightning Skills -5% increased maximum Life - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]], - output = {["SpellSuppressionChanceOverCap"] = 0, -["FrenzyChargesMin"] = 0, -["EnergyShieldOnGloves"] = 43, -["HitChance"] = 100, -["LightningDotEHP"] = 33548, -["CrabBarriersMax"] = 0, -["SiphoningChargesMax"] = 0, -["AvoidColdDamageChance"] = 0, -["AnyTakenReflect"] = 0, -["InspirationCharges"] = 5, -["AbsorptionChargesMax"] = 0, -["LifePercentCost"] = 0, -["ReqInt"] = 188, -["IgniteEffMult"] = 1.1, -["ProjectileNotHitChance"] = 6, -["LifeCost"] = 0, -["ManaPercentCost"] = 0, -["ColdMinBase"] = 737, -["MaxManaLeechRate"] = 278.2, -["PhysicalTakenReflectMult"] = 0.4652, -["LightningLightningBaseTakenHitMult"] = 0.2, -["SelfShockDuration"] = 100, -["ManaOnHit"] = 0, -["AfflictionChargesMax"] = 0, -["PhysicalProjectileDamageChance"] = 24, -["ManaCost"] = 95, -["DoubleDamageChance"] = 0, -["SpellSuppressionEffect"] = 50, -["BloodChargesMax"] = 5, -["FireMeleeDamageChance"] = 24, -["PhysicalGuardEffectiveLife"] = 6728, -["ActiveTrapLimit"] = 15, -["PhysicalAegis"] = 0, -["EnergyShieldRegen"] = 0, -["LightningAegis"] = 0, -["SiphoningCharges"] = 0, -["RuthlessBlowEffect"] = 1, -["Cooldown"] = 0.99, -["PhysicalTakenHitMult"] = 0.4652, -["ChaosDotEHP"] = 21025, -["ChillSourceEffect"] = 18, -["ReqStr"] = 155, -["LightningGuardAbsorbRate"] = 0, -["MissingLightningResist"] = 0, -["AverageBlockChance"] = 12, -["LightningGuardEffectivePool"] = 0, -["EnergyShieldOnBody Armour"] = 53, -["MaxEnergyShieldLeechRate"] = 165.9, -["EnergyShieldLeechInstanceRate"] = 33.18, -["PhysicalNumberOfHits"] = 17.5726, -["ChaosTakenHit"] = 0.8, -["CritExtraDamageReduction"] = 0, -["CurrentShock"] = 0, -["PhysicalResist"] = 13.8525, -["ColdSpellProjectileDamageChance"] = 0, -["FireResistOver75"] = 0, -["ColdResist"] = 75, -["ScorchChanceOnHit"] = 0, -["PhysicalMinBase"] = 0, -["SpellProjectileBlockChance"] = 0, -["ColdTakenReflectMult"] = 0.2, -["Dex"] = 135, -["Spec:EnergyShieldInc"] = 114, -["Spec:EvasionInc"] = 25, -["Spec:ArmourInc"] = 20, -["KnockbackChanceOnHit"] = 0, -["TheoreticalOffensiveWarcryEffect"] = 1, -["IgniteChanceOnHit"] = 10, -["Spec:ManaInc"] = 43, -["PowerChargesMax"] = 3, -["Spec:LifeInc"] = 201, -["ExtraPoints"] = 2, -["FullDPS"] = 0, -["EnergyShieldOnHit"] = 0, -["SelfBleedDuration"] = 100, -["TotalDotDPS"] = 343620.6553, -["MaxOffensiveWarcryEffect"] = 1, -["PhysicalDamageReduction"] = 41.8525, -["SelfChillEffect"] = 100, -["Str"] = 207, -["SpellDodgeChanceOverCap"] = 0, -["WithIgniteDPS"] = 47174.6109, -["FireProjectileDamageChance"] = 24, -["LightningSpellProjectileDamageChance"] = 0, -["AttackDodgeChanceOverCap"] = 0, -["WithPoisonDPS"] = 46997.0778, -["WithDotDPS"] = 390440.1999, -["CombinedAvg"] = 46997.0778, -["CombinedDPS"] = 390617.733, -["AnyGuard"] = false, -["PhysicalTakenReflect"] = 0.8, -["MaximumScorch"] = 50, -["ShieldBlockChance"] = 24, -["TotalDot"] = 343443.1221, -["EnergyShieldLeechGainRate"] = 93.5519, -["ColdDot"] = 343443.1221, -["ColdResistOverCap"] = 43.8525, -["SpellBlockChance"] = 0, -["PhysicalMindOverMatter"] = 0, -["LifeOnBlock"] = 0, -["EnemyStunDuration"] = 0.4305, -["LightningManaEffectiveLife"] = 6728, -["ManaLeechInstances"] = 0, -["LightningResistOver75"] = 0, -["ColdTakenReflect"] = 0.8, -["SpellBlockChanceMax"] = 75, -["ChaosEnergyShieldBypass"] = 100, -["EnemyStunThresholdMod"] = 1, -["impaleStoredHitAvg"] = 0, -["KnockbackChance"] = 0, -["ManaOnHitRate"] = 0, -["DamageTakenOnBlock"] = 0, -["FreezeDurationMod"] = 1.6, -["EnergyShieldRechargeDelay"] = 2, -["FreezeChance"] = 70.546, -["LightningTotalPool"] = 8387, -["ChillEffectModDisplay"] = 80, -["BlockChanceOverCap"] = 0, -["ChallengerCharges"] = 0, -["Int"] = 430, -["ColdEnergyShieldBypass"] = 0, -["ChillEffectMod"] = 80, -["FireResistTotal"] = 97.8525, -["FreezeAvoidChance"] = 100, -["IgniteFireMin"] = 87, -["ChaosTakenHitMult"] = 0.256, -["ShockChance"] = 11.638, -["BleedChanceOnHit"] = 0, -["IgniteDamage"] = 705.8546, -["AttackDodgeChance"] = 0, -["LifeLeechDuration"] = 0, -["IgniteDPS"] = 177.5331, -["IgniteChance"] = 11.638, -["CritIgniteDotMulti"] = 1.19, -["FistOfWarAilmentEffect"] = 1, -["ReqDex"] = 111, -["ColdTakenHit"] = 0.8, -["ShockChanceOnCrit"] = 100, -["LightningProjectileDamageChance"] = 24, -["PhysicalHitAverage"] = 0, -["ChillChance"] = 100, -["DoubleDamageChanceOnCrit"] = 0, -["BrutalChargesMin"] = 0, -["ChaosMindOverMatter"] = 0, -["ImpaleChance"] = 0, -["Armour"] = 2393, -["LifeOnHit"] = 0, -["BrittleChanceOnHit"] = 0, -["PoisonAvoidChance"] = 100, -["LightningResistTotal"] = 99.8525, -["FireMinBase"] = 8, -["LightningMinBase"] = 0, -["ChillChanceOnHit"] = 100, -["FreezeChanceOnHit"] = 70, -["ShockChanceOnHit"] = 10, -["InterruptStunAvoidChance"] = 0, -["RuthlessBlowMaxCount"] = 0, -["AfflictionCharges"] = 0, -["AverageDamage"] = 46527.107, -["ColdTakenHitMult"] = 0.2, -["PowerCharges"] = 0, -["Devotion"] = 0, -["MissingColdResist"] = 0, -["ChaosGuardAbsorbRate"] = 0, -["PoisonChanceOnHit"] = 0, -["KnockbackChanceOnCrit"] = 0, -["PhysicalTakenHit"] = 0.8, -["SapChanceOnCrit"] = 0, -["LifeUnreserved"] = 6728, -["PreEffectiveCritChance"] = 1.82, -["ChillChanceOnCrit"] = 100, -["ColdGuardAbsorbRate"] = 0, -["EnergyShieldLeechDuration"] = 2.7913, -["IgniteFireMax"] = 130, -["FireResist"] = 75, -["RemovableFrenzyCharges"] = 0, -["IgniteChanceOnCrit"] = 100, -["ChaosAegis"] = 0, -["PoisonChanceOnCrit"] = 0, -["BleedChanceOnCrit"] = 0, -["ManaLeechGainRate"] = 0, -["PhysicalTotalPool"] = 8387, -["FreezeChanceOnCrit"] = 100, -["BlockDuration"] = 0.35, -["ManaLeechPerHit"] = 0, -["ManaLeechRate"] = 0, -["MissingChaosResist"] = 7, -["ManaLeechInstanceRate"] = 27.82, -["EnergyShieldLeechPerHit"] = 92.6164, -["FireTakenHit"] = 0.8, -["EnergyShieldLeechRate"] = 93.5519, -["BleedAvoidChance"] = 100, -["AverageNotHitChance"] = 3, -["AnyAegis"] = false, -["EnergyShieldOnBlock"] = 0, -["LifeLeechRate"] = 0, -["StunAvoidChance"] = 0, -["Gear:Ward"] = 0, -["EvadeChance"] = 6, -["Life"] = 6728, -["DurationMod"] = 1.005, -["TotalDPS"] = 46997.0778, -["EnduranceCharges"] = 3, -["AverageHit"] = 46527.107, -["EnergyShieldOnHitRate"] = 0, -["ColdTakenDotMult"] = 0.25, -["ChaosAverageDamageChance"] = 12, -["LifeOnHitRate"] = 0, -["ChaosMaximumHitTaken"] = 26281.25, -["SapChanceOnHit"] = 0, -["PhysicalTotalEHP"] = 21659.9397, -["ESCost"] = 0, -["ManaLeechInstantRate"] = 0, -["ColdMindOverMatter"] = 0, -["PhysicalGuardEffectivePool"] = 0, -["MaxLifeLeechRate"] = 1345.6, -["MaximumShock"] = 50, -["EnergyShieldLeechInstantRate"] = 0, -["EnergyShieldLeechInstant"] = 0, -["SpellProjectileNotHitChance"] = 0, -["LifeRegenPercent"] = 4.9, -["LightningResist"] = 75, -["PhysicalSpellProjectileDamageChance"] = 0, -["LifeLeechGainRate"] = 0, -["SpellNotHitChance"] = 0, -["FireGuardEffectivePool"] = 0, -["PhysicalMaximumHitTaken"] = 18029.5799, -["LifeLeechInstances"] = 0, -["WarcryPower"] = 20, -["ProjectileEvadeChance"] = 6, -["AbsorptionCharges"] = 0, -["FireMaxBase"] = 12, -["LightningCritAverage"] = 0, -["LifeLeechInstantRate"] = 0, -["MaxEnergyShieldLeechInstance"] = 165.9, -["IgniteDuration"] = 3.9759, -["PhysicalSpellDamageChance"] = 0, -["EnergyShieldLeechInstances"] = 2.8195, -["AvoidPhysicalDamageChance"] = 0, -["TotalMax"] = 55822.822, -["EvasionOnBoots"] = 177, -["CullMultiplier"] = 1, -["SelfBlindDuration"] = 100, -["ChaosResistTotal"] = 68, -["CrabBarriers"] = 0, -["LightningResistOverCap"] = 24.8525, -["FireHitAverage"] = 218.9, -["ColdHitAverage"] = 46308.207, -["EnergyShieldOnHelmet"] = 205, -["TotalDotInstance"] = 343443.1221, -["ManaReservedPercent"] = 96.3336, -["ChaosCritAverage"] = 0, -["FireCritAverage"] = 218.9, -["LightningTakenReflectMult"] = 0.2, -["AvoidChaosDamageChance"] = 0, -["FireFireBaseTakenHitMult"] = 0.2, -["PhysicalCritAverage"] = 0, -["allMult"] = 1, -["ChaosTotalPool"] = 6728, -["ManaLeech"] = 0, -["LowestOfMaximumLifeAndMaximumMana"] = 1391, -["ColdDotEHP"] = 33548, -["ArmourOnBoots"] = 177, -["SelfPoisonDuration"] = 100, -["LifeLeechInstant"] = 0, -["LifeLeech"] = 0, -["BrutalCharges"] = 0, -["ChaosMaxBase"] = 0, -["DamageReductionMax"] = 90, -["ColdMaxBase"] = 1105, -["LightningMaxBase"] = 0, -["InspirationChargesMax"] = 5, -["ChaosResist"] = 68, -["PhysicalMaxBase"] = 0, -["FrenzyChargesMax"] = 3, -["DoubleDamageEffect"] = 1, -["ManaUnreserved"] = 51, -["FireTakenReflect"] = 0.8, -["Accuracy"] = 466, -["TripleDamageEffect"] = 1, -["LifeLeechPerHit"] = 0, -["TripleDamageChanceOnCrit"] = 0, -["ScaledDamageEffect"] = 1, -["WardRechargeDelay"] = 5, -["FireTakenReflectMult"] = 0.2, -["MaxLifeLeechInstance"] = 672.8, -["SpellSuppressionEffectiveChance"] = 0, -["EnduranceChargesMin"] = 0, -["BonusCritDotMultiplier"] = 0, -["CritEffect"] = 1, -["TripleDamageChance"] = 0, -["LifeUnreservedPercent"] = 100, -["ScorchChanceOnCrit"] = 0, -["ShowBlockEffect"] = true, -["CritChance"] = 1.82, -["FistOfWarCooldown"] = 0, -["RuthlessBlowMultiplier"] = 1, -["IgniteDotMulti"] = 1.19, -["BlockChanceMax"] = 75, -["RuthlessBlowChance"] = 0, -["LightRadiusMod"] = 1.1, -["FistOfWarHitEffect"] = 1, -["ExertedAttackUptimeRatio"] = 0, -["ManaRegen"] = 85.7, -["ChaosChaosBaseTakenHitMult"] = 0.256, -["AilmentWarcryEffect"] = 1, -["RallyingHitEffect"] = 1, -["HitTime"] = 0.99, -["SeismicHitEffect"] = 1, -["TheoreticalMaxOffensiveWarcryEffect"] = 1, -["WithBleedDPS"] = 46997.0778, -["OffensiveWarcryEffect"] = 1, -["AvoidLightningDamageChance"] = 0, -["HitSpeed"] = 1.0101, -["ColdColdBaseTakenHitMult"] = 0.2, -["SelfIgniteDuration"] = 100, -["AvoidFireDamageChance"] = 0, -["ChaosSpellProjectileDamageChance"] = 0, -["Speed"] = 0, -["FrenzyCharges"] = 0, -["TotalCharges"] = 3, -["ChaosTakenReflectMult"] = 0.256, -["Time"] = 0, -["LifeReserved"] = 0, -["SpellSuppressionChance"] = 0, -["RageCost"] = 0, -["FireSpellProjectileDamageChance"] = 0, -["Duration"] = 3.015, -["AreaOfEffectRadius"] = 21, -["AreaOfEffectMod"] = 1.16, -["ActiveMineLimit"] = 15, -["EnemyCurseLimit"] = 2, -["ChaosTotalEHP"] = 31767.9116, -["LightningEnergyShieldBypass"] = 0, -["ChaosNumberOfHits"] = 25.7732, -["ColdMeleeDamageChance"] = 24, -["ColdTotalPool"] = 8387, -["LightningMindOverMatter"] = 0, -["FireNumberOfHits"] = 41.0028, -["ColdTotalEHP"] = 50539.8594, -["ColdNumberOfHits"] = 41.0028, -["LightningHitAverage"] = 0, -["ChillAvoidChance"] = 100, -["ChaosResistOver75"] = 0, -["ColdMaximumHitTaken"] = 41935, -["PhysicalResistWhenHit"] = 13.8525, -["LightningMaximumHitTaken"] = 41935, -["FireDotEHP"] = 33548, -["PhysicalDotEHP"] = 9735.6278, -["BlitzChargesMax"] = 0, -["ChaosSpellDamageChance"] = 0, -["LightningAverageDamageChance"] = 12, -["BrittleChanceOnCrit"] = 0, -["SelfFreezeDuration"] = 100, -["ChaosMeleeDamageChance"] = 24, -["ChaosGuardEffectiveLife"] = 6728, -["FireAverageDamageChance"] = 12, -["MovementSpeedMod"] = 1.89, -["FireTotalPool"] = 8387, -["ColdProjectileDamageChance"] = 24, -["FireSpellDamageChance"] = 0, -["ColdAverageDamageChance"] = 12, -["LowestAttribute"] = 135, -["EnduranceChargesMax"] = 3, -["ActionSpeedMod"] = 1, -["SpellBlockChanceOverCap"] = 0, -["MeleeEvadeChance"] = 6, -["LightningTakenDotMult"] = 0.25, -["ProjectileBlockChance"] = 24, -["FireTotalEHP"] = 50539.8594, -["RemovableEnduranceCharges"] = 3, -["LightningSpellDamageChance"] = 0, -["LightningMeleeDamageChance"] = 24, -["ChaosGuardEffectivePool"] = 0, -["PhysicalAverageDamageChance"] = 12, -["PowerChargesMin"] = 0, -["FireResistOverCap"] = 22.8525, -["ChallengerChargesMax"] = 0, -["Gear:EnergyShield"] = 370, -["LifeReservedPercent"] = 0, -["EvasionOnHelmet"] = 437, -["ChaosTakenDotMult"] = 0.32, -["ColdCritAverage"] = 46308.207, -["MissingFireResist"] = 0, -["LightningTakenHitMult"] = 0.2, -["StunDuration"] = 0.35, -["PhysicalMeleeDamageChance"] = 24, -["LowestOfArmourAndEvasion"] = 1462, -["AnyMindOverMatter"] = false, -["ManaRegenInc"] = 144, -["ManaOnBlock"] = 0, -["AfflictionChargesMin"] = 0, -["ColdResistTotal"] = 118.8525, -["LightningTakenReflect"] = 0.8, -["FireTakenHitMult"] = 0.2, -["ColdDotEffMult"] = 1.485, -["EnergyShield"] = 1659, -["EnergyShieldLeech"] = 92.6164, -["ChaosMinBase"] = 0, -["FireMindOverMatter"] = 0, -["FireGuardEffectiveLife"] = 6728, -["ChaosHitAverage"] = 0, -["dontSplitEvade"] = true, -["ColdResistOver75"] = 0, -["SpellDodgeChance"] = 0, -["AbsorptionChargesMin"] = 0, -["LifeLeechInstanceRate"] = 134.56, -["Gear:Armour"] = 177, -["EnergyShieldRechargeAppliesToEnergyShield"] = true, -["EnergyShieldOnWeapon 2"] = 69, -["SelfShockEffect"] = 100, -["PhysicalEnergyShieldBypass"] = 0, -["EnergyShieldOnSpellBlock"] = 0, -["IgniteAvoidChance"] = 10, -["ShockAvoidChance"] = 10, -["BrutalChargesMax"] = 0, -["LightningTotalEHP"] = 50539.8594, -["ChaosProjectileDamageChance"] = 24, -["ManaLeechDuration"] = 0, -["EnergyShieldRegenPercent"] = 0, -["EnergyShieldRecharge"] = 602, -["MaxManaLeechInstance"] = 139.1, -["CurrentScorch"] = 0, -["SelfChillDuration"] = 100, -["BlockChance"] = 24, -["FireGuardAbsorbRate"] = 0, -["ChaosPoisonChance"] = 0, -["ChaosManaEffectiveLife"] = 6728, -["TotalAttr"] = 772, -["EffectiveMovementSpeedMod"] = 1.89, -["EvasionOnBody Armour"] = 265, -["FireAegis"] = 0, -["RemovablePowerCharges"] = 0, -["Evasion"] = 1462, -["Gear:Evasion"] = 879, -["Mana"] = 1391, -["ColdAegis"] = 0, -["AvoidProjectilesChance"] = 0, -["ColdGuardEffectiveLife"] = 6728, -["ColdSpellDamageChance"] = 0, -["BlitzCharges"] = 0, -["FireEnergyShieldBypass"] = 0, -["PhysicalGuardAbsorbRate"] = 0, -["TotalMin"] = 37231.392, -["ChaosTakenReflect"] = 0.8, -["CullPercent"] = 0, -["ColdGuardEffectivePool"] = 0, -["LightningGuardEffectiveLife"] = 6728, -["PhysicalPhysicalBaseTakenHitMult"] = 0.4652, -["BloodCharges"] = 5, -["ChaosResistOverCap"] = 0, -["BlindAvoidChance"] = 0, -["FireMaximumHitTaken"] = 41935, -["Ward"] = 0, -["ManaRecoveryRateMod"] = 1, -["ColdManaEffectiveLife"] = 6728, -["FireManaEffectiveLife"] = 6728, -["LifeRecoveryRateMod"] = 1, -["LightningNumberOfHits"] = 41.0028, -["CritMultiplier"] = 1, -["ManaReserved"] = 1340, -["ChillDurationMod"] = 1.55, -["GhostShrouds"] = 0, -["ManaUnreservedPercent"] = 3.6664, -["LifeRegen"] = 329.616, -["AnyBypass"] = false, -["PhysicalTakenDotMult"] = 0.8615, -["EnergyShieldRecoveryRateMod"] = 1, -["MeleeNotHitChance"] = 6, -["ManaLeechInstant"] = 0, -["PhysicalManaEffectiveLife"] = 6728, -["BlockEffect"] = 100, -["FireTakenDotMult"] = 0.25, -["LightningTakenHit"] = 0.8, -} - -} \ No newline at end of file diff --git a/spec/TestBuilds/3.13/Dual Savior.xml b/spec/TestBuilds/Dual Savior.xml similarity index 100% rename from spec/TestBuilds/3.13/Dual Savior.xml rename to spec/TestBuilds/Dual Savior.xml diff --git a/spec/TestBuilds/3.13/Dual Wield Cospris CoC.xml b/spec/TestBuilds/Dual Wield Cospris CoC.xml similarity index 100% rename from spec/TestBuilds/3.13/Dual Wield Cospris CoC.xml rename to spec/TestBuilds/Dual Wield Cospris CoC.xml diff --git a/spec/TestBuilds/3.13/Generals Perforate Zerker.xml b/spec/TestBuilds/Generals Perforate Zerker.xml similarity index 100% rename from spec/TestBuilds/3.13/Generals Perforate Zerker.xml rename to spec/TestBuilds/Generals Perforate Zerker.xml diff --git a/spec/TestBuilds/3.13/Mirage Archer Toxic Rain.xml b/spec/TestBuilds/Mirage Archer Toxic Rain.xml similarity index 100% rename from spec/TestBuilds/3.13/Mirage Archer Toxic Rain.xml rename to spec/TestBuilds/Mirage Archer Toxic Rain.xml diff --git a/spec/TestBuilds/3.13/OccVortex.xml b/spec/TestBuilds/OccVortex.xml similarity index 100% rename from spec/TestBuilds/3.13/OccVortex.xml rename to spec/TestBuilds/OccVortex.xml diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 16e8d4d2dcc..066b01edd72 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -1,33 +1,37 @@ #!/bin/sh -git config --system --add safe.directory /root +cd $WORKDIR +git config --global --add safe.directory /workdir headref=$(git rev-parse HEAD) devref=$(git rev-parse dev) -if [[ ! -f "/root/spec/Cache/$devref" ]] # Output of builds outdated or nonexistent +if [[ ! -f "$CACHEDIR/$devref" ]] # Output of builds outdated or nonexistent then - rm /root/spec/Cache/* - rm -rf /devRef - mkdir /devRef && cp -r /root/. /devRef/ && cd /devRef && \ + rm -rf $CACHEDIR/* + cp -rf --parents $WORKDIR /tmp && cd /tmp$WORKDIR && \ git restore . && git clean -fd && git checkout dev && \ - cp /root/.busted . && rm -rf /devRef/spec/ && cp -r /root/spec/ /devRef/spec/ && \ - BUILDCACHEPREFIX='/root/spec/Cache' busted --lua=luajit -r generate && \ - date > "/root/spec/Cache/$devref" && cd /root && echo "[+] Build cache computed for $devref" - rm -rf /devRef + cp $WORKDIR/.busted /tmp$WORKDIR/.busted && cp $WORKDIR/src/HeadlessWrapper.lua /tmp$WORKDIR/src/HeadlessWrapper.lua && rm -rf /tmp$WORKDIR/spec/ && cp -r $WORKDIR/spec/ /tmp$WORKDIR/spec/ && \ + cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 "cat > /tmp/parallel_links_{#}; BUILDLINKS=/tmp/parallel_links_{#} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate; rm /tmp/parallel_links_{#}" && \ + BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref" fi -if [[ -f "/root/spec/Cache/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev +if [[ -f "$CACHEDIR/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev then - rm /tmp/* + rm -rf /tmp/* + cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 'cat > /tmp/parallel_links_{#}; BUILDLINKS="/tmp/parallel_links_{#}" BUILDCACHEPREFIX="/tmp" busted --lua=luajit -r generate; rm /tmp/parallel_links_{#}' && \ BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && echo "[+] Build cache computed for $headref" fi if [[ -f "/tmp/$headref" ]] # Make sure generating builds for current HEAD was successful then - for build in /root/spec/Cache/*.lua + for build in $CACHEDIR/*.lua + do + luajit $WORKDIR/spec/buildOutputDiff.lua /tmp/$(basename "$build") "$build" + done + for build in $CACHEDIR/*.build do BASENAME=$(basename "$build") - echo "[-] Diff for $BASENAME" + echo "[-] Savefile Diff for $BASENAME" diff "$build" "/tmp/$BASENAME" - echo "[+] Diff for $BASENAME" + echo "[+] Savefile Diff for $BASENAME" done fi diff --git a/spec/buildOutputDiff.lua b/spec/buildOutputDiff.lua new file mode 100644 index 00000000000..a572ba60cb3 --- /dev/null +++ b/spec/buildOutputDiff.lua @@ -0,0 +1,22 @@ +local l = loadfile(arg[1])().output +local r = loadfile(arg[2])().output +local mismatch = {} + +for key, val in pairs(l) do + if r[key] ~= val then + table.insert(mismatch, key) + end +end + +for key, val in pairs(r) do + if l[key] ~= val then + table.insert(mismatch, key) + end +end + +print("[?] Mismatch count: " .. #mismatch) +for _, key in ipairs(mismatch) do + print(string.format("[%s] mismatch:", key)) + print("\t".. arg[1] .. ": " .. tostring(l[key])) + print("\t".. arg[2] .. ": " .. tostring(r[key])) +end \ No newline at end of file diff --git a/spec/builds.txt b/spec/builds.txt new file mode 100644 index 00000000000..f59a375af02 --- /dev/null +++ b/spec/builds.txt @@ -0,0 +1,9 @@ +https://pobb.in/IE4NagN7GTSG +https://pobb.in/JMVIpB8NfS3W +https://pobb.in/PadeL7jl7LOf +https://pobb.in/LWMgGFgeY1OA +https://pobb.in/q_zvdst3wVY8 +https://pobb.in/wYMBCn6VMnMH +https://pobb.in/9Zk2dHONu60p +https://pobb.in/QYMalBGKpank +https://pobb.in/TaEKdjV0Q6op diff --git a/src/HeadlessWrapper.lua b/src/HeadlessWrapper.lua index c6f9502826c..b46e5e975de 100644 --- a/src/HeadlessWrapper.lua +++ b/src/HeadlessWrapper.lua @@ -1,5 +1,5 @@ #@ --- This wrapper allows the program to run headless on any OS (in theory) +-- This wrapper allows the program to run headless -- It can be run using a standard lua interpreter, although LuaJIT is preferable @@ -23,6 +23,12 @@ function SetMainObject(obj) mainObject = obj end +-- https://stackoverflow.com/questions/19326368/iterate-over-lines-including-blank-lines +function magiclines(s) + if s:sub(-1)~="\n" then s=s.."\n" end + return s:gmatch("(.-)\n") +end + -- Image Handles local imageHandleClass = { } imageHandleClass.__index = imageHandleClass @@ -68,8 +74,26 @@ function GetAsyncCount() return 0 end +posix = require("posix") + -- Search Handles -function NewFileSearch() end +function NewFileSearch(path) + local paths = posix.glob(path) + local currentPath = 1 + return paths and {GetFileName = function() + return posix.basename(paths[currentPath]) + end, + GetFileModifiedTime = function() + return posix.lstat(paths[currentPath]).st_mtime + end, + GetFileSize = function() + return posix.lstat(paths[currentPath]).st_size + end, + NextFile = function() + currentPath = currentPath + 1 + return paths[currentPath] + end} +end -- General Functions function SetWindowTitle(title) end @@ -81,31 +105,31 @@ function ShowCursor(doShow) end function IsKeyDown(keyName) end function Copy(text) end function Paste() end + +require "zlib" function Deflate(data) - -- TODO: Might need this - return "" + return zlib.deflate()(data) end function Inflate(data) - -- TODO: And this - return "" + return zlib.inflate()(data) end function GetTime() - return 0 + return os.clock() * 10 end function GetScriptPath() - return "" + return os.getenv("PWD") .. "/src" end function GetRuntimePath() return "" end function GetUserPath() - return "" + return os.getenv("HOME") end function MakeDir(path) end function RemoveDir(path) end function SetWorkDir(path) end function GetWorkDir() - return "" + return os.getenv("PWD") end function LaunchSubScript(scriptText, funcList, subList, ...) end function AbortSubScript(ssID) end @@ -154,18 +178,58 @@ function SetProfiling(isEnabled) end function Restart() end function Exit() end -local l_require = require -function require(name) - -- Hack to stop it looking for lcurl, which we don't really need - if name == "lcurl.safe" then - return +dofile("Launch.lua") + +function launch:DownloadPage(url, callback, params) + params = params or {} + local responseHeader = "" + local responseBody = "" + ConPrintf("Downloading page at: %s", url) + local curl = require("lcurl.safe") + local easy = curl.easy() + if params.header then + local header = {} + for s in params.header:gmatch("[^\r\n]+") do + table.insert(header, s) + end + easy:setopt(curl.OPT_HTTPHEADER, header) + end + easy:setopt_url(url) + easy:setopt(curl.OPT_USERAGENT, "Path of Building/]]..self.versionNumber..[[") + easy:setopt(curl.OPT_ACCEPT_ENCODING, "") + if params.body then + easy:setopt(curl.OPT_POST, true) + easy:setopt(curl.OPT_POSTFIELDS, params.body) + end + if params.connectionProtocol or self.connectionProtocol then + easy:setopt(curl.OPT_IPRESOLVE, params.connectionProtocol or self.connectionProtocol) end - return l_require(name) + if params.proxyURL or self.proxyURL then + easy:setopt(curl.OPT_PROXY, params.proxyURL or self.proxyURL) + end + easy:setopt_headerfunction(function(data) + responseHeader = responseHeader .. data + return true + end) + easy:setopt_writefunction(function(data) + responseBody = responseBody .. data + return true + end) + local _, error = easy:perform() + local code = easy:getinfo(curl.INFO_RESPONSE_CODE) + easy:close() + local errMsg + if error then + errMsg = error:msg() + elseif code ~= 200 then + errMsg = "Response code: "..code + elseif #responseBody == 0 then + errMsg = "No data returned" + end + ConPrintf("Download complete. Status: %s", errMsg or "OK") + callback({header=responseHeader, body=responseBody}, errMsg) end - -dofile("Launch.lua") - -- The CI env var will be true when run from github workflows but should be false for other tools using the headless wrapper mainObject.continuousIntegrationMode = os.getenv("CI") From c60cd205a29ffdfd51b5ced1d3efd05b51fee01e Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 5 Jan 2024 09:21:14 +0100 Subject: [PATCH 024/106] FIX: update the test.yml action --- .github/workflows/test.yml | 41 ++++++++------------------------------ docker-compose.yml | 12 +++++------ spec/buildDiff.sh | 2 +- 3 files changed, 15 insertions(+), 40 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 269a05fd9c4..d83215602f8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,52 +8,27 @@ on: jobs: run_unit_tests: runs-on: ubuntu-latest - container: - # No good way to automatically get the lowercase repo owner name here. - image: ghcr.io/paliak/busted-tests steps: - name: Checkout repository uses: actions/checkout@v4 - name: Run busted tests - run: busted --lua=luajit + run: docker-compose up busted-tests + run_build_diff: runs-on: ubuntu-latest - container: - # No good way to automatically get the lowercase repo owner name here. - image: ghcr.io/paliak/busted-tests steps: - name: Checkout HEAD uses: actions/checkout@v4 - - name: Generate builds in reference to current commit - run: busted --lua=luajit -r generate + - name: Create cache directory + run: mkdir /tmp/Cache - name: Check if build cache exists id: cache-builds uses: actions/cache@v3 env: cache-name: cached-dev-builds with: - path: spec/Cache + path: /tmp/Cache key: ${{ github.event.pull_request.base.sha }} - - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} - name: Save changes to tests files - run: cp -r .busted spec /tmp/ - - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} - name: Checkout dev - uses: actions/checkout@v4 - with: - ref: 'dev' - - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} - name: Patch dev with latest tests files - run: rm -rf .busted spec && cp -r /tmp/.busted /tmp/spec . - - if: ${{ steps.cache-builds.outputs.cache-hit != 'true' }} - name: Generate builds in reference to dev branch - run: BUILDCACHEPREFIX="$(realpath spec/Cache)" busted --lua=luajit -r generate - - name: Display differences - run: > - for build in spec/Cache/*.lua; - do - BASENAME=$(basename "$build"); - echo "[-] Diff for $BASENAME"; - diff "$build" "/tmp/$BASENAME" || true; - echo "[+] Diff for $BASENAME"; - done + - name: Run build diff + run: CACHEDIR="/tmp/Cache" docker-compose up busted-diff + \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 9499d20fd96..7b4fd23e645 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ services: busted-tests: - build: . - #image: ghcr.io/paliak/busted-tests + #build: . + image: ghcr.io/paliak/busted-tests container_name: busted-tests command: busted --lua=luajit security_opt: @@ -12,9 +12,9 @@ services: volumes: - ./:/workdir:ro busted-diff: - build: . - #image: ghcr.io/paliak/busted-tests - environment: + #build: . + image: ghcr.io/paliak/busted-tests + environment: #Where in the container the folders are stored WORKDIR: /workdir CACHEDIR: /cache container_name: busted-diff @@ -25,6 +25,6 @@ services: working_dir: /workdir volumes: - ./:/workdir:ro - - busted-diff-cache:/cache + - "${CACHEDIR:-busted-diff-cache}:/cache" volumes: busted-diff-cache: \ No newline at end of file diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 066b01edd72..4df7baa61b1 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -11,7 +11,7 @@ then git restore . && git clean -fd && git checkout dev && \ cp $WORKDIR/.busted /tmp$WORKDIR/.busted && cp $WORKDIR/src/HeadlessWrapper.lua /tmp$WORKDIR/src/HeadlessWrapper.lua && rm -rf /tmp$WORKDIR/spec/ && cp -r $WORKDIR/spec/ /tmp$WORKDIR/spec/ && \ cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 "cat > /tmp/parallel_links_{#}; BUILDLINKS=/tmp/parallel_links_{#} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate; rm /tmp/parallel_links_{#}" && \ - BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref" + BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref" && cd $WORKDIR fi if [[ -f "$CACHEDIR/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev From 51f09ac42378614b6d44ed6d80a4a1ba345836f4 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 5 Jan 2024 10:31:00 +0100 Subject: [PATCH 025/106] FIX: more info for mismatch count --- spec/buildOutputDiff.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/buildOutputDiff.lua b/spec/buildOutputDiff.lua index a572ba60cb3..3bc5769765e 100644 --- a/spec/buildOutputDiff.lua +++ b/spec/buildOutputDiff.lua @@ -14,7 +14,7 @@ for key, val in pairs(r) do end end -print("[?] Mismatch count: " .. #mismatch) +print("[?] Mismatch count: " .. #mismatch .. " for " .. arg[1] .. " and " arg[2]) for _, key in ipairs(mismatch) do print(string.format("[%s] mismatch:", key)) print("\t".. arg[1] .. ": " .. tostring(l[key])) From 9328c999d3325eb13855effc781a433c76072861 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 5 Jan 2024 10:32:54 +0100 Subject: [PATCH 026/106] FEAT: add more builds --- spec/builds.txt | 487 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 487 insertions(+) diff --git a/spec/builds.txt b/spec/builds.txt index f59a375af02..151125595df 100644 --- a/spec/builds.txt +++ b/spec/builds.txt @@ -7,3 +7,490 @@ https://pobb.in/wYMBCn6VMnMH https://pobb.in/9Zk2dHONu60p https://pobb.in/QYMalBGKpank https://pobb.in/TaEKdjV0Q6op +https://pobb.in/S9aqRfwcRkig +https://pobb.in/l8yyxQSve0-q +https://pobb.in/uDXPObcS5Umk +https://pobb.in/ibssLb49uDS3 +https://pobb.in/Be-pUqssGfa0 +https://pobb.in/TElsp5oR8Nsg +https://pobb.in/bECv3LzPKBKo +https://pobb.in/wDLFVhLgWirR +https://pobb.in/hK_Y2CnOWZ4F +https://pobb.in/54U-kgJ4MRKu +https://pobb.in/ki6HrllV1aB8 +https://pobb.in/SFslJqvR7cfk +https://pobb.in/Hsa-VHPxZoIY +https://pobb.in/j0pMpMx3_TU0 +https://pobb.in/AjXV0g6w6CGl +https://pobb.in/Wq7-YT2p1vZE +https://pobb.in/xYp-wwPp8a3y +https://pobb.in/Z2Mvl7EeuCxV +https://pobb.in/R2KCSu20A0x1 +https://pobb.in/smbctdc34cfH +https://pobb.in/eveJpzFgpABq +https://pobb.in/kQDsMsssM7Cd +https://pobb.in/IR-wmUnzNb5t +https://pobb.in/zja6gYi85Vi- +https://pobb.in/Gmy8Ha5XjlxH +https://pobb.in/bopGfR_OtxAd +https://pobb.in/eK0GthXVFTli +https://pobb.in/eGEoXF_1JMdv +https://pobb.in/TNseXhh0s34I +https://pobb.in/HjFpaJopbgkn +https://pobb.in/upwMs8RD7tqc +https://pobb.in/oTC_P19aN0mw +https://pobb.in/nyUDdl-MeE0i +https://pobb.in/tE1ikJ5jhvsQ +https://pobb.in/9eiU4SQvNhVn +https://pobb.in/Sf2cUlge3cXA +https://pobb.in/WNHPmLkPheCX +https://pobb.in/FXTjzI2no-iV +https://pobb.in/DEjQ59pJ6cep +https://pobb.in/jZmghaat0TTG +https://pobb.in/DjWB3Yn4PQpk +https://pobb.in/mi9rConMt-54 +https://pobb.in/KaB-X8C_HnwY +https://pobb.in/H3kffOAomNKu +https://pobb.in/81Q8t9QQHNsV +https://pobb.in/8af4qRbuvqeU +https://pobb.in/4wM1Zr7K4Cwh +https://pobb.in/oEb8wRv8BOej +https://pobb.in/V1-geRkxnEcP +https://pobb.in/96VEtNXW6rJc +https://pobb.in/ncOsN44is4np +https://pobb.in/ujB8-bN7xp-U +https://pobb.in/XpzE_KgjezkM +https://pobb.in/-vF0TFPojXt4 +https://pobb.in/djd3NOvOpUsL +https://pobb.in/44KghQ9UqV6c +https://pobb.in/3PQauTJQ9P6W +https://pobb.in/7wS-Qr0iSpc1 +https://pobb.in/gKFXA0EGw5zl +https://pobb.in/Ts39eMN4t56c +https://pobb.in/C6BOw8mtr6sp +https://pobb.in/C9WsIXJRy2HL +https://pobb.in/CQ4dTqZ0Nabz +https://pobb.in/X5TM5bwvvMd8 +https://pobb.in/JAAcoQ4Nd0ag +https://pobb.in/U_qxBoex9q7D +https://pobb.in/HF9t3mpb3zvp +https://pobb.in/L37mELjitfF8 +https://pobb.in/51C82oj0V1fA +https://pobb.in/m2PrCSq4xATv +https://pobb.in/hRfNYcsWwEmQ +https://pobb.in/ONDumuLU7Nrc +https://pobb.in/EjCrx9iIz_3s +https://pobb.in/nuC1qi1XEUE9 +https://pobb.in/sYdsB2H1DRkW +https://pobb.in/USwKhqanxkrr +https://pobb.in/ZQHLowtcuOn2 +https://pobb.in/VfpcLLf5Bjbr +https://pobb.in/umWKn_8AvlZJ +https://pobb.in/Qp9e9gA4zFzJ +https://pobb.in/ybrNx5kxTHMz +https://pobb.in/1NELamxHjk5C +https://pobb.in/tBj-Q2Fev0M9 +https://pobb.in/BVkIESFInGox +https://pobb.in/ng94oXaUa2vN +https://pobb.in/2MS-ybrerKuf +https://pobb.in/lKMS_N9LfD8E +https://pobb.in/uxic87OGxF-p +https://pobb.in/msqiktNJDffw +https://pobb.in/nKS73-FkwtZm +https://pobb.in/J8uGzeIEMRO4 +https://pastebin.com/yG1tgaCg +https://pobb.in/l-Xcp7cvg-Tw +https://pobb.in/u2wc1WFpFaj8 +https://pobb.in/SZoyI6Jy0TFp +https://pobb.in/4_ZnR2-Ct5PU +https://pobb.in/DMkOVl-A7CZs +https://pobb.in/cWnAfWcNHjku +https://pobb.in/6Md0lMDThvlI +https://pobb.in/AGAW9dxt3tfT +https://pobb.in/07K2n1mKHPTO +https://pobb.in/__Y6sg-7_h68 +https://pobb.in/j_dK9-hBXXp1 +https://pobb.in/n3nBymGaoywE +https://pobb.in/LGTXj5e6RPjz +https://pobb.in/J3KrfHGH31QT +https://pobb.in/kDD9op-w40Md +https://pobb.in/FVj-y73u3Abs +https://pobb.in/H2LTrp1PY4M2 +https://pobb.in/ZKJUjQMXRsCJ +https://pobb.in/5GdRvEAs4euj +https://pobb.in/yj9Wv0s8PZii +https://pobb.in/eg3V2eQ0ppT1 +https://pobb.in/FUwe-p0FvKAS +https://pobb.in/u_sZqMzTBr-N +https://pobb.in/-qKa0Fmr-zEs +https://pobb.in/Fqg3Oj3-obFC +https://pobb.in/DsU2DCj8uDqi +https://pobb.in/PE7dH82SLAbt +https://pobb.in/w8pVlddWDTrL +https://pobb.in/NMhlIYKjldHw +https://pobb.in/rxKv6B0X_tX2 +https://pobb.in/FW71jq4UA9Ct +https://pobb.in/xL08XMlk6yG0 +https://pobb.in/poW0bqFnwQr8 +https://pobb.in/r144hi0DEA5S +https://pobb.in/dunJdoyV_pu3 +https://pobb.in/umLO5W1mC5hl +https://pobb.in/zQiLmaTQsOp4 +https://pobb.in/igA9-ny_Wj-T +https://pobb.in/EAN0PHgQ_i50 +https://pobb.in/-07NEIgxfZXk +https://pobb.in/Kgpci1pI0OS4 +https://pobb.in/kJMk1Imw4Cla +https://pobb.in/k4cvCJVzw5ps +https://pobb.in/8cYpafa-FcvQ +https://pobb.in/MHVtAEJMIQof +https://pobb.in/UMbOsddyQYIo +https://pobb.in/qAoa4bkZRmWF +https://pobb.in/_B4UCtDnKGuq +https://pobb.in/biAyASZ_k-jd +https://pobb.in/BON5TeD7q5zF +https://pobb.in/C6aRrRYo78Eo +https://pobb.in/ruth1aHXLvxm +https://pobb.in/mqTWkmle8dTh +https://pobb.in/6QvNFqiAsBtQ +https://pobb.in/-ri8yvFeO0Vg +https://pobb.in/_UU9l9YX2LMF +https://pobb.in/b0Pu_tGvrukP +https://pobb.in/OApAqAX0gEUW +https://pobb.in/7MP8wjKatZjS +https://pobb.in/Z3nMFjOa6RLb +https://pobb.in/Y4F2fc4e-OtY +https://pobb.in/98burVE6hQ9l +https://pobb.in/FV2YnevL2u7D +https://pobb.in/TT7iT91rlUvG +https://pobb.in/bmlnUSUxiaU3 +https://pobb.in/ZpCrq6o_WFq2 +https://pobb.in/zEd5CTxQOLy3 +https://pobb.in/KlhL43emVusy +https://pobb.in/IdVH4TjSJMAF +https://pobb.in/iUUqFn14sfx7 +https://pobb.in/4A9xkLDdC2OS +https://pobb.in/sgQMgrN8Jg_H +https://pobb.in/fPc0Zt5YLPbU +https://pobb.in/qQ_NhnnUeEnn +https://pobb.in/pm5hGr_tqyUX +https://pobb.in/GtcA12JNvIQh +https://pobb.in/qFuuQGdemab5 +https://pobb.in/ipHlHvOWoqiR +https://pobb.in/UJoTJ_ywk0k_ +https://pobb.in/JjcBjl0RLx2D +https://pobb.in/kc5pFI73edqg +https://pobb.in/ERs0XDcMQ3hX +https://pobb.in/dxUNR6IORnQh +https://pobb.in/xbKYB5-9Spgj +https://pobb.in/19g9h80Djjs3 +https://pobb.in/3G8BQeLgJ0CJ +https://pobb.in/oQ0QcoKQFG4w +https://pobb.in/6pfeNsHZad_7 +https://pobb.in/EEa1kJ12fAHj +https://pobb.in/QCdaKepWj3J- +https://pobb.in/hAiM4csejJYU +https://pastebin.com/RbenZLcL +https://pobb.in/amaVuJ-WNuKd +https://pobb.in/-uU1KKrG8DU6 +https://pastebin.com/YnFDFirq +https://pobb.in/5LGtZufFvSHn +https://pobb.in/kJXRsYGXUx3Z +https://pobb.in/KoF2O2baexKs +https://pobb.in/QxVS-5o_6-9o +https://pobb.in/NBDi-6HwJigd +https://pobb.in/MUCA5xW1bA9V +https://pobb.in/XFSKeMsGqUcb +https://pobb.in/W6TCokL0IIsk +https://pobb.in/i3qcpqefso9L +https://pobb.in/OzJBlGxXBdf2 +https://pobb.in/Od2Wr-ilQDgf +https://pobb.in/dXGok1zpqCHY +https://pobb.in/8kLdNpTN-jFV +https://pobb.in/zZgJQ4WuD1kK +https://pobb.in/FzwIG3u64DHs +https://pobb.in/ArZ3B6b0W6UN +https://pobb.in/Fit5Pv2r3dEt +https://pobb.in/-3zKE3-NyVdL +https://pobb.in/whuvRIBGJhj- +https://pobb.in/YmmaeMeO40X7 +https://pobb.in/wie9SgFJwdwt +https://pobb.in/Be-Mg1mfcHdo +https://pobb.in/Egkh6-Ylp3Km +https://pobb.in/ovnS-f5WpcTm +https://pobb.in/nM3sdJpoEq9K +https://pobb.in/btEtteqXKRa8 +https://pobb.in/nWLRSTZEdFeW +https://pobb.in/EjmN9uy5UtTw +https://pobb.in/RYj-fud6QGlq +https://pobb.in/5lKIKuhS0S2o +https://pobb.in/NDmhKmUU8CYm +https://pobb.in/e2qZC7brodaX +https://pobb.in/E01ehXOj2gPI +https://pobb.in/z9BLpX_gt6YN +https://pobb.in/frtAFt9I5Ax0 +https://pobb.in/oIigpdp1_ZKq +https://pobb.in/tJs_Kcs4Bayb +https://pobb.in/pNhDaiKOMRBT +https://pobb.in/k02IW8DdiV6r +https://pobb.in/O9KMAKsQ3h90 +https://pobb.in/KqayL94duAFF +https://pobb.in/vxqhmw3IVoGN +https://pobb.in/BTvfZ5ufsu0c +https://pobb.in/O7dPnRNPZ_oO +https://pobb.in/-0ih9zEjNaBz +https://pobb.in/dNTFsdREKjqo +https://pobb.in/ecoXor593v4F +https://pobb.in/MpIHozx1EAgX +https://pobb.in/fdvDqj5SZ66G +https://pobb.in/7Spit2UZivbD +https://pobb.in/nfXnKQgtV1MQ +https://pobb.in/b7Rrle5O6dgB +https://pobb.in/8mScph1Saz57 +https://pobb.in/YjQUHEg9VHr_ +https://pobb.in/D7EPVT9wDK8f +https://pobb.in/TQN51If6AivG +https://pobb.in/1R7av1-GlriU +https://pastebin.com/1eZvWjQS +https://pobb.in/wl7njZwp-gP- +https://pobb.in/ziPgzKQAx2RU +https://pobb.in/gFWZt6FQlUON +https://pobb.in/Vck_qesvrWl9 +https://pobb.in/gzwNUqSD9_Ay +https://pobb.in/mylx0CKFXS0o +https://pobb.in/9YtjT89tX1uw +https://pobb.in/KqYBczFCFFV2 +https://pobb.in/XnNaXObqrqOz +https://pobb.in/ZtHR1MMDweUm +https://pobb.in/adFZRE4IHHBp +https://pobb.in/J1XxP7H_ebrw +https://pobb.in/URiRfcG5mV8m +https://pobb.in/brlnMafiHfeZ +https://pobb.in/58v7bIFnJxAa +https://pobb.in/bEUeNTkfbQuU +https://pobb.in/SQapgfbsL0f2 +https://pobb.in/R683B_NROGRj +https://pobb.in/hXdcBoPDa47l +https://pobb.in/QKF7pe9I1eZV +https://pobb.in/UGoeMrlnKQHh +https://pobb.in/eoZv--XORO9I +https://pobb.in/myrEejDOoBI4 +https://pobb.in/hZOZ3T6UgztH +https://pobb.in/J_Jyry_qcghc +https://pobb.in/rXr6yvdu1zpu +https://pobb.in/kEPNzt-lrQ4f +https://pobb.in/LC4U9fqLzbZf +https://pobb.in/boAKRwdZSR_M +https://pobb.in/pMK-3DEn0Kn_ +https://pobb.in/cCDCMzJpKlwA +https://pobb.in/J5Rg9mFOAcZt +https://pobb.in/tpyjCb-pLJSU +https://pobb.in/N5JeP04hARDc +https://pobb.in/d8hImyN06HKm +https://pobb.in/cwe79SGznaKo +https://pobb.in/nzTB2wmLVuYz +https://pobb.in/W-OKqb1RKYDi +https://pastebin.com/nd8XxzjM +https://pobb.in/CFNO_oeTo_6x +https://pastebin.com/Lp8RPvQK +https://pobb.in/-nZb_3q4n1p8 +https://pobb.in/pp4kYKfSlE3A +https://pobb.in/0Z1AA1p5n729 +https://pobb.in/ntxxIpw6FDW6 +https://pobb.in/vHmb69DHcdcu +https://pobb.in/1jf4AAQl9nRf +https://pastebin.com/ZeTzsRCi +https://pobb.in/KVc0guxzydXP +https://pobb.in/ar_eGJtxlp3A +https://pobb.in/youWw0a8CbHY +https://pobb.in/6l9rHWCkFQ3Q +https://pobb.in/9tnQ1Dp_Qebf +https://pobb.in/l5hKsuh2AVh6 +https://pobb.in/wctVq9Hwu8J8 +https://pobb.in/w0pVHB60rZm8 +https://pobb.in/KkBEcBzeXnsR +https://pobb.in/oeegwBv0Qwvq +https://pobb.in/Kk_VWB6C6i81 +https://pobb.in/YDIX5MnktplJ +https://pobb.in/ru2tii6_MD9b +https://pobb.in/BHHHAyNV9aRG +https://pobb.in/xMMmoinpxF-D +https://pobb.in/j3JOYwi2rGYN +https://pobb.in/bwHiVbS-UnKY +https://pobb.in/hESRI9SwTx8R +https://pobb.in/2JP91_esEXeY +https://pobb.in/58_EoX-p9HPD +https://pobb.in/iJN8SdZweah6 +https://pobb.in/_HzKifZYLkiW +https://pobb.in/rpixrdV1Z91b +https://pobb.in/UeSag0MBfAqz +https://pobb.in/9ACP67JVEGy0 +https://pobb.in/cWehUbRlP8VJ +https://pobb.in/R8FBmZ-8seLJ +https://pobb.in/uAgF2TfO2Diu +https://pobb.in/xDjuKrTF_-TT +https://pobb.in/jPTzGdcSKoxO +https://pobb.in/nlBGVt-w7jIc +https://pobb.in/zClgDj1g4H1G +https://pobb.in/ysJFWoXdNC9z +https://pobb.in/HXhNfnA6XmGY +https://pobb.in/JcolJsbDhNiN +https://pobb.in/GVSZSVDdnk1U +https://pobb.in/n0vWHE8tAcAL +https://pobb.in/0X00op3OB8jy +https://pobb.in/qTJGBNpjZ-o4 +https://pobb.in/PNAHoexwgF3o +https://pobb.in/m76dOUMfn1Ng +https://pastebin.com/qk555ufY +https://pobb.in/ZdBfjiDOiXy6 +https://pobb.in/GhTxgBYTUlFw +https://pobb.in/zeQxZwv1UAaa +https://pobb.in/gN3mL1bveLUi +https://pobb.in/9DbGmC9fX0Wb +https://pobb.in/4U8mrcEjkpID +https://pobb.in/Ndz7Z5OTrtK6 +https://pobb.in/MSANateBSMmQ +https://pobb.in/je175Y4q3tLm +https://pobb.in/yIX1EcF3_sNI +https://pobb.in/NQNuVrtZme9v +https://pobb.in/f5jjLp0rqvyW +https://pastebin.com/5GwgeTNV +https://pobb.in/JQJvmXE-Qogt +https://pobb.in/eyDFABaanqys +https://pastebin.com/9WBmCym4 +https://pobb.in/uTQEE6P4SmvW +https://pobb.in/5RIoMXHby-68 +https://pobb.in/BYYJdC33uCZT +https://pobb.in/E9nMI7FpnkGD +https://pobb.in/A8QX9H2p-m3D +https://pobb.in/Zs4Vhc1dEV16 +https://pobb.in/-cemSYSYqEEb +https://pobb.in/BwSEKcZ9OxRB +https://pobb.in/s9-ne_IZOpnQ +https://pobb.in/z3av5TS1fuUb +https://pobb.in/ka630Ngl2-oA +https://pobb.in/02qCbBTXOY2c +https://pobb.in/f8ksWeJvFw4r +https://pobb.in/0MYdjMBiyfXy +https://pastebin.com/cYwitwH8 +https://pobb.in/tZiG_YkM4_SX +https://pobb.in/XVIhxflBLgPH +https://pobb.in/JxTgZhFEoT9Y +https://pobb.in/ICzYnUryUOJx +https://pobb.in/Eoscl_ecmquX +https://pobb.in/G2ST2EGEH6Ws +https://pobb.in/-hyqzoGdSIyy +https://pobb.in/WLaxdhgNAesT +https://pobb.in/tNnUh68kHqW1 +https://pobb.in/opmUHt10iZed +https://pobb.in/prNyfUoiU1ME +https://pobb.in/FUrwupJJMpe6 +https://pobb.in/jbxsfUHQeDFy +https://pobb.in/pHctVCc1g8Mo +https://pobb.in/qzz_EbCzrAqJ +https://pobb.in/UssJKC1R6J98 +https://pobb.in/HQXGNILQ3bXj +https://pobb.in/vPVSF6A_W9kt +https://pobb.in/qj-rO9r1pQkk +https://pobb.in/sAuoMjX7zgyT +https://pobb.in/k_VbhDiHkfI8 +https://pobb.in/9QocExspWjTt +https://pobb.in/I-y3rBmHE7b1 +https://pobb.in/rN2kBaCb6OnM +https://pobb.in/FBY2ZLDw46Gn +https://pobb.in/ouY4mkkNYb-S +https://pobb.in/a90g42YBMhsW +https://pobb.in/Ba3CrESw8pwL +https://pobb.in/rdHcu3MEVtCV +https://pobb.in/7IUuwkTI203Z +https://pobb.in/wDjmKwMqrqqW +https://pobb.in/ekY1obH52hqJ +https://pobb.in/LJGqqZWfFnPU +https://pobb.in/QGNJ1pWGIPK5 +https://pobb.in/lcLST082wmO0 +https://pobb.in/E0M0PCnEOaf4 +https://pobb.in/7FhQM6rvfhkI +https://pobb.in/aAKn8AEJyJ8n +https://pobb.in/rr7qFsUZxpSH +https://pobb.in/Rp91CLLyDHXU +https://pobb.in/jJME3E1mwQ6x +https://pobb.in/kxKmf-BJfJqT +https://pobb.in/UqvH2efeHzB5 +https://pobb.in/egWgtV1d8iH2 +https://pobb.in/RmXtwiQALDy2 +https://pobb.in/Lipuk3Z1-AdQ +https://pobb.in/kD86OErOjQE2 +https://pobb.in/vlOTOWEwKEv8 +https://pobb.in/Zw4Pp3RgxPlw +https://pastebin.com/wnTVPGMS +https://pobb.in/P3CrdnXe79mU +https://pobb.in/1B8U9yDy_Wot +https://pobb.in/JWqxKBaZCKIi +https://pobb.in/peZH2ped5HpE +https://pobb.in/FXvCmpVGGx5V +https://pobb.in/m8iRz-fn3uuF +https://pobb.in/65mn49zAbxws +https://pobb.in/LxsyUa-yWWEA +https://pobb.in/uRqFMMOWj4ek +https://pobb.in/La6HbUOD8_cj +https://pobb.in/YvevUAopdZ0X +https://pobb.in/K8JyNeqlrtc8 +https://pobb.in/34dqVVWIZkty +https://pobb.in/6f4RyqRtXFU_ +https://pobb.in/y12TnJ8tObgn +https://pobb.in/moB2wtUhTIdB +https://pobb.in/yDr0yZAGgUj2 +https://pobb.in/V4QOuXTmUEES +https://pobb.in/sf4FtBCkwXAX +https://pobb.in/_OcWkcEWx2Hg +https://pobb.in/Qny0dRVqnITx +https://pobb.in/-S2_PaHL8uaX +https://pobb.in/EL-I8fx0HJ7M +https://pobb.in/qVCfgLmjL1rw +https://pobb.in/gXZIKt0z8cTh +https://pobb.in/2kki0_TSLH8M +https://pobb.in/GlzAApkyGTA8 +https://pobb.in/mTScfvMKTiiX +https://pobb.in/Bph43kHofnmV +https://pobb.in/_Wk3GlAEfUBp +https://pobb.in/h10qSifvN5U0 +https://pobb.in/6KGcQzUEMe5j +https://pobb.in/EZ5ZN0MoC94e +https://pobb.in/-CQO5fWQSRgx +https://pobb.in/tdKtccRiRIIm +https://pobb.in/_hfgEK0kcjMM +https://pobb.in/J_o3D0J952BE +https://pobb.in/8flglpMzzdzd +https://pobb.in/wXNw0j5BsXXw +https://pobb.in/WMkbZjhaNpP8 +https://pobb.in/WqflrzpJe15L +https://pobb.in/IY09cMdgFVkt +https://pobb.in/F7sdQa4QPD2_ +https://pobb.in/db_V85_Rj9-F +https://pobb.in/37zpDQwwGmLR +https://pobb.in/y3GwiyC_9y50 +https://pobb.in/uIJifV_JYepr +https://pobb.in/IzpBXdQVHzrG +https://pobb.in/wAW9bHB88p4F +https://pastebin.com/tUkdWJpR +https://pobb.in/f9wVoD5lv-ii +https://pobb.in/-9m6E9RwNtqA +https://pobb.in/MeEVBRxuhzIA +https://pobb.in/u1ACIWcPyWF- +https://pobb.in/sX1lD2ufzLxl +https://pobb.in/0qxEC-t_FPM8 +https://pobb.in/cnfuEVgb6iwe +https://pobb.in/ddoc0Vh7dZ7_ +https://pastebin.com/0HnALex8 +https://pobb.in/tDaxg2Nfv3zf +https://pobb.in/DMKCWkr_ie89 +https://pobb.in/WYgt_b7mVXfr +https://pobb.in/8DhWdsFzhpIk +https://pobb.in/g-2QBxQzV0yB +https://pobb.in/hlRkG9kVS_Z- +https://pobb.in/1dUQWideVatT +https://pobb.in/pqanrUkj78cn +https://pobb.in/4-4fDGHrZjQq +https://pobb.in/jyaHptqLpiDp +https://pobb.in/XEGUbhHv4GWY +https://pobb.in/pP0rCEVYOPjV From ecc4d6182532587505c8c2f4a1d32a76440f46e7 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 5 Jan 2024 10:38:52 +0100 Subject: [PATCH 027/106] FIX: luadiff script --- spec/buildOutputDiff.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/buildOutputDiff.lua b/spec/buildOutputDiff.lua index 3bc5769765e..5b2ebebaafd 100644 --- a/spec/buildOutputDiff.lua +++ b/spec/buildOutputDiff.lua @@ -14,7 +14,7 @@ for key, val in pairs(r) do end end -print("[?] Mismatch count: " .. #mismatch .. " for " .. arg[1] .. " and " arg[2]) +print("[?] Mismatch count: " .. #mismatch .. " for " .. arg[1] .. " and " .. arg[2]) for _, key in ipairs(mismatch) do print(string.format("[%s] mismatch:", key)) print("\t".. arg[1] .. ": " .. tostring(l[key])) From 5434b3ce1f885c656f1c244fe90383ba6b52a717 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 5 Jan 2024 10:52:32 +0100 Subject: [PATCH 028/106] FIX: specify origin for dev ref --- spec/buildDiff.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 4df7baa61b1..db52fb05b00 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -8,7 +8,7 @@ if [[ ! -f "$CACHEDIR/$devref" ]] # Output of builds outdated or nonexistent then rm -rf $CACHEDIR/* cp -rf --parents $WORKDIR /tmp && cd /tmp$WORKDIR && \ - git restore . && git clean -fd && git checkout dev && \ + git restore . && git clean -fd && git checkout origin/dev && \ cp $WORKDIR/.busted /tmp$WORKDIR/.busted && cp $WORKDIR/src/HeadlessWrapper.lua /tmp$WORKDIR/src/HeadlessWrapper.lua && rm -rf /tmp$WORKDIR/spec/ && cp -r $WORKDIR/spec/ /tmp$WORKDIR/spec/ && \ cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 "cat > /tmp/parallel_links_{#}; BUILDLINKS=/tmp/parallel_links_{#} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate; rm /tmp/parallel_links_{#}" && \ BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref" && cd $WORKDIR From 6b86ef63270adf1da0fa4e1a51ae4fee9e237222 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 5 Jan 2024 11:03:53 +0100 Subject: [PATCH 029/106] FIX: fetch a commit from every branch --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d83215602f8..030ef7ea0f3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,6 +19,7 @@ jobs: steps: - name: Checkout HEAD uses: actions/checkout@v4 + - run: git fetch --depth=1 - name: Create cache directory run: mkdir /tmp/Cache - name: Check if build cache exists From e6f44c5e3329d412bf39650f29b10a585eabef02 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 5 Jan 2024 14:50:51 +0100 Subject: [PATCH 030/106] FIX: unknown ref git error --- spec/buildDiff.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index db52fb05b00..12d410b168b 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -2,7 +2,7 @@ cd $WORKDIR git config --global --add safe.directory /workdir headref=$(git rev-parse HEAD) -devref=$(git rev-parse dev) +devref=$(git rev-parse origin/dev) if [[ ! -f "$CACHEDIR/$devref" ]] # Output of builds outdated or nonexistent then From b2a9f554e212d31e9b34bd93b14e4e4ea1a5693f Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sat, 6 Jan 2024 08:11:31 +0100 Subject: [PATCH 031/106] FIX: minor security/convenience improvements --- docker-compose.yml | 9 ++++++--- spec/buildDiff.sh | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7b4fd23e645..d28c9f4b21c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,10 @@ services: busted-tests: #build: . image: ghcr.io/paliak/busted-tests + environment: + HOME: /tmp container_name: busted-tests + user: nobody:nobody command: busted --lua=luajit security_opt: - no-new-privileges:true @@ -17,14 +20,14 @@ services: environment: #Where in the container the folders are stored WORKDIR: /workdir CACHEDIR: /cache + HOME: /tmp container_name: busted-diff tty: true + user: nobody:nobody command: /bin/sh /workdir/spec/buildDiff.sh security_opt: - no-new-privileges:true working_dir: /workdir volumes: - ./:/workdir:ro - - "${CACHEDIR:-busted-diff-cache}:/cache" -volumes: - busted-diff-cache: \ No newline at end of file + - "${CACHEDIR:-/tmp}:/cache" \ No newline at end of file diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 12d410b168b..751dbd16b03 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -1,6 +1,8 @@ #!/bin/sh cd $WORKDIR +umask 0 git config --global --add safe.directory /workdir +git config --global --add advice.detachedHead false headref=$(git rev-parse HEAD) devref=$(git rev-parse origin/dev) From 529336aafc770068128eac89cb19e62f277fac01 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sat, 6 Jan 2024 09:20:37 +0100 Subject: [PATCH 032/106] FEAT: cache downloaded builds --- docker-compose.yml | 2 +- spec/GenerateBuilds.lua | 44 +++++++++++++++++++++++++++-------------- spec/buildDiff.sh | 8 +++++--- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index d28c9f4b21c..b2ae8d17a2b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,4 +30,4 @@ services: working_dir: /workdir volumes: - ./:/workdir:ro - - "${CACHEDIR:-/tmp}:/cache" \ No newline at end of file + - "${CACHEDIR:-/tmp}:/cache" diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index c35739a0868..a380548e28d 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -6,21 +6,36 @@ local function fetchBuilds(path) error(errMsg) end local fileText = fileHnd:read("*a") + fileHnd:close() for line in magiclines( fileText ) do if line ~= "" then - for j=1,#buildSites.websiteList do - if line:match(buildSites.websiteList[j].matchURL) then - -- TODO: cache the downloaded xmls - buildSites.DownloadBuild(line, buildSites.websiteList[j], function(isSuccess, data) - if isSuccess then - coroutine.yield({xml = Inflate(common.base64.decode(data:gsub("-","+"):gsub("_","/"))), filename = line}) - else - print("Failed to download build: " .. line) - end - end) - break - end - end + for j=1,#buildSites.websiteList do + if line:match(buildSites.websiteList[j].matchURL) then + local filename = line:gsub('%W','') + + -- Load from cache if downloaded already + local fileHnd = io.open((os.getenv("CACHEDIR") or "/tmp") .. "/" .. filename .. ".xml", "r") + if fileHnd then + coroutine.yield({xml = fileHnd:read("*a"), filename = filename, link = line}) + fileHnd:close() + else + buildSites.DownloadBuild(line, buildSites.websiteList[j], function(isSuccess, data) + if isSuccess then + local xml = Inflate(common.base64.decode(data:gsub("-","+"):gsub("_","/"))) + coroutine.yield({xml = xml, filename = filename, link = line}) + local xmlHnd = io.open((os.getenv("CACHEDIR") or "/tmp") .. "/" .. filename .. ".xml", "w+") + xmlHnd:write(xml) + xmlHnd:close() + else + print("Failed to download build: " .. line) + end + end) + end + break + elseif j == #buildSites.websiteList then + print("Failed to match provider for: " .. line) + end + end end end else @@ -72,8 +87,7 @@ function buildTable(tableName, values, string) end for testBuild in fetchBuilds("../spec/TestBuilds") do - local filename = testBuild.filename:gsub('%W','') - local filepath = (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/" .. filename + local filepath = (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/" .. testBuild.filename print("[+] Computing ".. filepath) loadBuildFromXML(testBuild.xml) local buildHnd = io.open(filepath .. ".build", "w+") diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 751dbd16b03..8aa2d6e80e7 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -8,18 +8,20 @@ devref=$(git rev-parse origin/dev) if [[ ! -f "$CACHEDIR/$devref" ]] # Output of builds outdated or nonexistent then - rm -rf $CACHEDIR/* + rm $CACHEDIR/*.lua + rm $CACHEDIR/*.build + rm $CACHEDIR/*.xml cp -rf --parents $WORKDIR /tmp && cd /tmp$WORKDIR && \ git restore . && git clean -fd && git checkout origin/dev && \ cp $WORKDIR/.busted /tmp$WORKDIR/.busted && cp $WORKDIR/src/HeadlessWrapper.lua /tmp$WORKDIR/src/HeadlessWrapper.lua && rm -rf /tmp$WORKDIR/spec/ && cp -r $WORKDIR/spec/ /tmp$WORKDIR/spec/ && \ - cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 "cat > /tmp/parallel_links_{#}; BUILDLINKS=/tmp/parallel_links_{#} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate; rm /tmp/parallel_links_{#}" && \ + cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 "cat > /tmp/parallel_links_{#}; BUILDLINKS=/tmp/parallel_links_{#} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate" && \ BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref" && cd $WORKDIR fi if [[ -f "$CACHEDIR/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev then rm -rf /tmp/* - cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 'cat > /tmp/parallel_links_{#}; BUILDLINKS="/tmp/parallel_links_{#}" BUILDCACHEPREFIX="/tmp" busted --lua=luajit -r generate; rm /tmp/parallel_links_{#}' && \ + cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 'cat > /tmp/parallel_links_{#}; BUILDLINKS="/tmp/parallel_links_{#}" BUILDCACHEPREFIX="/tmp" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && echo "[+] Build cache computed for $headref" fi From 6e0829f25e60e07dd6f97cbfcf4261d1d4b969f3 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sat, 6 Jan 2024 09:34:35 +0100 Subject: [PATCH 033/106] FIX: cache folder permissions on github action --- .github/workflows/test.yml | 14 ++++++-------- docker-compose.yml | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 030ef7ea0f3..03868ba7f07 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,16 +20,14 @@ jobs: - name: Checkout HEAD uses: actions/checkout@v4 - run: git fetch --depth=1 - - name: Create cache directory - run: mkdir /tmp/Cache + - name: Get Dev branch HEAD hash + id: get-dev-ref + run: echo "devref=$(git rev-parse origin/dev)" >> $GITHUB_OUTPUT - name: Check if build cache exists - id: cache-builds uses: actions/cache@v3 - env: - cache-name: cached-dev-builds with: - path: /tmp/Cache - key: ${{ github.event.pull_request.base.sha }} + path: /tmp + key: ${{ steps.get-dev-ref.outputs.devref }} - name: Run build diff - run: CACHEDIR="/tmp/Cache" docker-compose up busted-diff + run: docker-compose up busted-diff \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index b2ae8d17a2b..88d8d1375e2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,4 +30,4 @@ services: working_dir: /workdir volumes: - ./:/workdir:ro - - "${CACHEDIR:-/tmp}:/cache" + - /tmp:/cache From 18623c5023b2a739ec92269d641667914ee57a75 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sat, 6 Jan 2024 11:08:58 +0100 Subject: [PATCH 034/106] FIX: temp batch files getting clobbered --- spec/buildDiff.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 8aa2d6e80e7..3505a2f5ec1 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -14,14 +14,14 @@ then cp -rf --parents $WORKDIR /tmp && cd /tmp$WORKDIR && \ git restore . && git clean -fd && git checkout origin/dev && \ cp $WORKDIR/.busted /tmp$WORKDIR/.busted && cp $WORKDIR/src/HeadlessWrapper.lua /tmp$WORKDIR/src/HeadlessWrapper.lua && rm -rf /tmp$WORKDIR/spec/ && cp -r $WORKDIR/spec/ /tmp$WORKDIR/spec/ && \ - cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 "cat > /tmp/parallel_links_{#}; BUILDLINKS=/tmp/parallel_links_{#} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate" && \ + cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS=${LINKSBATCH} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref" && cd $WORKDIR fi if [[ -f "$CACHEDIR/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev then rm -rf /tmp/* - cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 'cat > /tmp/parallel_links_{#}; BUILDLINKS="/tmp/parallel_links_{#}" BUILDCACHEPREFIX="/tmp" busted --lua=luajit -r generate' && \ + cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS=${LINKSBATCH} BUILDCACHEPREFIX="/tmp" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && echo "[+] Build cache computed for $headref" fi From 4190be868ac338edb5eb93183b5c2d16b8aba784 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sat, 6 Jan 2024 11:53:34 +0100 Subject: [PATCH 035/106] FIX: cache folder permissions again --- .github/workflows/test.yml | 11 ++++++++--- docker-compose.yml | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 03868ba7f07..4f210e8ad93 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,15 +19,20 @@ jobs: steps: - name: Checkout HEAD uses: actions/checkout@v4 - - run: git fetch --depth=1 + - name: Fetch Dev branch + run: git fetch --depth=1 - name: Get Dev branch HEAD hash id: get-dev-ref run: echo "devref=$(git rev-parse origin/dev)" >> $GITHUB_OUTPUT + - name: Create cache folder + run: mkdir /tmp/cache/ - name: Check if build cache exists uses: actions/cache@v3 with: - path: /tmp + path: /tmp/cache/ key: ${{ steps.get-dev-ref.outputs.devref }} + - name: Make sure cache is readable by docker + run: chmod -R 777 /tmp/cache - name: Run build diff - run: docker-compose up busted-diff + run: CACHEDIR="/tmp/cache" docker-compose up busted-diff \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 88d8d1375e2..b2ae8d17a2b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,4 +30,4 @@ services: working_dir: /workdir volumes: - ./:/workdir:ro - - /tmp:/cache + - "${CACHEDIR:-/tmp}:/cache" From ea6d72f88c9ded7d08ec686315e810716035d6f6 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 15 Jan 2024 22:02:09 +0100 Subject: [PATCH 036/106] FIX: apply suggestions. Docs wording. Use repo owner in docker label. --- .github/workflows/builddocker.yml | 2 +- CONTRIBUTING.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/builddocker.yml b/.github/workflows/builddocker.yml index 401ecb2cf86..902c118300d 100644 --- a/.github/workflows/builddocker.yml +++ b/.github/workflows/builddocker.yml @@ -25,7 +25,7 @@ jobs: images: | ghcr.io/${{ github.repository_owner }}/busted-tests labels: | - org.opencontainers.image.description=A docker image packaged with the correct verions of tools to run PathOfBuilding busted tests. Includes emmylua debugger files. Refer to https://github.com/Paliak/PathOfBuilding/blob/tests-rework/CONTRIBUTING.md#setting-up-a-development-environment for usage instructions. + org.opencontainers.image.description=A docker image packaged with the correct verions of tools to run PathOfBuilding busted tests. Includes emmylua debugger files. Refer to https://github.com/${{ github.repository_owner }}/PathOfBuilding/blob/tests-rework/CONTRIBUTING.md#setting-up-a-development-environment for usage instructions. org.opencontainers.image.licenses=https://opensource.org/licenses/MIT tags: | type=sha diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7d56e70498d..8c585d33ef3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -158,7 +158,7 @@ To do this in VSCode find the Java installation folder on your computer as displ -- This is the path to emmy_core.dll. The ?.dll at the end is intentional. package.cpath = package.cpath .. ";C:/Users/someuser/.vscode/extensions/tangzx.emmylua-0.3.28/debugger/emmy/windows/x86/?.dll" local dbg = require("emmy_core") --- This port must match the Visual Studio Code configuration. Default is 9966. +-- This port must match the IDE configuration. Default is 9966. dbg.tcpListen("localhost", 9966) -- Uncomment the next line if you want Path of Building to block until the debugger is attached --dbg.waitIDE() @@ -221,7 +221,7 @@ When running tests with a docker container it is possible to use emmylua for deb ```lua package.cpath = package.cpath .. ";/usr/local/bin/?.so" local dbg = require("emmy_core") --- This port must match the Visual Studio Code configuration. Default is 9966. +-- This port must match the IDE Code configuration. Default is 9966. dbg.tcpListen("localhost", 9966) dbg.waitIDE() ``` From 5380e0cf5665e179fb0d936e89bc4f06aae89a2a Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Thu, 18 Jan 2024 05:33:42 +0100 Subject: [PATCH 037/106] FIX: line ending issue on windows --- docker-compose.yml | 2 +- spec/buildDiff.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index b2ae8d17a2b..39776f4ec46 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,7 +24,7 @@ services: container_name: busted-diff tty: true user: nobody:nobody - command: /bin/sh /workdir/spec/buildDiff.sh + command: /bin/sh -c "dos2unix < /workdir/spec/buildDiff.sh | /bin/sh" security_opt: - no-new-privileges:true working_dir: /workdir diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 3505a2f5ec1..3bc2a6778af 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -14,14 +14,14 @@ then cp -rf --parents $WORKDIR /tmp && cd /tmp$WORKDIR && \ git restore . && git clean -fd && git checkout origin/dev && \ cp $WORKDIR/.busted /tmp$WORKDIR/.busted && cp $WORKDIR/src/HeadlessWrapper.lua /tmp$WORKDIR/src/HeadlessWrapper.lua && rm -rf /tmp$WORKDIR/spec/ && cp -r $WORKDIR/spec/ /tmp$WORKDIR/spec/ && \ - cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS=${LINKSBATCH} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate' && \ + cat $WORKDIR/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS=${LINKSBATCH} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref" && cd $WORKDIR fi if [[ -f "$CACHEDIR/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev then rm -rf /tmp/* - cat $WORKDIR/spec/builds.txt | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS=${LINKSBATCH} BUILDCACHEPREFIX="/tmp" busted --lua=luajit -r generate' && \ + cat $WORKDIR/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS=${LINKSBATCH} BUILDCACHEPREFIX="/tmp" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && echo "[+] Build cache computed for $headref" fi From 516df64259856411bc2a4ea3aa6c273fffa51098 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 21 Jan 2024 10:01:22 +0100 Subject: [PATCH 038/106] FIX: rename magiclines func. --- spec/GenerateBuilds.lua | 2 +- src/HeadlessWrapper.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index a380548e28d..e53781995c9 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -7,7 +7,7 @@ local function fetchBuilds(path) end local fileText = fileHnd:read("*a") fileHnd:close() - for line in magiclines( fileText ) do + for line in splitLines( fileText ) do if line ~= "" then for j=1,#buildSites.websiteList do if line:match(buildSites.websiteList[j].matchURL) then diff --git a/src/HeadlessWrapper.lua b/src/HeadlessWrapper.lua index b46e5e975de..1a293494e5b 100644 --- a/src/HeadlessWrapper.lua +++ b/src/HeadlessWrapper.lua @@ -24,7 +24,7 @@ function SetMainObject(obj) end -- https://stackoverflow.com/questions/19326368/iterate-over-lines-including-blank-lines -function magiclines(s) +function splitLines(s) if s:sub(-1)~="\n" then s=s.."\n" end return s:gmatch("(.-)\n") end From a5b0eae2874fece3ce9b9fafdf369f9ece27ee19 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 29 Jan 2024 10:31:59 +0100 Subject: [PATCH 039/106] FIX: GetTime func scale --- src/HeadlessWrapper.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/HeadlessWrapper.lua b/src/HeadlessWrapper.lua index 1a293494e5b..93927823bc4 100644 --- a/src/HeadlessWrapper.lua +++ b/src/HeadlessWrapper.lua @@ -114,7 +114,9 @@ function Inflate(data) return zlib.inflate()(data) end function GetTime() - return os.clock() * 10 + -- os.clock returns cpu time as float in seconds + -- SG GetTime https://github.com/PathOfBuildingCommunity/PathOfBuilding-SimpleGraphic/blob/166d251eefa6bf96ee5f6cd022d08410b7023283/engine/system/win/sys_main.cpp#L541 + return os.clock() * 1000 end function GetScriptPath() return os.getenv("PWD") .. "/src" From 88fab376fe0baa444ffe91d519c537ab5f13726f Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 29 Jan 2024 10:37:57 +0100 Subject: [PATCH 040/106] FEAT: impl save options. Allows for saving full output to xml. --- src/Modules/Build.lua | 105 +++++++++++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 33 deletions(-) diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index 69ecb7f0269..98049842152 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -194,7 +194,7 @@ function buildMode:Init(dbFileName, buildName, buildXML, convertBuild) end if mult > 0.01 then local line = level - if level >= 68 then + if level >= 68 then line = line .. string.format(" (Tier %d)", level - 67) end line = line .. string.format(": %.1f%%", mult * 100) @@ -215,7 +215,7 @@ function buildMode:Init(dbFileName, buildName, buildXML, convertBuild) self.spec:SelectClass(value.classId) self.spec:AddUndoState() self.spec:SetWindowTitleWithBuildClass() - self.buildFlag = true + self.buildFlag = true end) end end @@ -639,7 +639,7 @@ function buildMode:Init(dbFileName, buildName, buildXML, convertBuild) self.legacyLoaders = { -- Special loaders for legacy sections ["Spec"] = self.treeTab, } - + --special rebuild to properly initialise boss placeholders self.configTab:BuildModList() @@ -739,10 +739,10 @@ function buildMode:Init(dbFileName, buildName, buildXML, convertBuild) self.abortSave = false end -local acts = { - [1] = { level = 1, questPoints = 0 }, - [2] = { level = 12, questPoints = 2 }, - [3] = { level = 22, questPoints = 3 }, +local acts = { + [1] = { level = 1, questPoints = 0 }, + [2] = { level = 12, questPoints = 2 }, + [3] = { level = 22, questPoints = 3 }, [4] = { level = 32, questPoints = 5 }, [5] = { level = 40, questPoints = 6 }, [6] = { level = 44, questPoints = 8 }, @@ -767,7 +767,7 @@ function buildMode:EstimatePlayerProgress() act = act + 1 level = m_min(m_max(PointsUsed + 1 - acts[act].questPoints - actExtra(act, extra), acts[act].level), 100) until act == 11 or level <= acts[act + 1].level - + if self.characterLevelAutoMode and self.characterLevel ~= level then self.characterLevel = level self.controls.characterLevel:SetText(self.characterLevel) @@ -781,12 +781,12 @@ function buildMode:EstimatePlayerProgress() or level < 75 and "\nLabyrinth: Merciless Lab" or level < 90 and "\nLabyrinth: Uber Lab" or "" - + if PointsUsed > usedMax then InsertIfNew(self.controls.warnings.lines, "You have too many passive points allocated") end if AscUsed > ascMax then InsertIfNew(self.controls.warnings.lines, "You have too many ascendancy points allocated") end if SecondaryAscUsed > secondaryAscMax then InsertIfNew(self.controls.warnings.lines, "You have too many secondary ascendancy points allocated") end self.Act = level < 90 and act <= 10 and act or "Endgame" - + return string.format("%s%3d / %3d %s%d / %d", PointsUsed > usedMax and colorCodes.NEGATIVE or "^7", PointsUsed, usedMax, AscUsed > ascMax and colorCodes.NEGATIVE or "^7", AscUsed, ascMax), "Required Level: "..level.."\nEstimated Progress:\nAct: "..self.Act.."\nQuestpoints: "..acts[act].questPoints.."\nExtra Skillpoints: "..actExtra(act, extra)..labSuggest end @@ -803,7 +803,7 @@ function buildMode:Shutdown() if launch.devMode and (not main.disableDevAutoSave) and self.targetVersion and not self.abortSave then if self.dbFileName then self:SaveDBFile() - elseif self.unsaved then + elseif self.unsaved then self.dbFileName = main.buildPath.."~~temp~~.xml" self.buildName = "~~temp~~" self.dbFileSubPath = "" @@ -864,7 +864,7 @@ function buildMode:Load(xml, fileName) end end -function buildMode:Save(xml) +function buildMode:Save(xml, options) xml.attrib = { targetVersion = self.targetVersion, viewMode = self.viewMode, @@ -881,7 +881,7 @@ function buildMode:Save(xml) t_insert(xml, { elem = "Spectre", attrib = { id = id } }) end local addedStatNames = { } - for index, statData in ipairs(self.displayStats) do + for _, statData in ipairs(self.displayStats) do if not statData.flag or self.calcsTab.mainEnv.player.mainSkill.skillFlags[statData.flag] then if statData.stat and not addedStatNames[statData.stat] then if statData.stat == "SkillDPS" then @@ -908,22 +908,61 @@ function buildMode:Save(xml) end end end - for index, stat in ipairs(self.extraSaveStats) do - local statVal = self.calcsTab.mainOutput[stat] - if statVal then - t_insert(xml, { elem = "PlayerStat", attrib = { stat = stat, value = tostring(statVal) } }) + + if options.fullPlayerStat then -- Save all of output + local q = {self.calcsTab.mainOutput} + while #q > 0 do + local current = table.remove(q) + for key, val in pairs(current) do + if not addedStatNames[key] then + if type(val) ~= "table" then + t_insert(xml, { elem = "PlayerStat", attrib = { stat = key, value = tostring(val) } }) + elseif key ~= "Minion" then -- Minion stats are processed lower with the MinionStat elem name + table.insert(q,val) + end + addedStatNames[key] = true + end + end + end + else + for _, stat in ipairs(self.extraSaveStats) do + local statVal = self.calcsTab.mainOutput[stat] + if statVal then + t_insert(xml, { elem = "PlayerStat", attrib = { stat = stat, value = tostring(statVal) } }) + end end end + if self.calcsTab.mainEnv.minion then - for index, statData in ipairs(self.minionDisplayStats) do - if statData.stat then - local statVal = self.calcsTab.mainOutput.Minion[statData.stat] - if statVal then - t_insert(xml, { elem = "MinionStat", attrib = { stat = statData.stat, value = tostring(statVal) } }) + local addedMinionStats = {} + if options.fullMinionStat then + local q = {self.calcsTab.mainOutput.Minion} + while #q > 0 do + local current = table.remove(q) + for key, val in pairs(current) do + if not addedMinionStats[key] then + if type(val) ~= "table" then + t_insert(xml, { elem = "MinionStat", attrib = { stat = key, value = tostring(val) } }) + else + table.insert(q,val) + end + addedMinionStats[key] = true + end + end + end + else + for _, statData in ipairs(self.minionDisplayStats) do + if not addedMinionStats[statData.stat] and statData.stat then + local statVal = self.calcsTab.mainOutput.Minion[statData.stat] + if statVal then + t_insert(xml, { elem = "MinionStat", attrib = { stat = statData.stat, value = tostring(statVal) } }) + addedMinionStats[statData.stat] = true + end end end end end + local timelessData = { elem = "TimelessData", attrib = { @@ -1055,7 +1094,7 @@ function buildMode:OnFrame(inputEvents) height = main.screenH - 32 } if self.viewMode == "IMPORT" then - self.importTab:Draw(tabViewPort, inputEvents) + self.importTab:Draw(tabViewPort, inputEvents) elseif self.viewMode == "NOTES" then self.notesTab:Draw(tabViewPort, inputEvents) elseif self.viewMode == "PARTY" then @@ -1204,7 +1243,7 @@ function buildMode:OpenSpectreLibrary() for id in pairs(self.data.spectres) do t_insert(sourceList, id) end - table.sort(sourceList, function(a,b) + table.sort(sourceList, function(a,b) if self.data.minions[a].name == self.data.minions[b].name then return a < b else @@ -1336,7 +1375,7 @@ function buildMode:FormatStat(statData, statVal, overCapStatVal, colorOverride) if statData.label == "Unreserved Life" and statVal == 0 then color = colorCodes.NEGATIVE end - + local valStr = s_format("%"..statData.fmt, val) valStr:gsub("%.", main.decimalSeparator) valStr = color .. formatNumSep(valStr) @@ -1431,8 +1470,8 @@ function buildMode:AddDisplayStatList(statList, actor) end end elseif statData.label and statData.condFunc and statData.condFunc(actor.output) then - t_insert(statBoxList, { - height = 16, labelColor..statData.label..":", + t_insert(statBoxList, { + height = 16, labelColor..statData.label..":", "^7"..actor.output[statData.labelStat].."%^x808080" .. " (" .. statData.val .. ")",}) elseif not statBoxList[#statBoxList] or statBoxList[#statBoxList][1] then t_insert(statBoxList, { height = 6 }) @@ -1587,7 +1626,7 @@ do if omni and (omni > 0 or omni > self.calcsTab.mainOutput.Omni) then t_insert(req, s_format("%s%d ^x7F7F7FOmni", main:StatColor(omni, 0, self.calcsTab.mainOutput.Omni), omni)) end - else + else if str and (str > 14 or str > self.calcsTab.mainOutput.Str) then t_insert(req, s_format("%s%d ^x7F7F7FStr", main:StatColor(str, strBase, self.calcsTab.mainOutput.Str), str)) end @@ -1597,11 +1636,11 @@ do if int and (int > 14 or int > self.calcsTab.mainOutput.Int) then t_insert(req, s_format("%s%d ^x7F7F7FInt", main:StatColor(int, intBase, self.calcsTab.mainOutput.Int), int)) end - end + end if req[1] then tooltip:AddLine(16, "^x7F7F7FRequires "..table.concat(req, "^x7F7F7F, ")) tooltip:AddSeparator(10) - end + end wipeTable(req) end end @@ -1648,20 +1687,20 @@ function buildMode:LoadDBFile() return self:LoadDB(xmlText, self.dbFileName) end -function buildMode:SaveDB(fileName) +function buildMode:SaveDB(fileName, options) local dbXML = { elem = "PathOfBuilding" } -- Save Build section first do local node = { elem = "Build" } - self:Save(node) + self:Save(node, options) t_insert(dbXML, node) end -- Call on all savers to save their data in their respective sections for elem, saver in pairs(self.savers) do local node = { elem = elem } - saver:Save(node) + saver:Save(node, options) t_insert(dbXML, node) end From 5848348961d2d686f288b9f824c409beb20c83c1 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 29 Jan 2024 11:00:56 +0100 Subject: [PATCH 041/106] FIX: docker compose exit code propagation --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4f210e8ad93..203fffa7ab5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Run busted tests - run: docker-compose up busted-tests + run: docker-compose up busted-tests --exit-code-from busted-tests run_build_diff: runs-on: ubuntu-latest @@ -34,5 +34,5 @@ jobs: - name: Make sure cache is readable by docker run: chmod -R 777 /tmp/cache - name: Run build diff - run: CACHEDIR="/tmp/cache" docker-compose up busted-diff + run: CACHEDIR="/tmp/cache" docker-compose up busted-diff --exit-code-from busted-diff \ No newline at end of file From 2df962b12ab05ccce938319935daebe8e91f3ba7 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 29 Jan 2024 11:10:59 +0100 Subject: [PATCH 042/106] FIX: nil deref when save options are not specified. --- src/Modules/Build.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index 98049842152..a4bdde8e3e1 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -909,7 +909,7 @@ function buildMode:Save(xml, options) end end - if options.fullPlayerStat then -- Save all of output + if options and options.fullPlayerStat then -- Save all of output local q = {self.calcsTab.mainOutput} while #q > 0 do local current = table.remove(q) @@ -935,7 +935,7 @@ function buildMode:Save(xml, options) if self.calcsTab.mainEnv.minion then local addedMinionStats = {} - if options.fullMinionStat then + if options and options.fullMinionStat then local q = {self.calcsTab.mainOutput.Minion} while #q > 0 do local current = table.remove(q) From 3faf02edb82155d66c7e05d4573daab3ec18e6cc Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 29 Jan 2024 11:41:40 +0100 Subject: [PATCH 043/106] FEAT: impl build download throttling. Avoids triggering DDOS protection on high core count systems. --- spec/GenerateBuilds.lua | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index e53781995c9..891df0d30b6 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -1,4 +1,5 @@ local function fetchBuilds(path) + local lastDLtime = GetTime() local co = coroutine.create(function(path) if os.getenv("BUILDLINKS") then local fileHnd, errMsg = io.open(os.getenv("BUILDLINKS"), "r") @@ -14,22 +15,29 @@ local function fetchBuilds(path) local filename = line:gsub('%W','') -- Load from cache if downloaded already - local fileHnd = io.open((os.getenv("CACHEDIR") or "/tmp") .. "/" .. filename .. ".xml", "r") + local fileHnd = io.open((os.getenv("CACHEDIR") or "/tmp") .. "/" .. filename .. ".xml", "r") if fileHnd then coroutine.yield({xml = fileHnd:read("*a"), filename = filename, link = line}) fileHnd:close() else - buildSites.DownloadBuild(line, buildSites.websiteList[j], function(isSuccess, data) + -- Throttle build downloads to 5 per second + local timeSinceLastDL = GetTime() - lastDLtime + if timeSinceLastDL < 200 then + posix.nanosleep(0, (200 - timeSinceLastDL) * 1000000) + end + + buildSites.DownloadBuild(line, buildSites.websiteList[j], function(isSuccess, data) + lastDLtime = GetTime() if isSuccess then local xml = Inflate(common.base64.decode(data:gsub("-","+"):gsub("_","/"))) - coroutine.yield({xml = xml, filename = filename, link = line}) local xmlHnd = io.open((os.getenv("CACHEDIR") or "/tmp") .. "/" .. filename .. ".xml", "w+") xmlHnd:write(xml) xmlHnd:close() + coroutine.yield({xml = xml, filename = filename, link = line}) else print("Failed to download build: " .. line) end - end) + end) end break elseif j == #buildSites.websiteList then @@ -57,7 +65,7 @@ local function fetchBuilds(path) end end end) - + return function() local ok, result = coroutine.resume(co, path) if not ok then @@ -66,7 +74,7 @@ local function fetchBuilds(path) return result end end - + function buildTable(tableName, values, string) string = string or "" From a15d7e78c6dc9242683e66581b974cf90ee50fc4 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 2 Feb 2024 01:37:20 +0100 Subject: [PATCH 044/106] FIX: attempt to fix exit-code-from switch missing on gh. --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 203fffa7ab5..4c1bf603a82 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Run busted tests - run: docker-compose up busted-tests --exit-code-from busted-tests + run: docker compose up busted-tests --exit-code-from busted-tests run_build_diff: runs-on: ubuntu-latest @@ -34,5 +34,5 @@ jobs: - name: Make sure cache is readable by docker run: chmod -R 777 /tmp/cache - name: Run build diff - run: CACHEDIR="/tmp/cache" docker-compose up busted-diff --exit-code-from busted-diff + run: CACHEDIR="/tmp/cache" docker compose up busted-diff --exit-code-from busted-diff \ No newline at end of file From 86656dfa883d2c68a695561927891788a0329d23 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 11 Feb 2024 17:04:34 +0100 Subject: [PATCH 045/106] FIX: name comflicts in DFS stat traversal. --- src/Modules/Build.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index 90260b20f1d..ee9b2c99665 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -914,15 +914,15 @@ function buildMode:Save(xml, options) end if options and options.fullPlayerStat then -- Save all of output - local q = {self.calcsTab.mainOutput} + local q = {value = self.calcsTab.mainOutput} while #q > 0 do local current = table.remove(q) - for key, val in pairs(current) do + for key, val in pairs(current.value) do if not addedStatNames[key] then if type(val) ~= "table" then - t_insert(xml, { elem = "PlayerStat", attrib = { stat = key, value = tostring(val) } }) + t_insert(xml, { elem = "PlayerStat", attrib = { stat = (current.key or "")..key, value = tostring(val) } }) elseif key ~= "Minion" then -- Minion stats are processed lower with the MinionStat elem name - table.insert(q,val) + table.insert(q,{key = key, value = val}) end addedStatNames[key] = true end @@ -938,17 +938,17 @@ function buildMode:Save(xml, options) end if self.calcsTab.mainEnv.minion then - local addedMinionStats = {} if options and options.fullMinionStat then - local q = {self.calcsTab.mainOutput.Minion} + local addedMinionStats = {} + local q = {value = self.calcsTab.mainOutput.Minion} while #q > 0 do local current = table.remove(q) - for key, val in pairs(current) do + for key, val in pairs(current.value) do if not addedMinionStats[key] then if type(val) ~= "table" then - t_insert(xml, { elem = "MinionStat", attrib = { stat = key, value = tostring(val) } }) + t_insert(xml, { elem = "MinionStat", attrib = { stat = (current.key or "")..key, value = tostring(val) } }) else - table.insert(q,val) + table.insert(q,{key = key, value = val}) end addedMinionStats[key] = true end From b424234b7b4e9667b580ae842d0c8ed14b7d81ce Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 11 Feb 2024 17:54:49 +0100 Subject: [PATCH 046/106] FIX: format xml into canonical form before diff. --- Dockerfile | 2 +- spec/GenerateBuilds.lua | 25 +------------------------ spec/buildDiff.sh | 9 ++------- spec/buildOutputDiff.lua | 22 ---------------------- 4 files changed, 4 insertions(+), 54 deletions(-) delete mode 100644 spec/buildOutputDiff.lua diff --git a/Dockerfile b/Dockerfile index aabd4f1b065..b61b85f8446 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM alpine:3.18 as base -RUN apk add --no-cache curl unzip openssl build-base readline-dev cmake readline-dev git ca-certificates libcurl curl-dev zlib parallel tar +RUN apk add --no-cache curl unzip openssl build-base readline-dev cmake readline-dev git ca-certificates libcurl curl-dev zlib parallel tar libxml2-utils FROM base as buildbase WORKDIR /opt diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index 891df0d30b6..97dd46dcb72 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -75,34 +75,11 @@ local function fetchBuilds(path) end end - -function buildTable(tableName, values, string) - string = string or "" - string = string .. tableName .. " = {" - for key, value in pairs(values) do - if type(value) == "table" then - buildTable(key, value, string) - elseif type(value) == "boolean" then - string = string .. "[\"" .. key .. "\"] = " .. (value and "true" or "false") .. ",\n" - elseif type(value) == "string" then - string = string .. "[\"" .. key .. "\"] = \"" .. value .. "\",\n" - else - string = string .. "[\"" .. key .. "\"] = " .. round(value, 4) .. ",\n" - end - end - string = string .. "}\n" - return string -end - for testBuild in fetchBuilds("../spec/TestBuilds") do local filepath = (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/" .. testBuild.filename print("[+] Computing ".. filepath) loadBuildFromXML(testBuild.xml) local buildHnd = io.open(filepath .. ".build", "w+") - buildHnd:write(build:SaveDB("Cache")) + buildHnd:write(build:SaveDB("Cache", {fullPlayerStat = true, fullMinionStat = true})) buildHnd:close() - - local outputHnd = io.open(filepath .. ".lua", "w+") - outputHnd:write("return {\n " .. buildTable("output", build.calcsTab.mainOutput) .. "\n}") - outputHnd:close() end \ No newline at end of file diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 3bc2a6778af..682dab0223a 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -27,15 +27,10 @@ fi if [[ -f "/tmp/$headref" ]] # Make sure generating builds for current HEAD was successful then - for build in $CACHEDIR/*.lua - do - luajit $WORKDIR/spec/buildOutputDiff.lua /tmp/$(basename "$build") "$build" - done for build in $CACHEDIR/*.build do BASENAME=$(basename "$build") - echo "[-] Savefile Diff for $BASENAME" - diff "$build" "/tmp/$BASENAME" - echo "[+] Savefile Diff for $BASENAME" + echo "## Savefile Diff for $BASENAME" + diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/$BASENAME") done fi diff --git a/spec/buildOutputDiff.lua b/spec/buildOutputDiff.lua deleted file mode 100644 index 5b2ebebaafd..00000000000 --- a/spec/buildOutputDiff.lua +++ /dev/null @@ -1,22 +0,0 @@ -local l = loadfile(arg[1])().output -local r = loadfile(arg[2])().output -local mismatch = {} - -for key, val in pairs(l) do - if r[key] ~= val then - table.insert(mismatch, key) - end -end - -for key, val in pairs(r) do - if l[key] ~= val then - table.insert(mismatch, key) - end -end - -print("[?] Mismatch count: " .. #mismatch .. " for " .. arg[1] .. " and " .. arg[2]) -for _, key in ipairs(mismatch) do - print(string.format("[%s] mismatch:", key)) - print("\t".. arg[1] .. ": " .. tostring(l[key])) - print("\t".. arg[2] .. ": " .. tostring(r[key])) -end \ No newline at end of file From 14e9317b8a559f151b9b9f31998cb27af3263bc6 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 11 Feb 2024 19:08:31 +0100 Subject: [PATCH 047/106] FIX: only print the header if there's a diff to display. --- spec/buildDiff.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 682dab0223a..a67fb9e1cc8 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -30,7 +30,9 @@ then for build in $CACHEDIR/*.build do BASENAME=$(basename "$build") - echo "## Savefile Diff for $BASENAME" - diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/$BASENAME") + DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/$BASENAME")) || { + echo "## Savefile Diff for $BASENAME" + echo $DIFFOUTPUT + } done fi From dba3a8f76b05d5250af5597285649739e8f0476b Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 11 Feb 2024 19:20:01 +0100 Subject: [PATCH 048/106] FEAT: upload the diff output as an artefact in gha. --- .github/workflows/test.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4c1bf603a82..ad496598eb1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,4 +35,15 @@ jobs: run: chmod -R 777 /tmp/cache - name: Run build diff run: CACHEDIR="/tmp/cache" docker compose up busted-diff --exit-code-from busted-diff + - name: Generate artefact + id: gen-artefact + run: | + docker compose logs --no-log-prefix busted-diff | sed -n '/Savefile Diff for/, $p' > /tmp/artefact + echo "difflength=$(wc -l /tmp/artefact | awk '{print $1}')" >> $GITHUB_OUTPUT + - name: Upload artefact + if: ${{ steps.gen-artefact.outputs.difflength }} != '0' + uses: actions/upload-artifact@v4 + with: + name: build-diff-output + path: /tmp/artefact \ No newline at end of file From 4c9b6fb813b4c71ee166b4abf1137a8b820b2a83 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 11 Feb 2024 22:55:56 +0100 Subject: [PATCH 049/106] FIX: tests failing --- src/Modules/Build.lua | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index ee9b2c99665..cff4c1244bb 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -939,28 +939,23 @@ function buildMode:Save(xml, options) if self.calcsTab.mainEnv.minion then if options and options.fullMinionStat then - local addedMinionStats = {} local q = {value = self.calcsTab.mainOutput.Minion} while #q > 0 do local current = table.remove(q) for key, val in pairs(current.value) do - if not addedMinionStats[key] then - if type(val) ~= "table" then - t_insert(xml, { elem = "MinionStat", attrib = { stat = (current.key or "")..key, value = tostring(val) } }) - else - table.insert(q,{key = key, value = val}) - end - addedMinionStats[key] = true + if type(val) ~= "table" then + t_insert(xml, { elem = "MinionStat", attrib = { stat = (current.key or "")..key, value = tostring(val) } }) + else + table.insert(q,{key = key, value = val}) end end end else for _, statData in ipairs(self.minionDisplayStats) do - if not addedMinionStats[statData.stat] and statData.stat then + if statData.stat then local statVal = self.calcsTab.mainOutput.Minion[statData.stat] if statVal then t_insert(xml, { elem = "MinionStat", attrib = { stat = statData.stat, value = tostring(statVal) } }) - addedMinionStats[statData.stat] = true end end end @@ -1717,7 +1712,6 @@ function buildMode:SaveDB(fileName, options) end end - function buildMode:SaveDBFile() if not self.dbFileName then self:OpenSaveAsPopup() From cb8f0ec47bc2630e3f1d5220546bdb8e2f90bb20 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 11 Feb 2024 23:17:02 +0100 Subject: [PATCH 050/106] FEAT: wrap diff output in markdown block. --- spec/buildDiff.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index a67fb9e1cc8..f31d2095b6e 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -15,14 +15,14 @@ then git restore . && git clean -fd && git checkout origin/dev && \ cp $WORKDIR/.busted /tmp$WORKDIR/.busted && cp $WORKDIR/src/HeadlessWrapper.lua /tmp$WORKDIR/src/HeadlessWrapper.lua && rm -rf /tmp$WORKDIR/spec/ && cp -r $WORKDIR/spec/ /tmp$WORKDIR/spec/ && \ cat $WORKDIR/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS=${LINKSBATCH} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate' && \ - BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref" && cd $WORKDIR + BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" && cd $WORKDIR fi if [[ -f "$CACHEDIR/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev then rm -rf /tmp/* cat $WORKDIR/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS=${LINKSBATCH} BUILDCACHEPREFIX="/tmp" busted --lua=luajit -r generate' && \ - BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && echo "[+] Build cache computed for $headref" + BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && echo "[+] Build cache computed for $headref (headref)" fi if [[ -f "/tmp/$headref" ]] # Make sure generating builds for current HEAD was successful @@ -31,8 +31,10 @@ then do BASENAME=$(basename "$build") DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/$BASENAME")) || { + echo '```diff' echo "## Savefile Diff for $BASENAME" echo $DIFFOUTPUT + echo '```' } done fi From 04d19964b4d2f74cd00acc96d597959f15e1c0a9 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 12 Feb 2024 00:36:08 +0100 Subject: [PATCH 051/106] FEAT: rework buildDiff.sh - Keeps cache inside container instance when running locally - Removes Settings.xml to avoid loading temp builds - Changes repo reset to use git - Works on a repo copy to allow for changes after running tests --- .github/workflows/test.yml | 6 ++-- docker-compose.yml | 2 -- spec/buildDiff.sh | 62 ++++++++++++++++++++------------------ 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ad496598eb1..65f99142e23 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Run busted tests - run: docker compose up busted-tests --exit-code-from busted-tests + run: docker compose run busted-tests run_build_diff: runs-on: ubuntu-latest @@ -27,14 +27,14 @@ jobs: - name: Create cache folder run: mkdir /tmp/cache/ - name: Check if build cache exists - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: /tmp/cache/ key: ${{ steps.get-dev-ref.outputs.devref }} - name: Make sure cache is readable by docker run: chmod -R 777 /tmp/cache - name: Run build diff - run: CACHEDIR="/tmp/cache" docker compose up busted-diff --exit-code-from busted-diff + run: docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff - name: Generate artefact id: gen-artefact run: | diff --git a/docker-compose.yml b/docker-compose.yml index 39776f4ec46..b8eabdb65e9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,7 +19,6 @@ services: image: ghcr.io/paliak/busted-tests environment: #Where in the container the folders are stored WORKDIR: /workdir - CACHEDIR: /cache HOME: /tmp container_name: busted-diff tty: true @@ -30,4 +29,3 @@ services: working_dir: /workdir volumes: - ./:/workdir:ro - - "${CACHEDIR:-/tmp}:/cache" diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index f31d2095b6e..ea2c81bccc2 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -1,40 +1,44 @@ #!/bin/sh -cd $WORKDIR umask 0 -git config --global --add safe.directory /workdir + +# If external cache dir has not been defined keep it inside the container +if [[ -z "$CACHEDIR" ]] +then + mkdir /tmp/cachedir + export CACHEDIR="/tmp/cachedir" +fi + +# Copy mounted workdir to allow for changes during test run +rm -rf /tmp/workdir && mkdir /tmp/workdir && cp -rf $WORKDIR/. /tmp/workdir/ && cd /tmp/workdir + +git config --global --add safe.directory /tmp/workdir git config --global --add advice.detachedHead false headref=$(git rev-parse HEAD) devref=$(git rev-parse origin/dev) +rm -rf /tmp/devref && mkdir /tmp/devref +rm /tmp/workdir/src/Settings.xml +cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="/tmp/devref" busted --lua=luajit -r generate' && \ +BUILDCACHEPREFIX='/tmp/devref' busted --lua=luajit -r generate && date > "/tmp/devref/$headref" && echo "[+] Build cache computed for $headref (headref)" + + if [[ ! -f "$CACHEDIR/$devref" ]] # Output of builds outdated or nonexistent then - rm $CACHEDIR/*.lua - rm $CACHEDIR/*.build - rm $CACHEDIR/*.xml - cp -rf --parents $WORKDIR /tmp && cd /tmp$WORKDIR && \ - git restore . && git clean -fd && git checkout origin/dev && \ - cp $WORKDIR/.busted /tmp$WORKDIR/.busted && cp $WORKDIR/src/HeadlessWrapper.lua /tmp$WORKDIR/src/HeadlessWrapper.lua && rm -rf /tmp$WORKDIR/spec/ && cp -r $WORKDIR/spec/ /tmp$WORKDIR/spec/ && \ - cat $WORKDIR/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS=${LINKSBATCH} BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate' && \ - BUILDCACHEPREFIX=${CACHEDIR} busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" && cd $WORKDIR -fi + rm -rf $CACHEDIR/* -if [[ -f "$CACHEDIR/$devref" ]] #Make sure cache of dev branch builds exists and matches current dev -then - rm -rf /tmp/* - cat $WORKDIR/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS=${LINKSBATCH} BUILDCACHEPREFIX="/tmp" busted --lua=luajit -r generate' && \ - BUILDCACHEPREFIX='/tmp' busted --lua=luajit -r generate && date > "/tmp/$headref" && echo "[+] Build cache computed for $headref (headref)" + # Keep new changes to tests related files + git diff /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/patch && \ + git reset --hard origin/dev && git apply /tmp/patch && \ + cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ + BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" fi -if [[ -f "/tmp/$headref" ]] # Make sure generating builds for current HEAD was successful -then - for build in $CACHEDIR/*.build - do - BASENAME=$(basename "$build") - DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/$BASENAME")) || { - echo '```diff' - echo "## Savefile Diff for $BASENAME" - echo $DIFFOUTPUT - echo '```' - } - done -fi +for build in $CACHEDIR/*.build +do + BASENAME=$(basename "$build") + # Only print the header if there is a diff to display + DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/devref/$BASENAME")) || { + echo "## Savefile Diff for $BASENAME" + echo "\`\`\`diff\n${DIFFOUTPUT}\n\`\`\`" + } +done \ No newline at end of file From 2701fdd757d1a237a01513c2d537dc4bb4f3f134 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 12 Feb 2024 01:40:45 +0100 Subject: [PATCH 052/106] FIX: fill output not being included in xml for test output. --- src/Modules/Build.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index cff4c1244bb..41e11d4d45c 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -914,7 +914,7 @@ function buildMode:Save(xml, options) end if options and options.fullPlayerStat then -- Save all of output - local q = {value = self.calcsTab.mainOutput} + local q = {{value = self.calcsTab.mainOutput}} while #q > 0 do local current = table.remove(q) for key, val in pairs(current.value) do @@ -939,7 +939,7 @@ function buildMode:Save(xml, options) if self.calcsTab.mainEnv.minion then if options and options.fullMinionStat then - local q = {value = self.calcsTab.mainOutput.Minion} + local q = {{value = self.calcsTab.mainOutput.Minion}} while #q > 0 do local current = table.remove(q) for key, val in pairs(current.value) do From 213ee296fb0feeae1a19c9cf2b58eba8fb5ad41d Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 12 Feb 2024 01:50:59 +0100 Subject: [PATCH 053/106] FIX: different approach of avoiding creation of an emppty artefact. --- .github/workflows/test.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 65f99142e23..4b129acd4cb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,12 +36,10 @@ jobs: - name: Run build diff run: docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff - name: Generate artefact - id: gen-artefact run: | docker compose logs --no-log-prefix busted-diff | sed -n '/Savefile Diff for/, $p' > /tmp/artefact - echo "difflength=$(wc -l /tmp/artefact | awk '{print $1}')" >> $GITHUB_OUTPUT + [ -s /tmp/artefact ] || rm /tmp/artefact - name: Upload artefact - if: ${{ steps.gen-artefact.outputs.difflength }} != '0' uses: actions/upload-artifact@v4 with: name: build-diff-output From c27c0b7321c08d67c68a3709aeb901d22982fe76 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 12 Feb 2024 13:38:28 +0100 Subject: [PATCH 054/106] FIX: artefact creation. Log artefact contents. --- .github/workflows/test.yml | 6 +++--- spec/buildDiff.sh | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4b129acd4cb..9bff32cb9bf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Run busted tests - run: docker compose run busted-tests + run: docker compose run --no-TTY busted-tests run_build_diff: runs-on: ubuntu-latest @@ -34,10 +34,10 @@ jobs: - name: Make sure cache is readable by docker run: chmod -R 777 /tmp/cache - name: Run build diff - run: docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff + run: docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' --no-TTY busted-diff - name: Generate artefact run: | - docker compose logs --no-log-prefix busted-diff | sed -n '/Savefile Diff for/, $p' > /tmp/artefact + docker compose logs --no-log-prefix busted-diff | sed -n '/Savefile Diff for/, $p' | tee /tmp/artefact [ -s /tmp/artefact ] || rm /tmp/artefact - name: Upload artefact uses: actions/upload-artifact@v4 diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index ea2c81bccc2..af4b4043fa5 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -39,6 +39,8 @@ do # Only print the header if there is a diff to display DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/devref/$BASENAME")) || { echo "## Savefile Diff for $BASENAME" - echo "\`\`\`diff\n${DIFFOUTPUT}\n\`\`\`" + echo '```diff' + echo $DIFFOUTPUT + echo '```' } done \ No newline at end of file From c04c3c099dd0327d24220a831920ad8bb10f3e25 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 13 Feb 2024 02:28:46 +0100 Subject: [PATCH 055/106] FIX: another attampt at fixing artefact generation --- .github/workflows/test.yml | 4 ++-- spec/buildDiff.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9bff32cb9bf..b2998be717d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,10 +34,10 @@ jobs: - name: Make sure cache is readable by docker run: chmod -R 777 /tmp/cache - name: Run build diff - run: docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' --no-TTY busted-diff + run: docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff | tee /tmp/dockerlog - name: Generate artefact run: | - docker compose logs --no-log-prefix busted-diff | sed -n '/Savefile Diff for/, $p' | tee /tmp/artefact + sed -n '/Savefile Diff for/, $p' /tmp/dockerlog | tee /tmp/artefact [ -s /tmp/artefact ] || rm /tmp/artefact - name: Upload artefact uses: actions/upload-artifact@v4 diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index af4b4043fa5..1c8718844a9 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -40,7 +40,7 @@ do DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/devref/$BASENAME")) || { echo "## Savefile Diff for $BASENAME" echo '```diff' - echo $DIFFOUTPUT + echo "$DIFFOUTPUT" echo '```' } done \ No newline at end of file From 33ca34082165a69ba0ced19204ee60649b4efdd5 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:38:18 +0100 Subject: [PATCH 056/106] FIX: sort player and minion stats to prevent stats from moving arounud in the diff. --- src/Modules/Build.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index 41e11d4d45c..8506492a915 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -962,6 +962,12 @@ function buildMode:Save(xml, options) end end + if options and (options.fullPlayerStat or options.fullMinionStat) then + table.sort(xml, function(a, b) + return a.attrib and b.attrib and (a.elem == "MinionStat" or b.elem == "PlayerStat") and a.attrib.stat < b.attrib.stat + end) + end + local timelessData = { elem = "TimelessData", attrib = { From 325b1ff0bd1dc785818b622526ecc052b9b9741c Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Thu, 15 Feb 2024 18:07:09 +0100 Subject: [PATCH 057/106] FIX: nil compare --- src/Modules/Build.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index 8506492a915..b10c17564e5 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -964,7 +964,7 @@ function buildMode:Save(xml, options) if options and (options.fullPlayerStat or options.fullMinionStat) then table.sort(xml, function(a, b) - return a.attrib and b.attrib and (a.elem == "MinionStat" or b.elem == "PlayerStat") and a.attrib.stat < b.attrib.stat + return a.attrib and a.attrib.stat and b.attrib and b.attrib.stat and (a.elem == "MinionStat" or b.elem == "PlayerStat") and a.attrib.stat < b.attrib.stat end) end From 57f4c516583447b85db3b6f22871c0d65cbe72a7 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 16 Feb 2024 01:33:20 +0100 Subject: [PATCH 058/106] FIX: allow empty git patch --- spec/buildDiff.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 1c8718844a9..1f1ecc1c07a 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -27,8 +27,8 @@ then rm -rf $CACHEDIR/* # Keep new changes to tests related files - git diff /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/patch && \ - git reset --hard origin/dev && git apply /tmp/patch && \ + git diff --no-color /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/patch && \ + git reset --hard origin/dev && git clean -fd && git apply --allow-empty /tmp/patch && \ cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" fi From 3dec1b2256b1b11614964e549687d862613a29a9 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 16 Feb 2024 04:02:48 +0100 Subject: [PATCH 059/106] FIX: download cache not working. GenerateBuild.lua formatting. --- spec/GenerateBuilds.lua | 62 ++++++++++++++++++----------------------- spec/buildDiff.sh | 2 +- 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index 97dd46dcb72..9762aa6a1e0 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -3,21 +3,19 @@ local function fetchBuilds(path) local co = coroutine.create(function(path) if os.getenv("BUILDLINKS") then local fileHnd, errMsg = io.open(os.getenv("BUILDLINKS"), "r") - if not fileHnd then - error(errMsg) - end + if not fileHnd then error(errMsg) end local fileText = fileHnd:read("*a") fileHnd:close() - for line in splitLines( fileText ) do + for line in splitLines(fileText) do if line ~= "" then - for j=1,#buildSites.websiteList do + for j = 1, #buildSites.websiteList do if line:match(buildSites.websiteList[j].matchURL) then - local filename = line:gsub('%W','') + local filename = line:gsub('%W', '') -- Load from cache if downloaded already - local fileHnd = io.open((os.getenv("CACHEDIR") or "/tmp") .. "/" .. filename .. ".xml", "r") + local fileHnd = io.open( (os.getenv("CACHEDIR") or "/tmp") .. "/" .. filename .. ".xml", "r") if fileHnd then - coroutine.yield({xml = fileHnd:read("*a"), filename = filename, link = line}) + coroutine.yield({ xml = fileHnd:read("*a"), filename = filename, link = line }) fileHnd:close() else -- Throttle build downloads to 5 per second @@ -25,17 +23,16 @@ local function fetchBuilds(path) if timeSinceLastDL < 200 then posix.nanosleep(0, (200 - timeSinceLastDL) * 1000000) end - buildSites.DownloadBuild(line, buildSites.websiteList[j], function(isSuccess, data) - lastDLtime = GetTime() + lastDLtime = GetTime() if isSuccess then - local xml = Inflate(common.base64.decode(data:gsub("-","+"):gsub("_","/"))) - local xmlHnd = io.open((os.getenv("CACHEDIR") or "/tmp") .. "/" .. filename .. ".xml", "w+") + local xml = Inflate(common.base64.decode(data:gsub("-", "+"):gsub("_", "/"))) + local xmlHnd = io.open((os.getenv("CACHEDIR") or "/tmp") .. "/" .. filename .. ".xml", "w") xmlHnd:write(xml) xmlHnd:close() - coroutine.yield({xml = xml, filename = filename, link = line}) + coroutine.yield({ xml = xml, filename = filename, link = line }) else - print("Failed to download build: " .. line) + print("Failed to download build: " .. line) end end) end @@ -49,37 +46,32 @@ local function fetchBuilds(path) else for file in lfs.dir(path) do if file ~= "." and file ~= ".." then - local f = path..'/'..file - local attr = lfs.attributes (f) - assert(type(attr) == "table") - if attr.mode ~= "directory" and file:match("^.+(%..+)$") == ".xml" then - local fileHnd, errMsg = io.open(f, "r") - if not fileHnd then - error(errMsg) - end - local fileText = fileHnd:read("*a") - fileHnd:close() - coroutine.yield({xml = fileText, filename = file}) - end + local f = path .. '/' .. file + local attr = lfs.attributes(f) + assert(type(attr) == "table") + if attr.mode ~= "directory" and file:match("^.+(%..+)$") == ".xml" then + local fileHnd, errMsg = io.open(f, "r") + if not fileHnd then error(errMsg) end + local fileText = fileHnd:read("*a") + fileHnd:close() + coroutine.yield({ xml = fileText, filename = file }) + end end end end end) - return function() local ok, result = coroutine.resume(co, path) - if not ok then - error(result) - end + if not ok then error(result) end return result end - end +end for testBuild in fetchBuilds("../spec/TestBuilds") do - local filepath = (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/" .. testBuild.filename - print("[+] Computing ".. filepath) + local filepath = (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/" .. testBuild.filename + print("[+] Computing " .. filepath) loadBuildFromXML(testBuild.xml) local buildHnd = io.open(filepath .. ".build", "w+") - buildHnd:write(build:SaveDB("Cache", {fullPlayerStat = true, fullMinionStat = true})) + buildHnd:write(build:SaveDB("Cache", {fullPlayerStat = true, fullMinionStat = true} )) buildHnd:close() -end \ No newline at end of file +end diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 1f1ecc1c07a..4c7129bc18c 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -24,7 +24,7 @@ BUILDCACHEPREFIX='/tmp/devref' busted --lua=luajit -r generate && date > "/tmp/d if [[ ! -f "$CACHEDIR/$devref" ]] # Output of builds outdated or nonexistent then - rm -rf $CACHEDIR/* + rm -rf $CACHEDIR/*.build # Keep new changes to tests related files git diff --no-color /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/patch && \ From ef374769afd212204ce3c21b6dac92ed7008ef85 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 23 Feb 2024 11:20:23 +0100 Subject: [PATCH 060/106] FIX: use the same version of luajit as new SG. --- Dockerfile | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index b61b85f8446..43c148a223a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,8 +11,14 @@ RUN wget https://luarocks.org/releases/luarocks-3.7.0.tar.gz && tar xf luarocks- RUN cd luarocks-3.7.0 && ./configure && make FROM buildbase as luajit -RUN git clone --depth 1 --branch v2.1.0-beta3 https://github.com/LuaJIT/LuaJIT -RUN cd LuaJIT && make +# Fetch only the wanted commit +RUN mkdir LuaJIT && \ +cd LuaJIT && \ +git init && \ +git remote add origin https://github.com/LuaJIT/LuaJIT && \ +git fetch --depth 1 origin d0e88930ddde28ff662503f9f20facf34f7265aa && \ +git checkout FETCH_HEAD && \ +make FROM buildbase as emmyluadebugger RUN git clone --depth 1 --branch 1.7.1 https://github.com/EmmyLua/EmmyLuaDebugger @@ -22,7 +28,7 @@ FROM base RUN --mount=type=cache,from=buildBase,source=/opt,target=/opt make -C /opt/lua-5.1.5/ install RUN --mount=type=cache,from=luarocks,source=/opt,target=/opt make -C /opt/luarocks-3.7.0/ install -#Install here to install pkgs in pararell with compilation of emmylua and luajit +# Install here to install pkgs in pararell with compilation of emmylua and luajit RUN luarocks install busted RUN luarocks install cluacov RUN luarocks install Lua-cURL From 84de79bc8e50bf7a5816adae9fb66b668e496542 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 23 Feb 2024 11:21:21 +0100 Subject: [PATCH 061/106] FIX: remove batching. The updated luajit should shupport GC64 allowing for more memory usage. This should speed up the tests. --- spec/buildDiff.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 4c7129bc18c..30ffa25a832 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -18,7 +18,7 @@ devref=$(git rev-parse origin/dev) rm -rf /tmp/devref && mkdir /tmp/devref rm /tmp/workdir/src/Settings.xml -cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="/tmp/devref" busted --lua=luajit -r generate' && \ +cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="/tmp/devref" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX='/tmp/devref' busted --lua=luajit -r generate && date > "/tmp/devref/$headref" && echo "[+] Build cache computed for $headref (headref)" @@ -29,7 +29,7 @@ then # Keep new changes to tests related files git diff --no-color /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/patch && \ git reset --hard origin/dev && git clean -fd && git apply --allow-empty /tmp/patch && \ - cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ + cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" fi From 5fd5da7e06a9dc611eef216f3e98e493e317cb26 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 23 Feb 2024 12:29:41 +0100 Subject: [PATCH 062/106] FIX: exit code not propagating up the call chain --- spec/buildDiff.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 30ffa25a832..b1b1e58b81e 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -19,7 +19,7 @@ devref=$(git rev-parse origin/dev) rm -rf /tmp/devref && mkdir /tmp/devref rm /tmp/workdir/src/Settings.xml cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="/tmp/devref" busted --lua=luajit -r generate' && \ -BUILDCACHEPREFIX='/tmp/devref' busted --lua=luajit -r generate && date > "/tmp/devref/$headref" && echo "[+] Build cache computed for $headref (headref)" +BUILDCACHEPREFIX='/tmp/devref' busted --lua=luajit -r generate && date > "/tmp/devref/$headref" && echo "[+] Build cache computed for $headref (headref)" || exit $? if [[ ! -f "$CACHEDIR/$devref" ]] # Output of builds outdated or nonexistent @@ -30,7 +30,7 @@ then git diff --no-color /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/patch && \ git reset --hard origin/dev && git clean -fd && git apply --allow-empty /tmp/patch && \ cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ - BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" + BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" || exit $? fi for build in $CACHEDIR/*.build @@ -43,4 +43,4 @@ do echo "$DIFFOUTPUT" echo '```' } -done \ No newline at end of file +done From cd9640d9a270d50b64918a7c901e1d6c5abed134 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 23 Feb 2024 19:33:15 +0100 Subject: [PATCH 063/106] Revert "FIX: use the same version of luajit as new SG." This reverts commit ef374769afd212204ce3c21b6dac92ed7008ef85. Roll back to older version as the newer one seems to be significantly slower for some reason. --- Dockerfile | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 43c148a223a..b61b85f8446 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,14 +11,8 @@ RUN wget https://luarocks.org/releases/luarocks-3.7.0.tar.gz && tar xf luarocks- RUN cd luarocks-3.7.0 && ./configure && make FROM buildbase as luajit -# Fetch only the wanted commit -RUN mkdir LuaJIT && \ -cd LuaJIT && \ -git init && \ -git remote add origin https://github.com/LuaJIT/LuaJIT && \ -git fetch --depth 1 origin d0e88930ddde28ff662503f9f20facf34f7265aa && \ -git checkout FETCH_HEAD && \ -make +RUN git clone --depth 1 --branch v2.1.0-beta3 https://github.com/LuaJIT/LuaJIT +RUN cd LuaJIT && make FROM buildbase as emmyluadebugger RUN git clone --depth 1 --branch 1.7.1 https://github.com/EmmyLua/EmmyLuaDebugger @@ -28,7 +22,7 @@ FROM base RUN --mount=type=cache,from=buildBase,source=/opt,target=/opt make -C /opt/lua-5.1.5/ install RUN --mount=type=cache,from=luarocks,source=/opt,target=/opt make -C /opt/luarocks-3.7.0/ install -# Install here to install pkgs in pararell with compilation of emmylua and luajit +#Install here to install pkgs in pararell with compilation of emmylua and luajit RUN luarocks install busted RUN luarocks install cluacov RUN luarocks install Lua-cURL From b80b4c5e9fea2f0d00bdbd3f7cdaa67d4f199791 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 23 Feb 2024 19:36:08 +0100 Subject: [PATCH 064/106] Revert "FIX: remove batching." This reverts commit 84de79bc8e50bf7a5816adae9fb66b668e496542. Re-add batching as the older luajit will run out of memory after roughly 70 builds. --- spec/buildDiff.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index b1b1e58b81e..1181073585b 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -18,10 +18,9 @@ devref=$(git rev-parse origin/dev) rm -rf /tmp/devref && mkdir /tmp/devref rm /tmp/workdir/src/Settings.xml -cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="/tmp/devref" busted --lua=luajit -r generate' && \ +cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="/tmp/devref" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX='/tmp/devref' busted --lua=luajit -r generate && date > "/tmp/devref/$headref" && echo "[+] Build cache computed for $headref (headref)" || exit $? - if [[ ! -f "$CACHEDIR/$devref" ]] # Output of builds outdated or nonexistent then rm -rf $CACHEDIR/*.build @@ -29,7 +28,7 @@ then # Keep new changes to tests related files git diff --no-color /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/patch && \ git reset --hard origin/dev && git clean -fd && git apply --allow-empty /tmp/patch && \ - cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ + cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" || exit $? fi From c78ad3bd57ea5560b83085c29261edf6ecba6485 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 1 Mar 2024 21:50:28 +0100 Subject: [PATCH 065/106] FEAT: add output only diff. --- spec/buildDiff.sh | 9 ++++++ spec/diffOutput.lua | 72 +++++++++++++++++++++++++++++++++++++++++++ src/Modules/Build.lua | 6 ---- 3 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 spec/diffOutput.lua diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 1181073585b..46bc30547f0 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -35,6 +35,7 @@ fi for build in $CACHEDIR/*.build do BASENAME=$(basename "$build") + # Only print the header if there is a diff to display DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/devref/$BASENAME")) || { echo "## Savefile Diff for $BASENAME" @@ -42,4 +43,12 @@ do echo "$DIFFOUTPUT" echo '```' } + + # Dedicated output diff + DIFFOUTPUT=$(luajit spec/diffOutput.lua "$build" "/tmp/devref/$BASENAME") || { + echo "## Output Diff for $BASENAME" + echo '```' + echo "$DIFFOUTPUT" + echo '```' + } done diff --git a/spec/diffOutput.lua b/spec/diffOutput.lua new file mode 100644 index 00000000000..5f3228f21c0 --- /dev/null +++ b/spec/diffOutput.lua @@ -0,0 +1,72 @@ +-- https://stackoverflow.com/questions/19326368/iterate-over-lines-including-blank-lines +local function splitLines(s) + if s:sub(-1)~="\n" then s=s.."\n" end + return s:gmatch("(.-)\n") +end + +local function buildOutputMap(filecontent) + local playerOutput = {} + local minionOutput = {} + for line in splitLines(filecontent) do + local key, val = line:match('PlayerStat stat="(.-)" value="(.-)"') + if key then + playerOutput[key] = val + else + local key,val = line:match('MinionStat stat="(.-)" value="(.-)"') + if key then + minionOutput[key] = val + end + end + end + return playerOutput, minionOutput +end + +local headhnd = io.open(arg[1], "r") +local devhnd = io.open(arg[2], "r") + +if headhnd and devhnd then + local playerHEADOutput, minionHEADOutput = buildOutputMap(headhnd:read("*a")) + local playerDEVOutput, minionDEVOutput = buildOutputMap(devhnd:read("*a")) + local mismatch = {} + local mismatchFound = false + for key, val in pairs(playerHEADOutput) do + if not playerDEVOutput[key] or playerDEVOutput[key] ~= val then + mismatch[key] = {devOutput = playerDEVOutput[key], headOutput = val} + mismatchFound = true + end + end + for key, val in pairs(playerDEVOutput) do + if not mismatch[key] and (not playerHEADOutput[key] or playerHEADOutput[key] ~= val) then + mismatch[key] = {headOutput = playerHEADOutput[key], devOutput = val} + mismatchFound = true + end + end + for key, val in pairs(mismatch) do + print(key .. " Mismatch in player outputs: ") + print("\t" .."head Output: " .. tostring(val["headOutput"])) + print("\t" .."dev Output: " .. tostring(val["devOutput"])) + end + mismatch = {} + for key, val in pairs(minionHEADOutput) do + if not minionDEVOutput[key] or minionDEVOutput[key] ~= val then + mismatch[key] = {devOutput = minionDEVOutput[key], headOutput = val} + mismatchFound = true + end + end + for key, val in pairs(minionDEVOutput) do + if not mismatch[key] and (not minionHEADOutput[key] or minionHEADOutput[key] ~= val) then + mismatch[key] = {headOutput = minionHEADOutput[key], devOutput = val} + mismatchFound = true + end + end + for key, val in pairs(mismatch) do + print(key .. " Mismatch in minion outputs: ") + print("\t" .."head Output: " .. tostring(val["headOutput"])) + print("\t" .."dev Output: " .. tostring(val["devOutput"])) + end + if mismatchFound then + os.exit(1) -- Make the exit codes of the script match the exit codes of the diff utility + end +else + os.exit(2) +end \ No newline at end of file diff --git a/src/Modules/Build.lua b/src/Modules/Build.lua index b10c17564e5..41e11d4d45c 100644 --- a/src/Modules/Build.lua +++ b/src/Modules/Build.lua @@ -962,12 +962,6 @@ function buildMode:Save(xml, options) end end - if options and (options.fullPlayerStat or options.fullMinionStat) then - table.sort(xml, function(a, b) - return a.attrib and a.attrib.stat and b.attrib and b.attrib.stat and (a.elem == "MinionStat" or b.elem == "PlayerStat") and a.attrib.stat < b.attrib.stat - end) - end - local timelessData = { elem = "TimelessData", attrib = { From b049b8d2cde2719d41a7c950a1ac77d0418d5edb Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sat, 2 Mar 2024 17:45:43 +0100 Subject: [PATCH 066/106] FIX: rename folder as it actually contains headref --- spec/buildDiff.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 46bc30547f0..c761655aec1 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -16,10 +16,10 @@ git config --global --add advice.detachedHead false headref=$(git rev-parse HEAD) devref=$(git rev-parse origin/dev) -rm -rf /tmp/devref && mkdir /tmp/devref +rm -rf /tmp/headref && mkdir /tmp/headref rm /tmp/workdir/src/Settings.xml -cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="/tmp/devref" busted --lua=luajit -r generate' && \ -BUILDCACHEPREFIX='/tmp/devref' busted --lua=luajit -r generate && date > "/tmp/devref/$headref" && echo "[+] Build cache computed for $headref (headref)" || exit $? +cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="/tmp/headref" busted --lua=luajit -r generate' && \ +BUILDCACHEPREFIX='/tmp/headref' busted --lua=luajit -r generate && date > "/tmp/headref/$headref" && echo "[+] Build cache computed for $headref (headref)" || exit $? if [[ ! -f "$CACHEDIR/$devref" ]] # Output of builds outdated or nonexistent then @@ -37,7 +37,7 @@ do BASENAME=$(basename "$build") # Only print the header if there is a diff to display - DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/devref/$BASENAME")) || { + DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/headref/$BASENAME")) || { echo "## Savefile Diff for $BASENAME" echo '```diff' echo "$DIFFOUTPUT" @@ -45,7 +45,7 @@ do } # Dedicated output diff - DIFFOUTPUT=$(luajit spec/diffOutput.lua "$build" "/tmp/devref/$BASENAME") || { + DIFFOUTPUT=$(luajit spec/diffOutput.lua "$build" "/tmp/headref/$BASENAME") || { echo "## Output Diff for $BASENAME" echo '```' echo "$DIFFOUTPUT" From a5a7df86ed1b98f8655b209bea6d84d01e367476 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:33:53 +0100 Subject: [PATCH 067/106] FIX: stricter download limits --- spec/GenerateBuilds.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index 9762aa6a1e0..0853f01f874 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -18,10 +18,10 @@ local function fetchBuilds(path) coroutine.yield({ xml = fileHnd:read("*a"), filename = filename, link = line }) fileHnd:close() else - -- Throttle build downloads to 5 per second + -- Throttle build downloads to 15 per 10 seconds local timeSinceLastDL = GetTime() - lastDLtime - if timeSinceLastDL < 200 then - posix.nanosleep(0, (200 - timeSinceLastDL) * 1000000) + if timeSinceLastDL < 666 then + posix.nanosleep(0, (666 - timeSinceLastDL) * 1000000) end buildSites.DownloadBuild(line, buildSites.websiteList[j], function(isSuccess, data) lastDLtime = GetTime() From 197f897478dded720ea8561703132736ef87258a Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:52:49 +0100 Subject: [PATCH 068/106] FIX: curl user agent --- src/HeadlessWrapper.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/HeadlessWrapper.lua b/src/HeadlessWrapper.lua index 93927823bc4..648a9e4c93a 100644 --- a/src/HeadlessWrapper.lua +++ b/src/HeadlessWrapper.lua @@ -182,6 +182,9 @@ function Exit() end dofile("Launch.lua") +-- The CI env var will be true when run from github workflows but should be false for other tools using the headless wrapper +mainObject.continuousIntegrationMode = os.getenv("CI") + function launch:DownloadPage(url, callback, params) params = params or {} local responseHeader = "" @@ -197,7 +200,7 @@ function launch:DownloadPage(url, callback, params) easy:setopt(curl.OPT_HTTPHEADER, header) end easy:setopt_url(url) - easy:setopt(curl.OPT_USERAGENT, "Path of Building/]]..self.versionNumber..[[") + easy:setopt(curl.OPT_USERAGENT, "Headless Path of Building" .. (mainObject.continuousIntegrationMode and " CI" or "") .. "/"..launch.versionNumber) easy:setopt(curl.OPT_ACCEPT_ENCODING, "") if params.body then easy:setopt(curl.OPT_POST, true) @@ -232,9 +235,6 @@ function launch:DownloadPage(url, callback, params) callback({header=responseHeader, body=responseBody}, errMsg) end --- The CI env var will be true when run from github workflows but should be false for other tools using the headless wrapper -mainObject.continuousIntegrationMode = os.getenv("CI") - runCallback("OnInit") runCallback("OnFrame") -- Need at least one frame for everything to initialise From 8394e2f824f6f7fdea032852d03278605c89bceb Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 8 Mar 2024 20:33:21 +0100 Subject: [PATCH 069/106] FIX: staged changes to tests code not applying to devref. --- spec/buildDiff.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index c761655aec1..1b4b63afb98 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -26,7 +26,7 @@ then rm -rf $CACHEDIR/*.build # Keep new changes to tests related files - git diff --no-color /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/patch && \ + git diff --no-color origin/dev -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/patch && \ git reset --hard origin/dev && git clean -fd && git apply --allow-empty /tmp/patch && \ cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" || exit $? From 82248ec73b03e542499b349bf7f4e1fd8c6933bc Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 26 Mar 2024 00:24:11 +0100 Subject: [PATCH 070/106] FEAT: tweaks to existing workflows Limit workflows to only run on the main POB repo and not forks (can be modified by fork authors). Limit concurency on build diff to limit build code provider bandwidth. --- .github/workflows/beta.yml | 35 ++++++++++--------- .github/workflows/{test.yml => buildtest.yml} | 17 ++++----- .github/workflows/unittest.yml | 16 +++++++++ 3 files changed, 40 insertions(+), 28 deletions(-) rename .github/workflows/{test.yml => buildtest.yml} (82%) create mode 100644 .github/workflows/unittest.yml diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml index eb680fc79c1..8ebb7b59eac 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/beta.yml @@ -1,5 +1,5 @@ name: Push beta branch -on: +on: schedule: - cron: '0 0 * * 5' push: @@ -8,21 +8,22 @@ on: workflow_dispatch: jobs: push-beta: + if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' runs-on: ubuntu-22.04 steps: - - name: Set line endings - run: git config --global core.autocrlf true - - name: Checkout - uses: actions/checkout@v3 - with: - ref: 'dev' - - name: Configure bot user - run: | - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - - name: Update manifest.xml - run: python3 update_manifest.py --quiet --in-place - - name: Push to beta branch - run: | - git commit -am "Weekly beta release" --allow-empty --author="github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" - git push origin HEAD:beta --force + - name: Set line endings + run: git config --global core.autocrlf true + - name: Checkout + uses: actions/checkout@v3 + with: + ref: 'dev' + - name: Configure bot user + run: | + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + - name: Update manifest.xml + run: python3 update_manifest.py --quiet --in-place + - name: Push to beta branch + run: | + git commit -am "Weekly beta release" --allow-empty --author="github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" + git push origin HEAD:beta --force diff --git a/.github/workflows/test.yml b/.github/workflows/buildtest.yml similarity index 82% rename from .github/workflows/test.yml rename to .github/workflows/buildtest.yml index b2998be717d..a9c730a9027 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/buildtest.yml @@ -1,20 +1,15 @@ name: Run Tests on: - workflow_dispatch: - push: - branches: [ dev ] pull_request: branches: [ dev ] -jobs: - run_unit_tests: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Run busted tests - run: docker compose run --no-TTY busted-tests +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: run_build_diff: + if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' runs-on: ubuntu-latest steps: - name: Checkout HEAD diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml new file mode 100644 index 00000000000..20eed9fded1 --- /dev/null +++ b/.github/workflows/unittest.yml @@ -0,0 +1,16 @@ +name: Run Unit Tests +on: + workflow_dispatch: + push: + branches: [ dev ] + pull_request: + branches: [ dev ] + +jobs: + run_unit_tests: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Run busted tests + run: docker compose run --no-TTY busted-tests \ No newline at end of file From 469115dd4b59f851dc877eed779b2baf756cdf29 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 26 Mar 2024 00:25:47 +0100 Subject: [PATCH 071/106] FEAT: add automatic test build list update --- .github/workflows/updatebuildlist.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/updatebuildlist.yml diff --git a/.github/workflows/updatebuildlist.yml b/.github/workflows/updatebuildlist.yml new file mode 100644 index 00000000000..cf74aa23345 --- /dev/null +++ b/.github/workflows/updatebuildlist.yml @@ -0,0 +1,27 @@ +name: Update build list for tests +on: + schedule: + - cron: '20 4 * * *' + workflow_dispatch: + +jobs: + push-beta: + if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' + runs-on: ubuntu-22.04 + steps: + - name: Download old build list + uses: actions/download-artifact@v4 + with: + name: test-build-list + - name: Update list + run: | + cat builds.txt <({ curl "https://pobarchives.com/api/builds?q=latest" & curl "https://pobarchives.com/api/builds?q=trending"; } | jq -r '.builds[].build_info.build_link') | sort -u | tail -n 500 | sponge builds.txt + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: test-build-list + path: builds.txt + overwrite: true + if-no-files-found: error + + From ed845203578f0b0ce55434d34671efeb9b943b22 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 26 Mar 2024 09:44:42 +0100 Subject: [PATCH 072/106] FIX: yaml formatting --- .github/workflows/beta.yml | 22 +++++++++++----------- .github/workflows/buildtest.yml | 20 +++++++++----------- .github/workflows/unittest.yml | 9 +++++---- .github/workflows/updatebuildlist.yml | 8 ++------ 4 files changed, 27 insertions(+), 32 deletions(-) diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml index 8ebb7b59eac..a353d400a26 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/beta.yml @@ -4,26 +4,26 @@ on: - cron: '0 0 * * 5' push: branches: - - 'master' + - master workflow_dispatch: jobs: push-beta: if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' runs-on: ubuntu-22.04 steps: - - name: Set line endings + - name: Set line endings run: git config --global core.autocrlf true - - name: Checkout + - name: Checkout uses: actions/checkout@v3 with: - ref: 'dev' - - name: Configure bot user + ref: dev + - name: Configure bot user run: | - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global user.name "github-actions[bot]" - - name: Update manifest.xml + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + - name: Update manifest.xml run: python3 update_manifest.py --quiet --in-place - - name: Push to beta branch + - name: Push to beta branch run: | - git commit -am "Weekly beta release" --allow-empty --author="github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" - git push origin HEAD:beta --force + git commit -am "Weekly beta release" --allow-empty --author="github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>" + git push origin HEAD:beta --force diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index a9c730a9027..ffa3f6a37bf 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -1,12 +1,11 @@ name: Run Tests on: pull_request: - branches: [ dev ] - + branches: + - dev concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: '${{ github.workflow }}-${{ github.ref }}' cancel-in-progress: true - jobs: run_build_diff: if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' @@ -25,18 +24,17 @@ jobs: uses: actions/cache@v4 with: path: /tmp/cache/ - key: ${{ steps.get-dev-ref.outputs.devref }} + key: '${{ steps.get-dev-ref.outputs.devref }}' - name: Make sure cache is readable by docker run: chmod -R 777 /tmp/cache - name: Run build diff run: docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff | tee /tmp/dockerlog - name: Generate artefact - run: | - sed -n '/Savefile Diff for/, $p' /tmp/dockerlog | tee /tmp/artefact - [ -s /tmp/artefact ] || rm /tmp/artefact + run: | + sed -n '/Savefile Diff for/, $p' /tmp/dockerlog | tee /tmp/artefact + [ -s /tmp/artefact ] || rm /tmp/artefact - name: Upload artefact uses: actions/upload-artifact@v4 with: - name: build-diff-output - path: /tmp/artefact - \ No newline at end of file + name: build-diff-output + path: /tmp/artefact diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index 20eed9fded1..43d280673ce 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -2,10 +2,11 @@ name: Run Unit Tests on: workflow_dispatch: push: - branches: [ dev ] + branches: + - dev pull_request: - branches: [ dev ] - + branches: + - dev jobs: run_unit_tests: runs-on: ubuntu-latest @@ -13,4 +14,4 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Run busted tests - run: docker compose run --no-TTY busted-tests \ No newline at end of file + run: docker compose run --no-TTY busted-tests diff --git a/.github/workflows/updatebuildlist.yml b/.github/workflows/updatebuildlist.yml index cf74aa23345..f7c1b2ec233 100644 --- a/.github/workflows/updatebuildlist.yml +++ b/.github/workflows/updatebuildlist.yml @@ -1,9 +1,8 @@ name: Update build list for tests -on: +on: schedule: - cron: '20 4 * * *' workflow_dispatch: - jobs: push-beta: if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' @@ -14,8 +13,7 @@ jobs: with: name: test-build-list - name: Update list - run: | - cat builds.txt <({ curl "https://pobarchives.com/api/builds?q=latest" & curl "https://pobarchives.com/api/builds?q=trending"; } | jq -r '.builds[].build_info.build_link') | sort -u | tail -n 500 | sponge builds.txt + run: cat builds.txt <({ curl "https://pobarchives.com/api/builds?q=latest" & curl "https://pobarchives.com/api/builds?q=trending"; } | jq -r '.builds[].build_info.build_link') | sort -u | tail -n 500 | sponge builds.txt - name: Upload Artifact uses: actions/upload-artifact@v4 with: @@ -23,5 +21,3 @@ jobs: path: builds.txt overwrite: true if-no-files-found: error - - From c040cb8fec922d0da63de55ad33c015ac32df23e Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:18:05 +0200 Subject: [PATCH 073/106] FIX: flipped arguments dev<-->head --- spec/buildDiff.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 1b4b63afb98..eb971677feb 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -45,7 +45,7 @@ do } # Dedicated output diff - DIFFOUTPUT=$(luajit spec/diffOutput.lua "$build" "/tmp/headref/$BASENAME") || { + DIFFOUTPUT=$(luajit spec/diffOutput.lua "/tmp/headref/$BASENAME" "$build") || { echo "## Output Diff for $BASENAME" echo '```' echo "$DIFFOUTPUT" From d8422a872c9c1d508c1713293a06f3be42961bfe Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:19:45 +0200 Subject: [PATCH 074/106] FIX: specify latest version in the compose file --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index b8eabdb65e9..2d0e871125e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ services: busted-tests: #build: . - image: ghcr.io/paliak/busted-tests + image: ghcr.io/paliak/busted-tests:latest environment: HOME: /tmp container_name: busted-tests @@ -16,7 +16,7 @@ services: - ./:/workdir:ro busted-diff: #build: . - image: ghcr.io/paliak/busted-tests + image: ghcr.io/paliak/busted-tests:latest environment: #Where in the container the folders are stored WORKDIR: /workdir HOME: /tmp From 6f4d79b0e96c9d682c46544c31915760f619a9da Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Fri, 28 Jun 2024 17:53:13 +0200 Subject: [PATCH 075/106] WIP: testing builds.txt update logic --- .github/workflows/buildtest.yml | 7 +- .github/workflows/updatebuildlist.yml | 16 +- spec/builds.txt | 495 -------------------------- 3 files changed, 12 insertions(+), 506 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index ffa3f6a37bf..69dae4b5026 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -8,7 +8,7 @@ concurrency: cancel-in-progress: true jobs: run_build_diff: - if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' + #if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' runs-on: ubuntu-latest steps: - name: Checkout HEAD @@ -25,6 +25,11 @@ jobs: with: path: /tmp/cache/ key: '${{ steps.get-dev-ref.outputs.devref }}' + - name: Download new build list + uses: actions/cache@v4 + with: + path: spec/builds.txt + key: 'builds.txt' - name: Make sure cache is readable by docker run: chmod -R 777 /tmp/cache - name: Run build diff diff --git a/.github/workflows/updatebuildlist.yml b/.github/workflows/updatebuildlist.yml index f7c1b2ec233..18029b95c21 100644 --- a/.github/workflows/updatebuildlist.yml +++ b/.github/workflows/updatebuildlist.yml @@ -5,19 +5,15 @@ on: workflow_dispatch: jobs: push-beta: - if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' + #if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' runs-on: ubuntu-22.04 steps: + - name: Checkout HEAD + uses: actions/checkout@v4 - name: Download old build list - uses: actions/download-artifact@v4 + uses: actions/cache@v4 with: - name: test-build-list + path: spec/builds.txt + key: 'builds.txt' - name: Update list run: cat builds.txt <({ curl "https://pobarchives.com/api/builds?q=latest" & curl "https://pobarchives.com/api/builds?q=trending"; } | jq -r '.builds[].build_info.build_link') | sort -u | tail -n 500 | sponge builds.txt - - name: Upload Artifact - uses: actions/upload-artifact@v4 - with: - name: test-build-list - path: builds.txt - overwrite: true - if-no-files-found: error diff --git a/spec/builds.txt b/spec/builds.txt index 151125595df..491ed25adbb 100644 --- a/spec/builds.txt +++ b/spec/builds.txt @@ -1,496 +1 @@ https://pobb.in/IE4NagN7GTSG -https://pobb.in/JMVIpB8NfS3W -https://pobb.in/PadeL7jl7LOf -https://pobb.in/LWMgGFgeY1OA -https://pobb.in/q_zvdst3wVY8 -https://pobb.in/wYMBCn6VMnMH -https://pobb.in/9Zk2dHONu60p -https://pobb.in/QYMalBGKpank -https://pobb.in/TaEKdjV0Q6op -https://pobb.in/S9aqRfwcRkig -https://pobb.in/l8yyxQSve0-q -https://pobb.in/uDXPObcS5Umk -https://pobb.in/ibssLb49uDS3 -https://pobb.in/Be-pUqssGfa0 -https://pobb.in/TElsp5oR8Nsg -https://pobb.in/bECv3LzPKBKo -https://pobb.in/wDLFVhLgWirR -https://pobb.in/hK_Y2CnOWZ4F -https://pobb.in/54U-kgJ4MRKu -https://pobb.in/ki6HrllV1aB8 -https://pobb.in/SFslJqvR7cfk -https://pobb.in/Hsa-VHPxZoIY -https://pobb.in/j0pMpMx3_TU0 -https://pobb.in/AjXV0g6w6CGl -https://pobb.in/Wq7-YT2p1vZE -https://pobb.in/xYp-wwPp8a3y -https://pobb.in/Z2Mvl7EeuCxV -https://pobb.in/R2KCSu20A0x1 -https://pobb.in/smbctdc34cfH -https://pobb.in/eveJpzFgpABq -https://pobb.in/kQDsMsssM7Cd -https://pobb.in/IR-wmUnzNb5t -https://pobb.in/zja6gYi85Vi- -https://pobb.in/Gmy8Ha5XjlxH -https://pobb.in/bopGfR_OtxAd -https://pobb.in/eK0GthXVFTli -https://pobb.in/eGEoXF_1JMdv -https://pobb.in/TNseXhh0s34I -https://pobb.in/HjFpaJopbgkn -https://pobb.in/upwMs8RD7tqc -https://pobb.in/oTC_P19aN0mw -https://pobb.in/nyUDdl-MeE0i -https://pobb.in/tE1ikJ5jhvsQ -https://pobb.in/9eiU4SQvNhVn -https://pobb.in/Sf2cUlge3cXA -https://pobb.in/WNHPmLkPheCX -https://pobb.in/FXTjzI2no-iV -https://pobb.in/DEjQ59pJ6cep -https://pobb.in/jZmghaat0TTG -https://pobb.in/DjWB3Yn4PQpk -https://pobb.in/mi9rConMt-54 -https://pobb.in/KaB-X8C_HnwY -https://pobb.in/H3kffOAomNKu -https://pobb.in/81Q8t9QQHNsV -https://pobb.in/8af4qRbuvqeU -https://pobb.in/4wM1Zr7K4Cwh -https://pobb.in/oEb8wRv8BOej -https://pobb.in/V1-geRkxnEcP -https://pobb.in/96VEtNXW6rJc -https://pobb.in/ncOsN44is4np -https://pobb.in/ujB8-bN7xp-U -https://pobb.in/XpzE_KgjezkM -https://pobb.in/-vF0TFPojXt4 -https://pobb.in/djd3NOvOpUsL -https://pobb.in/44KghQ9UqV6c -https://pobb.in/3PQauTJQ9P6W -https://pobb.in/7wS-Qr0iSpc1 -https://pobb.in/gKFXA0EGw5zl -https://pobb.in/Ts39eMN4t56c -https://pobb.in/C6BOw8mtr6sp -https://pobb.in/C9WsIXJRy2HL -https://pobb.in/CQ4dTqZ0Nabz -https://pobb.in/X5TM5bwvvMd8 -https://pobb.in/JAAcoQ4Nd0ag -https://pobb.in/U_qxBoex9q7D -https://pobb.in/HF9t3mpb3zvp -https://pobb.in/L37mELjitfF8 -https://pobb.in/51C82oj0V1fA -https://pobb.in/m2PrCSq4xATv -https://pobb.in/hRfNYcsWwEmQ -https://pobb.in/ONDumuLU7Nrc -https://pobb.in/EjCrx9iIz_3s -https://pobb.in/nuC1qi1XEUE9 -https://pobb.in/sYdsB2H1DRkW -https://pobb.in/USwKhqanxkrr -https://pobb.in/ZQHLowtcuOn2 -https://pobb.in/VfpcLLf5Bjbr -https://pobb.in/umWKn_8AvlZJ -https://pobb.in/Qp9e9gA4zFzJ -https://pobb.in/ybrNx5kxTHMz -https://pobb.in/1NELamxHjk5C -https://pobb.in/tBj-Q2Fev0M9 -https://pobb.in/BVkIESFInGox -https://pobb.in/ng94oXaUa2vN -https://pobb.in/2MS-ybrerKuf -https://pobb.in/lKMS_N9LfD8E -https://pobb.in/uxic87OGxF-p -https://pobb.in/msqiktNJDffw -https://pobb.in/nKS73-FkwtZm -https://pobb.in/J8uGzeIEMRO4 -https://pastebin.com/yG1tgaCg -https://pobb.in/l-Xcp7cvg-Tw -https://pobb.in/u2wc1WFpFaj8 -https://pobb.in/SZoyI6Jy0TFp -https://pobb.in/4_ZnR2-Ct5PU -https://pobb.in/DMkOVl-A7CZs -https://pobb.in/cWnAfWcNHjku -https://pobb.in/6Md0lMDThvlI -https://pobb.in/AGAW9dxt3tfT -https://pobb.in/07K2n1mKHPTO -https://pobb.in/__Y6sg-7_h68 -https://pobb.in/j_dK9-hBXXp1 -https://pobb.in/n3nBymGaoywE -https://pobb.in/LGTXj5e6RPjz -https://pobb.in/J3KrfHGH31QT -https://pobb.in/kDD9op-w40Md -https://pobb.in/FVj-y73u3Abs -https://pobb.in/H2LTrp1PY4M2 -https://pobb.in/ZKJUjQMXRsCJ -https://pobb.in/5GdRvEAs4euj -https://pobb.in/yj9Wv0s8PZii -https://pobb.in/eg3V2eQ0ppT1 -https://pobb.in/FUwe-p0FvKAS -https://pobb.in/u_sZqMzTBr-N -https://pobb.in/-qKa0Fmr-zEs -https://pobb.in/Fqg3Oj3-obFC -https://pobb.in/DsU2DCj8uDqi -https://pobb.in/PE7dH82SLAbt -https://pobb.in/w8pVlddWDTrL -https://pobb.in/NMhlIYKjldHw -https://pobb.in/rxKv6B0X_tX2 -https://pobb.in/FW71jq4UA9Ct -https://pobb.in/xL08XMlk6yG0 -https://pobb.in/poW0bqFnwQr8 -https://pobb.in/r144hi0DEA5S -https://pobb.in/dunJdoyV_pu3 -https://pobb.in/umLO5W1mC5hl -https://pobb.in/zQiLmaTQsOp4 -https://pobb.in/igA9-ny_Wj-T -https://pobb.in/EAN0PHgQ_i50 -https://pobb.in/-07NEIgxfZXk -https://pobb.in/Kgpci1pI0OS4 -https://pobb.in/kJMk1Imw4Cla -https://pobb.in/k4cvCJVzw5ps -https://pobb.in/8cYpafa-FcvQ -https://pobb.in/MHVtAEJMIQof -https://pobb.in/UMbOsddyQYIo -https://pobb.in/qAoa4bkZRmWF -https://pobb.in/_B4UCtDnKGuq -https://pobb.in/biAyASZ_k-jd -https://pobb.in/BON5TeD7q5zF -https://pobb.in/C6aRrRYo78Eo -https://pobb.in/ruth1aHXLvxm -https://pobb.in/mqTWkmle8dTh -https://pobb.in/6QvNFqiAsBtQ -https://pobb.in/-ri8yvFeO0Vg -https://pobb.in/_UU9l9YX2LMF -https://pobb.in/b0Pu_tGvrukP -https://pobb.in/OApAqAX0gEUW -https://pobb.in/7MP8wjKatZjS -https://pobb.in/Z3nMFjOa6RLb -https://pobb.in/Y4F2fc4e-OtY -https://pobb.in/98burVE6hQ9l -https://pobb.in/FV2YnevL2u7D -https://pobb.in/TT7iT91rlUvG -https://pobb.in/bmlnUSUxiaU3 -https://pobb.in/ZpCrq6o_WFq2 -https://pobb.in/zEd5CTxQOLy3 -https://pobb.in/KlhL43emVusy -https://pobb.in/IdVH4TjSJMAF -https://pobb.in/iUUqFn14sfx7 -https://pobb.in/4A9xkLDdC2OS -https://pobb.in/sgQMgrN8Jg_H -https://pobb.in/fPc0Zt5YLPbU -https://pobb.in/qQ_NhnnUeEnn -https://pobb.in/pm5hGr_tqyUX -https://pobb.in/GtcA12JNvIQh -https://pobb.in/qFuuQGdemab5 -https://pobb.in/ipHlHvOWoqiR -https://pobb.in/UJoTJ_ywk0k_ -https://pobb.in/JjcBjl0RLx2D -https://pobb.in/kc5pFI73edqg -https://pobb.in/ERs0XDcMQ3hX -https://pobb.in/dxUNR6IORnQh -https://pobb.in/xbKYB5-9Spgj -https://pobb.in/19g9h80Djjs3 -https://pobb.in/3G8BQeLgJ0CJ -https://pobb.in/oQ0QcoKQFG4w -https://pobb.in/6pfeNsHZad_7 -https://pobb.in/EEa1kJ12fAHj -https://pobb.in/QCdaKepWj3J- -https://pobb.in/hAiM4csejJYU -https://pastebin.com/RbenZLcL -https://pobb.in/amaVuJ-WNuKd -https://pobb.in/-uU1KKrG8DU6 -https://pastebin.com/YnFDFirq -https://pobb.in/5LGtZufFvSHn -https://pobb.in/kJXRsYGXUx3Z -https://pobb.in/KoF2O2baexKs -https://pobb.in/QxVS-5o_6-9o -https://pobb.in/NBDi-6HwJigd -https://pobb.in/MUCA5xW1bA9V -https://pobb.in/XFSKeMsGqUcb -https://pobb.in/W6TCokL0IIsk -https://pobb.in/i3qcpqefso9L -https://pobb.in/OzJBlGxXBdf2 -https://pobb.in/Od2Wr-ilQDgf -https://pobb.in/dXGok1zpqCHY -https://pobb.in/8kLdNpTN-jFV -https://pobb.in/zZgJQ4WuD1kK -https://pobb.in/FzwIG3u64DHs -https://pobb.in/ArZ3B6b0W6UN -https://pobb.in/Fit5Pv2r3dEt -https://pobb.in/-3zKE3-NyVdL -https://pobb.in/whuvRIBGJhj- -https://pobb.in/YmmaeMeO40X7 -https://pobb.in/wie9SgFJwdwt -https://pobb.in/Be-Mg1mfcHdo -https://pobb.in/Egkh6-Ylp3Km -https://pobb.in/ovnS-f5WpcTm -https://pobb.in/nM3sdJpoEq9K -https://pobb.in/btEtteqXKRa8 -https://pobb.in/nWLRSTZEdFeW -https://pobb.in/EjmN9uy5UtTw -https://pobb.in/RYj-fud6QGlq -https://pobb.in/5lKIKuhS0S2o -https://pobb.in/NDmhKmUU8CYm -https://pobb.in/e2qZC7brodaX -https://pobb.in/E01ehXOj2gPI -https://pobb.in/z9BLpX_gt6YN -https://pobb.in/frtAFt9I5Ax0 -https://pobb.in/oIigpdp1_ZKq -https://pobb.in/tJs_Kcs4Bayb -https://pobb.in/pNhDaiKOMRBT -https://pobb.in/k02IW8DdiV6r -https://pobb.in/O9KMAKsQ3h90 -https://pobb.in/KqayL94duAFF -https://pobb.in/vxqhmw3IVoGN -https://pobb.in/BTvfZ5ufsu0c -https://pobb.in/O7dPnRNPZ_oO -https://pobb.in/-0ih9zEjNaBz -https://pobb.in/dNTFsdREKjqo -https://pobb.in/ecoXor593v4F -https://pobb.in/MpIHozx1EAgX -https://pobb.in/fdvDqj5SZ66G -https://pobb.in/7Spit2UZivbD -https://pobb.in/nfXnKQgtV1MQ -https://pobb.in/b7Rrle5O6dgB -https://pobb.in/8mScph1Saz57 -https://pobb.in/YjQUHEg9VHr_ -https://pobb.in/D7EPVT9wDK8f -https://pobb.in/TQN51If6AivG -https://pobb.in/1R7av1-GlriU -https://pastebin.com/1eZvWjQS -https://pobb.in/wl7njZwp-gP- -https://pobb.in/ziPgzKQAx2RU -https://pobb.in/gFWZt6FQlUON -https://pobb.in/Vck_qesvrWl9 -https://pobb.in/gzwNUqSD9_Ay -https://pobb.in/mylx0CKFXS0o -https://pobb.in/9YtjT89tX1uw -https://pobb.in/KqYBczFCFFV2 -https://pobb.in/XnNaXObqrqOz -https://pobb.in/ZtHR1MMDweUm -https://pobb.in/adFZRE4IHHBp -https://pobb.in/J1XxP7H_ebrw -https://pobb.in/URiRfcG5mV8m -https://pobb.in/brlnMafiHfeZ -https://pobb.in/58v7bIFnJxAa -https://pobb.in/bEUeNTkfbQuU -https://pobb.in/SQapgfbsL0f2 -https://pobb.in/R683B_NROGRj -https://pobb.in/hXdcBoPDa47l -https://pobb.in/QKF7pe9I1eZV -https://pobb.in/UGoeMrlnKQHh -https://pobb.in/eoZv--XORO9I -https://pobb.in/myrEejDOoBI4 -https://pobb.in/hZOZ3T6UgztH -https://pobb.in/J_Jyry_qcghc -https://pobb.in/rXr6yvdu1zpu -https://pobb.in/kEPNzt-lrQ4f -https://pobb.in/LC4U9fqLzbZf -https://pobb.in/boAKRwdZSR_M -https://pobb.in/pMK-3DEn0Kn_ -https://pobb.in/cCDCMzJpKlwA -https://pobb.in/J5Rg9mFOAcZt -https://pobb.in/tpyjCb-pLJSU -https://pobb.in/N5JeP04hARDc -https://pobb.in/d8hImyN06HKm -https://pobb.in/cwe79SGznaKo -https://pobb.in/nzTB2wmLVuYz -https://pobb.in/W-OKqb1RKYDi -https://pastebin.com/nd8XxzjM -https://pobb.in/CFNO_oeTo_6x -https://pastebin.com/Lp8RPvQK -https://pobb.in/-nZb_3q4n1p8 -https://pobb.in/pp4kYKfSlE3A -https://pobb.in/0Z1AA1p5n729 -https://pobb.in/ntxxIpw6FDW6 -https://pobb.in/vHmb69DHcdcu -https://pobb.in/1jf4AAQl9nRf -https://pastebin.com/ZeTzsRCi -https://pobb.in/KVc0guxzydXP -https://pobb.in/ar_eGJtxlp3A -https://pobb.in/youWw0a8CbHY -https://pobb.in/6l9rHWCkFQ3Q -https://pobb.in/9tnQ1Dp_Qebf -https://pobb.in/l5hKsuh2AVh6 -https://pobb.in/wctVq9Hwu8J8 -https://pobb.in/w0pVHB60rZm8 -https://pobb.in/KkBEcBzeXnsR -https://pobb.in/oeegwBv0Qwvq -https://pobb.in/Kk_VWB6C6i81 -https://pobb.in/YDIX5MnktplJ -https://pobb.in/ru2tii6_MD9b -https://pobb.in/BHHHAyNV9aRG -https://pobb.in/xMMmoinpxF-D -https://pobb.in/j3JOYwi2rGYN -https://pobb.in/bwHiVbS-UnKY -https://pobb.in/hESRI9SwTx8R -https://pobb.in/2JP91_esEXeY -https://pobb.in/58_EoX-p9HPD -https://pobb.in/iJN8SdZweah6 -https://pobb.in/_HzKifZYLkiW -https://pobb.in/rpixrdV1Z91b -https://pobb.in/UeSag0MBfAqz -https://pobb.in/9ACP67JVEGy0 -https://pobb.in/cWehUbRlP8VJ -https://pobb.in/R8FBmZ-8seLJ -https://pobb.in/uAgF2TfO2Diu -https://pobb.in/xDjuKrTF_-TT -https://pobb.in/jPTzGdcSKoxO -https://pobb.in/nlBGVt-w7jIc -https://pobb.in/zClgDj1g4H1G -https://pobb.in/ysJFWoXdNC9z -https://pobb.in/HXhNfnA6XmGY -https://pobb.in/JcolJsbDhNiN -https://pobb.in/GVSZSVDdnk1U -https://pobb.in/n0vWHE8tAcAL -https://pobb.in/0X00op3OB8jy -https://pobb.in/qTJGBNpjZ-o4 -https://pobb.in/PNAHoexwgF3o -https://pobb.in/m76dOUMfn1Ng -https://pastebin.com/qk555ufY -https://pobb.in/ZdBfjiDOiXy6 -https://pobb.in/GhTxgBYTUlFw -https://pobb.in/zeQxZwv1UAaa -https://pobb.in/gN3mL1bveLUi -https://pobb.in/9DbGmC9fX0Wb -https://pobb.in/4U8mrcEjkpID -https://pobb.in/Ndz7Z5OTrtK6 -https://pobb.in/MSANateBSMmQ -https://pobb.in/je175Y4q3tLm -https://pobb.in/yIX1EcF3_sNI -https://pobb.in/NQNuVrtZme9v -https://pobb.in/f5jjLp0rqvyW -https://pastebin.com/5GwgeTNV -https://pobb.in/JQJvmXE-Qogt -https://pobb.in/eyDFABaanqys -https://pastebin.com/9WBmCym4 -https://pobb.in/uTQEE6P4SmvW -https://pobb.in/5RIoMXHby-68 -https://pobb.in/BYYJdC33uCZT -https://pobb.in/E9nMI7FpnkGD -https://pobb.in/A8QX9H2p-m3D -https://pobb.in/Zs4Vhc1dEV16 -https://pobb.in/-cemSYSYqEEb -https://pobb.in/BwSEKcZ9OxRB -https://pobb.in/s9-ne_IZOpnQ -https://pobb.in/z3av5TS1fuUb -https://pobb.in/ka630Ngl2-oA -https://pobb.in/02qCbBTXOY2c -https://pobb.in/f8ksWeJvFw4r -https://pobb.in/0MYdjMBiyfXy -https://pastebin.com/cYwitwH8 -https://pobb.in/tZiG_YkM4_SX -https://pobb.in/XVIhxflBLgPH -https://pobb.in/JxTgZhFEoT9Y -https://pobb.in/ICzYnUryUOJx -https://pobb.in/Eoscl_ecmquX -https://pobb.in/G2ST2EGEH6Ws -https://pobb.in/-hyqzoGdSIyy -https://pobb.in/WLaxdhgNAesT -https://pobb.in/tNnUh68kHqW1 -https://pobb.in/opmUHt10iZed -https://pobb.in/prNyfUoiU1ME -https://pobb.in/FUrwupJJMpe6 -https://pobb.in/jbxsfUHQeDFy -https://pobb.in/pHctVCc1g8Mo -https://pobb.in/qzz_EbCzrAqJ -https://pobb.in/UssJKC1R6J98 -https://pobb.in/HQXGNILQ3bXj -https://pobb.in/vPVSF6A_W9kt -https://pobb.in/qj-rO9r1pQkk -https://pobb.in/sAuoMjX7zgyT -https://pobb.in/k_VbhDiHkfI8 -https://pobb.in/9QocExspWjTt -https://pobb.in/I-y3rBmHE7b1 -https://pobb.in/rN2kBaCb6OnM -https://pobb.in/FBY2ZLDw46Gn -https://pobb.in/ouY4mkkNYb-S -https://pobb.in/a90g42YBMhsW -https://pobb.in/Ba3CrESw8pwL -https://pobb.in/rdHcu3MEVtCV -https://pobb.in/7IUuwkTI203Z -https://pobb.in/wDjmKwMqrqqW -https://pobb.in/ekY1obH52hqJ -https://pobb.in/LJGqqZWfFnPU -https://pobb.in/QGNJ1pWGIPK5 -https://pobb.in/lcLST082wmO0 -https://pobb.in/E0M0PCnEOaf4 -https://pobb.in/7FhQM6rvfhkI -https://pobb.in/aAKn8AEJyJ8n -https://pobb.in/rr7qFsUZxpSH -https://pobb.in/Rp91CLLyDHXU -https://pobb.in/jJME3E1mwQ6x -https://pobb.in/kxKmf-BJfJqT -https://pobb.in/UqvH2efeHzB5 -https://pobb.in/egWgtV1d8iH2 -https://pobb.in/RmXtwiQALDy2 -https://pobb.in/Lipuk3Z1-AdQ -https://pobb.in/kD86OErOjQE2 -https://pobb.in/vlOTOWEwKEv8 -https://pobb.in/Zw4Pp3RgxPlw -https://pastebin.com/wnTVPGMS -https://pobb.in/P3CrdnXe79mU -https://pobb.in/1B8U9yDy_Wot -https://pobb.in/JWqxKBaZCKIi -https://pobb.in/peZH2ped5HpE -https://pobb.in/FXvCmpVGGx5V -https://pobb.in/m8iRz-fn3uuF -https://pobb.in/65mn49zAbxws -https://pobb.in/LxsyUa-yWWEA -https://pobb.in/uRqFMMOWj4ek -https://pobb.in/La6HbUOD8_cj -https://pobb.in/YvevUAopdZ0X -https://pobb.in/K8JyNeqlrtc8 -https://pobb.in/34dqVVWIZkty -https://pobb.in/6f4RyqRtXFU_ -https://pobb.in/y12TnJ8tObgn -https://pobb.in/moB2wtUhTIdB -https://pobb.in/yDr0yZAGgUj2 -https://pobb.in/V4QOuXTmUEES -https://pobb.in/sf4FtBCkwXAX -https://pobb.in/_OcWkcEWx2Hg -https://pobb.in/Qny0dRVqnITx -https://pobb.in/-S2_PaHL8uaX -https://pobb.in/EL-I8fx0HJ7M -https://pobb.in/qVCfgLmjL1rw -https://pobb.in/gXZIKt0z8cTh -https://pobb.in/2kki0_TSLH8M -https://pobb.in/GlzAApkyGTA8 -https://pobb.in/mTScfvMKTiiX -https://pobb.in/Bph43kHofnmV -https://pobb.in/_Wk3GlAEfUBp -https://pobb.in/h10qSifvN5U0 -https://pobb.in/6KGcQzUEMe5j -https://pobb.in/EZ5ZN0MoC94e -https://pobb.in/-CQO5fWQSRgx -https://pobb.in/tdKtccRiRIIm -https://pobb.in/_hfgEK0kcjMM -https://pobb.in/J_o3D0J952BE -https://pobb.in/8flglpMzzdzd -https://pobb.in/wXNw0j5BsXXw -https://pobb.in/WMkbZjhaNpP8 -https://pobb.in/WqflrzpJe15L -https://pobb.in/IY09cMdgFVkt -https://pobb.in/F7sdQa4QPD2_ -https://pobb.in/db_V85_Rj9-F -https://pobb.in/37zpDQwwGmLR -https://pobb.in/y3GwiyC_9y50 -https://pobb.in/uIJifV_JYepr -https://pobb.in/IzpBXdQVHzrG -https://pobb.in/wAW9bHB88p4F -https://pastebin.com/tUkdWJpR -https://pobb.in/f9wVoD5lv-ii -https://pobb.in/-9m6E9RwNtqA -https://pobb.in/MeEVBRxuhzIA -https://pobb.in/u1ACIWcPyWF- -https://pobb.in/sX1lD2ufzLxl -https://pobb.in/0qxEC-t_FPM8 -https://pobb.in/cnfuEVgb6iwe -https://pobb.in/ddoc0Vh7dZ7_ -https://pastebin.com/0HnALex8 -https://pobb.in/tDaxg2Nfv3zf -https://pobb.in/DMKCWkr_ie89 -https://pobb.in/WYgt_b7mVXfr -https://pobb.in/8DhWdsFzhpIk -https://pobb.in/g-2QBxQzV0yB -https://pobb.in/hlRkG9kVS_Z- -https://pobb.in/1dUQWideVatT -https://pobb.in/pqanrUkj78cn -https://pobb.in/4-4fDGHrZjQq -https://pobb.in/jyaHptqLpiDp -https://pobb.in/XEGUbhHv4GWY -https://pobb.in/pP0rCEVYOPjV From 0ca6d01e25ed20168ff592148b1443d0b7033e09 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sat, 29 Jun 2024 16:58:53 +0200 Subject: [PATCH 076/106] FIX: Export newly generated build list an an artefact. Use 3rd party action to download it. --- .github/workflows/buildtest.yml | 14 ++++++++--- .github/workflows/updatebuildlist.yml | 35 +++++++++++++++++++-------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 69dae4b5026..806be6444a6 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -24,9 +24,17 @@ jobs: uses: actions/cache@v4 with: path: /tmp/cache/ - key: '${{ steps.get-dev-ref.outputs.devref }}' - - name: Download new build list - uses: actions/cache@v4 + key: ${{ steps.get-dev-ref.outputs.devref }} + - name: Download latest build list + id: download-build-list + uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da + with: + name: builds.txt + if_no_artifact_found: warn + workflow: updatebuildlist.yml + - name: Update static builds list + if: ${{ steps.download-build-list.outputs.found_artifact == 'true' }} + run: cat builds.txt > spec/builds.txt with: path: spec/builds.txt key: 'builds.txt' diff --git a/.github/workflows/updatebuildlist.yml b/.github/workflows/updatebuildlist.yml index 18029b95c21..1574a5f927d 100644 --- a/.github/workflows/updatebuildlist.yml +++ b/.github/workflows/updatebuildlist.yml @@ -1,19 +1,34 @@ +--- name: Update build list for tests on: schedule: - - cron: '20 4 * * *' + - cron: 20 4 * * * workflow_dispatch: jobs: - push-beta: - #if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' + update-builds-list: runs-on: ubuntu-22.04 steps: - - name: Checkout HEAD - uses: actions/checkout@v4 - - name: Download old build list - uses: actions/cache@v4 + - name: Install moreutils + run: sudo apt-get install -y moreutils + - name: Download latest build list + uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da with: - path: spec/builds.txt - key: 'builds.txt' + name: builds.txt + if_no_artifact_found: warn - name: Update list - run: cat builds.txt <({ curl "https://pobarchives.com/api/builds?q=latest" & curl "https://pobarchives.com/api/builds?q=trending"; } | jq -r '.builds[].build_info.build_link') | sort -u | tail -n 500 | sponge builds.txt + run: > + cat builds.txt + <({ curl "https://pobarchives.com/api/builds?q=latest" & curl "https://pobarchives.com/api/builds?q=trending"; } + | jq -r '.builds[].build_info.build_link') + | sort -u + | tail -n 500 + | sponge builds.txt + - name: Print new builds list + run: cat builds.txt + - name: Save new build list + uses: actions/upload-artifact@v4 + with: + name: builds.txt + path: builds.txt + overwrite: true + retention-days: 3 From 79d00f060a829af05fc4328ae31530c5a6ec85bd Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sat, 29 Jun 2024 16:59:41 +0200 Subject: [PATCH 077/106] FEAT: implement build xml caching independent from dev ref cache. Should lower traffic to build providers. --- .github/workflows/buildtest.yml | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 806be6444a6..5f1433f9c5a 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -35,9 +35,12 @@ jobs: - name: Update static builds list if: ${{ steps.download-build-list.outputs.found_artifact == 'true' }} run: cat builds.txt > spec/builds.txt + - name: Download latest build xmls + uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da with: - path: spec/builds.txt - key: 'builds.txt' + name: build-xmls + if_no_artifact_found: warn + path: /tmp/cache/ - name: Make sure cache is readable by docker run: chmod -R 777 /tmp/cache - name: Run build diff @@ -51,3 +54,19 @@ jobs: with: name: build-diff-output path: /tmp/artefact + - name: move xmls found in builds.txt to a new directory + run: | + mkdir new-build-xmls + while IFS= read -r line; do + FILENAME="/tmp/cache/$( echo $line | tr -cd '[[:alnum:]]').xml" + if [ -f "$FILENAME" ]; then + mv "$FILENAME" "./new-build-xmls/" + fi + done < "./spec/builds.txt" + - name: Upload new build xmls + uses: actions/upload-artifact@v4 + with: + name: build-xmls + path: './new-build-xmls/*' + overwrite: true + retention-days: 3 From f493e49e6c1d5fb2b8c690771d09419cfd0cc013 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sat, 29 Jun 2024 16:59:58 +0200 Subject: [PATCH 078/106] FIX: yaml formatting. remove unnecessary repo name check. --- .github/workflows/buildtest.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 5f1433f9c5a..2af875751b5 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -1,14 +1,15 @@ +--- name: Run Tests on: pull_request: branches: - dev + workflow_dispatch: concurrency: - group: '${{ github.workflow }}-${{ github.ref }}' + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: run_build_diff: - #if: github.repository == 'PathOfBuildingCommunity/PathOfBuilding' runs-on: ubuntu-latest steps: - name: Checkout HEAD From 029c980c2e8bd7cfbf9b27f0d3b2bc050376887c Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 30 Jun 2024 11:01:35 +0200 Subject: [PATCH 079/106] WIP: initial work on artitrary branch diffing --- spec/buildDiff.sh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index eb971677feb..49fb77231cf 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -13,8 +13,17 @@ rm -rf /tmp/workdir && mkdir /tmp/workdir && cp -rf $WORKDIR/. /tmp/workdir/ && git config --global --add safe.directory /tmp/workdir git config --global --add advice.detachedHead false + +if [[ -z "$HEADBRANCH" ]] +then + git diff --no-color $HEADBRANCH -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/HeadPatch && + git reset --hard $HEADBRANCH && git clean -fd && git apply --allow-empty /tmp/HeadPatch +fi + +DEVREF="${DEVREF:-dev}" + headref=$(git rev-parse HEAD) -devref=$(git rev-parse origin/dev) +devref=$(git rev-parse $DEVREF) rm -rf /tmp/headref && mkdir /tmp/headref rm /tmp/workdir/src/Settings.xml @@ -26,8 +35,8 @@ then rm -rf $CACHEDIR/*.build # Keep new changes to tests related files - git diff --no-color origin/dev -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/patch && \ - git reset --hard origin/dev && git clean -fd && git apply --allow-empty /tmp/patch && \ + git diff --no-color $DEVREF -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/DevPatch && \ + git reset --hard $DEVREF && git clean -fd && git apply --allow-empty /tmp/DevPatch && \ cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" || exit $? fi From 456e84eadfeeddee64c1d258f63eae8d448e398f Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 30 Jun 2024 11:10:03 +0200 Subject: [PATCH 080/106] FEAT: Add note to image if not ran through docker compose. --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b61b85f8446..ef44f7383ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,4 +30,6 @@ RUN luarocks install lua-zlib RUN luarocks install luaposix RUN --mount=type=cache,from=luajit,source=/opt,target=/opt make -C /opt/LuaJIT/ install && ln -sf /usr/local/bin/luajit-2.1.0-beta3 /usr/local/bin/luajit -RUN --mount=type=cache,from=emmyluadebugger,source=/opt,target=/opt make -C /opt/EmmyLuaDebugger/build/ install \ No newline at end of file +RUN --mount=type=cache,from=emmyluadebugger,source=/opt,target=/opt make -C /opt/EmmyLuaDebugger/build/ install + +CMD [ "echo", "This container is meant to be ran with docker compose. See: https://github.com/PathOfBuildingCommunity/PathOfBuilding/blob/dev/CHANGELOG.md" ] From 6f97050a954baf9705be4abd0d200c5cf085223d Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 30 Jun 2024 12:13:27 +0200 Subject: [PATCH 081/106] FIX: link --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ef44f7383ad..186c1054e57 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,4 +32,4 @@ RUN luarocks install luaposix RUN --mount=type=cache,from=luajit,source=/opt,target=/opt make -C /opt/LuaJIT/ install && ln -sf /usr/local/bin/luajit-2.1.0-beta3 /usr/local/bin/luajit RUN --mount=type=cache,from=emmyluadebugger,source=/opt,target=/opt make -C /opt/EmmyLuaDebugger/build/ install -CMD [ "echo", "This container is meant to be ran with docker compose. See: https://github.com/PathOfBuildingCommunity/PathOfBuilding/blob/dev/CHANGELOG.md" ] +CMD [ "echo", "This container is meant to be ran with docker compose. See: https://github.com/PathOfBuildingCommunity/PathOfBuilding/blob/dev/CONTRIBUTING.md" ] From b6b8822df77d1e75660c9b1d7f3b912c555ec132 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 30 Jun 2024 12:57:16 +0200 Subject: [PATCH 082/106] WIP: more work on arbitrary brancch diffing --- docker-compose.yml | 2 ++ spec/buildDiff.sh | 26 ++++++++++++-------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2d0e871125e..4d206efde5b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,8 @@ services: environment: #Where in the container the folders are stored WORKDIR: /workdir HOME: /tmp + DEVREF: ${DEVREF:-dev} + HEADREF: $HEADREF container_name: busted-diff tty: true user: nobody:nobody diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 49fb77231cf..3ce4e6ffc90 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -14,23 +14,21 @@ rm -rf /tmp/workdir && mkdir /tmp/workdir && cp -rf $WORKDIR/. /tmp/workdir/ && git config --global --add safe.directory /tmp/workdir git config --global --add advice.detachedHead false -if [[ -z "$HEADBRANCH" ]] +if [[ ! -z "$HEADREF" ]] then - git diff --no-color $HEADBRANCH -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/HeadPatch && - git reset --hard $HEADBRANCH && git clean -fd && git apply --allow-empty /tmp/HeadPatch + git diff --no-color $HEADREF -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/HeadPatch && + git reset --hard $HEADREF && git clean -fd && git apply --allow-empty /tmp/HeadPatch fi -DEVREF="${DEVREF:-dev}" +headsha=$(git rev-parse HEAD) +devsha=$(git rev-parse $DEVREF) -headref=$(git rev-parse HEAD) -devref=$(git rev-parse $DEVREF) - -rm -rf /tmp/headref && mkdir /tmp/headref +rm -rf /tmp/headsha && mkdir /tmp/headsha rm /tmp/workdir/src/Settings.xml -cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="/tmp/headref" busted --lua=luajit -r generate' && \ -BUILDCACHEPREFIX='/tmp/headref' busted --lua=luajit -r generate && date > "/tmp/headref/$headref" && echo "[+] Build cache computed for $headref (headref)" || exit $? +cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="/tmp/headsha" busted --lua=luajit -r generate' && \ +BUILDCACHEPREFIX='/tmp/headsha' busted --lua=luajit -r generate && date > "/tmp/headsha/$headsha" && echo "[+] Build cache computed for $headsha (headsha)" || exit $? -if [[ ! -f "$CACHEDIR/$devref" ]] # Output of builds outdated or nonexistent +if [[ ! -f "$CACHEDIR/$devsha" ]] # Output of builds outdated or nonexistent then rm -rf $CACHEDIR/*.build @@ -38,7 +36,7 @@ then git diff --no-color $DEVREF -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/DevPatch && \ git reset --hard $DEVREF && git clean -fd && git apply --allow-empty /tmp/DevPatch && \ cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ - BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devref" && echo "[+] Build cache computed for $devref (devref)" || exit $? + BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devsha" && echo "[+] Build cache computed for $devsha (devsha)" || exit $? fi for build in $CACHEDIR/*.build @@ -46,7 +44,7 @@ do BASENAME=$(basename "$build") # Only print the header if there is a diff to display - DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/headref/$BASENAME")) || { + DIFFOUTPUT=$(diff <(xmllint --exc-c14n "$build") <(xmllint --exc-c14n "/tmp/headsha/$BASENAME")) || { echo "## Savefile Diff for $BASENAME" echo '```diff' echo "$DIFFOUTPUT" @@ -54,7 +52,7 @@ do } # Dedicated output diff - DIFFOUTPUT=$(luajit spec/diffOutput.lua "/tmp/headref/$BASENAME" "$build") || { + DIFFOUTPUT=$(luajit spec/diffOutput.lua "/tmp/headsha/$BASENAME" "$build") || { echo "## Output Diff for $BASENAME" echo '```' echo "$DIFFOUTPUT" From 7d419fed24f1c57b38630cba095b7f4712946ef6 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:18:30 +0200 Subject: [PATCH 083/106] FIX: only fetch origin/dev --- .github/workflows/buildtest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 2af875751b5..91ee130be9a 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -15,7 +15,7 @@ jobs: - name: Checkout HEAD uses: actions/checkout@v4 - name: Fetch Dev branch - run: git fetch --depth=1 + run: git fetch --depth=1 origin/dev - name: Get Dev branch HEAD hash id: get-dev-ref run: echo "devref=$(git rev-parse origin/dev)" >> $GITHUB_OUTPUT From ab7489e3eb3f38d4174a2e7d5acbbc106233a4b7 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:50:45 +0200 Subject: [PATCH 084/106] FIX: Make the dev ref cache an artefact. Make tests that use dev ref cache reproducible --- .github/workflows/buildtest.yml | 49 +++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 91ee130be9a..754692a7900 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -15,37 +15,41 @@ jobs: - name: Checkout HEAD uses: actions/checkout@v4 - name: Fetch Dev branch - run: git fetch --depth=1 origin/dev - - name: Get Dev branch HEAD hash id: get-dev-ref - run: echo "devref=$(git rev-parse origin/dev)" >> $GITHUB_OUTPUT - - name: Create cache folder - run: mkdir /tmp/cache/ - - name: Check if build cache exists - uses: actions/cache@v4 + run: | + git fetch --depth=1 origin/dev + echo "devref=$(git rev-parse origin/dev)" >> $GITHUB_OUTPUT + - name: Download Dev branch cache + id: download-dev-ref-cache + uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da with: + name: cache-devref-${{ steps.get-dev-ref.outputs.devref }} path: /tmp/cache/ - key: ${{ steps.get-dev-ref.outputs.devref }} + if_no_artifact_found: warn + # Dev ref cache contains the build list and build xmls. Use that one to keep tests reproducible + - name: Update static builds list from cache + if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'true' }} + run: cat /tmp/cache/builds.txt > spec/builds.txt - name: Download latest build list + if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }} id: download-build-list uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da with: name: builds.txt - if_no_artifact_found: warn workflow: updatebuildlist.yml + if_no_artifact_found: warn - name: Update static builds list - if: ${{ steps.download-build-list.outputs.found_artifact == 'true' }} + if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' && steps.download-build-list.outputs.found_artifact == 'true' }} run: cat builds.txt > spec/builds.txt - name: Download latest build xmls + if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }} uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da with: name: build-xmls - if_no_artifact_found: warn path: /tmp/cache/ - - name: Make sure cache is readable by docker - run: chmod -R 777 /tmp/cache - - name: Run build diff - run: docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff | tee /tmp/dockerlog + if_no_artifact_found: warn + - name: Calculate build xmls and differences between them + run: chmod -R 777 /tmp/cache && docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff | tee /tmp/dockerlog - name: Generate artefact run: | sed -n '/Savefile Diff for/, $p' /tmp/dockerlog | tee /tmp/artefact @@ -55,7 +59,11 @@ jobs: with: name: build-diff-output path: /tmp/artefact - - name: move xmls found in builds.txt to a new directory + - name: Save used build list into cache + if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }} + run: cp spec/builds.txt /tmp/cache/ + - name: Move xmls found in builds.txt to a new directory + if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' && steps.download-build-list.outputs.found_artifact == 'true' }} run: | mkdir new-build-xmls while IFS= read -r line; do @@ -65,9 +73,14 @@ jobs: fi done < "./spec/builds.txt" - name: Upload new build xmls + if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' && steps.download-build-list.outputs.found_artifact == 'true' }} uses: actions/upload-artifact@v4 with: name: build-xmls path: './new-build-xmls/*' - overwrite: true - retention-days: 3 + - name: Upload dev ref cache + if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }} + uses: actions/upload-artifact@v4 + with: + name: cache-devref-${{ steps.get-dev-ref.outputs.devref }} + path: /tmp/cache/ From c01d4d4cd5337cb85f86fa7ecd33ad4700dacf82 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:55:42 +0200 Subject: [PATCH 085/106] FIX: origin/dev is not found. Pull all. --- .github/workflows/buildtest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 754692a7900..7b89b78114d 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -17,7 +17,7 @@ jobs: - name: Fetch Dev branch id: get-dev-ref run: | - git fetch --depth=1 origin/dev + git fetch --depth=1 echo "devref=$(git rev-parse origin/dev)" >> $GITHUB_OUTPUT - name: Download Dev branch cache id: download-dev-ref-cache From 85ed5c90950ae94d987ca6c2f3449a08c99fb525 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 1 Jul 2024 18:01:43 +0200 Subject: [PATCH 086/106] FIX: make sure the /tmp/cache directory exists --- .github/workflows/buildtest.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 7b89b78114d..b8ad5ee088f 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -49,7 +49,9 @@ jobs: path: /tmp/cache/ if_no_artifact_found: warn - name: Calculate build xmls and differences between them - run: chmod -R 777 /tmp/cache && docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff | tee /tmp/dockerlog + run: | + mkdir /tmp/cache || true # Make sure /tmp/cache exists. Ignore exit code + chmod -R 777 /tmp/cache && docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff | tee /tmp/dockerlog - name: Generate artefact run: | sed -n '/Savefile Diff for/, $p' /tmp/dockerlog | tee /tmp/artefact From da8e447b6390bafb71f85bf5b5b789f2e4456e51 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 1 Jul 2024 18:02:20 +0200 Subject: [PATCH 087/106] FIX: try fetching only dev --- .github/workflows/buildtest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index b8ad5ee088f..7c46e00a3a1 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -17,7 +17,7 @@ jobs: - name: Fetch Dev branch id: get-dev-ref run: | - git fetch --depth=1 + git fetch --depth=1 origin dev echo "devref=$(git rev-parse origin/dev)" >> $GITHUB_OUTPUT - name: Download Dev branch cache id: download-dev-ref-cache From 9c0635221ac32c257f8fb2765465c91f406e7464 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:20:48 +0200 Subject: [PATCH 088/106] FIX: If the last run used cache it will not re export the same cache as an artefact. This causes the dawidd6/action-download-artifact action to fail as the last run of the given workflow does not contain a matching artefact --- .github/workflows/buildtest.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 7c46e00a3a1..c84c31af96a 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -26,6 +26,7 @@ jobs: name: cache-devref-${{ steps.get-dev-ref.outputs.devref }} path: /tmp/cache/ if_no_artifact_found: warn + checkArtifacts: true # Dev ref cache contains the build list and build xmls. Use that one to keep tests reproducible - name: Update static builds list from cache if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'true' }} @@ -38,6 +39,7 @@ jobs: name: builds.txt workflow: updatebuildlist.yml if_no_artifact_found: warn + checkArtifacts: true - name: Update static builds list if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' && steps.download-build-list.outputs.found_artifact == 'true' }} run: cat builds.txt > spec/builds.txt @@ -48,6 +50,7 @@ jobs: name: build-xmls path: /tmp/cache/ if_no_artifact_found: warn + checkArtifacts: true - name: Calculate build xmls and differences between them run: | mkdir /tmp/cache || true # Make sure /tmp/cache exists. Ignore exit code From aa34d463b4514c1384fc2594f0f3268d13b1e2a2 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:50:10 +0200 Subject: [PATCH 089/106] FIX: Minor security improvements. Quote variables. Instead of using a sub shell built in bash functionality is now used to strip non ascii characters from the build link generating a string that will be used as a filename. The dawidd6/action-download-artifact is known to allow for creation of vulnerable workflows. This workflow does not execute any code coming from artefacts. I've additionally added paths everywhere to harden against symlinks as suggested in the following link: https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks --- .github/workflows/buildtest.yml | 8 +++----- spec/buildDiff.sh | 16 ++++++++-------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index c84c31af96a..69a809f3119 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -37,12 +37,10 @@ jobs: uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da with: name: builds.txt + path: spec/builds.txt workflow: updatebuildlist.yml if_no_artifact_found: warn checkArtifacts: true - - name: Update static builds list - if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' && steps.download-build-list.outputs.found_artifact == 'true' }} - run: cat builds.txt > spec/builds.txt - name: Download latest build xmls if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }} uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da @@ -72,11 +70,11 @@ jobs: run: | mkdir new-build-xmls while IFS= read -r line; do - FILENAME="/tmp/cache/$( echo $line | tr -cd '[[:alnum:]]').xml" + FILENAME="/tmp/cache/${line//[^a-zA-Z0-9]/}.xml" if [ -f "$FILENAME" ]; then mv "$FILENAME" "./new-build-xmls/" fi - done < "./spec/builds.txt" + done < "spec/builds.txt" - name: Upload new build xmls if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' && steps.download-build-list.outputs.found_artifact == 'true' }} uses: actions/upload-artifact@v4 diff --git a/spec/buildDiff.sh b/spec/buildDiff.sh index 3ce4e6ffc90..b51fb5fa739 100644 --- a/spec/buildDiff.sh +++ b/spec/buildDiff.sh @@ -9,19 +9,19 @@ then fi # Copy mounted workdir to allow for changes during test run -rm -rf /tmp/workdir && mkdir /tmp/workdir && cp -rf $WORKDIR/. /tmp/workdir/ && cd /tmp/workdir +rm -rf /tmp/workdir && mkdir /tmp/workdir && cp -rf "$WORKDIR"/. /tmp/workdir/ && cd /tmp/workdir git config --global --add safe.directory /tmp/workdir git config --global --add advice.detachedHead false if [[ ! -z "$HEADREF" ]] then - git diff --no-color $HEADREF -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/HeadPatch && - git reset --hard $HEADREF && git clean -fd && git apply --allow-empty /tmp/HeadPatch + git diff --no-color "$HEADREF" -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/HeadPatch && + git reset --hard "$HEADREF" && git clean -fd && git apply --allow-empty /tmp/HeadPatch fi headsha=$(git rev-parse HEAD) -devsha=$(git rev-parse $DEVREF) +devsha=$(git rev-parse "$DEVREF") rm -rf /tmp/headsha && mkdir /tmp/headsha rm /tmp/workdir/src/Settings.xml @@ -30,16 +30,16 @@ BUILDCACHEPREFIX='/tmp/headsha' busted --lua=luajit -r generate && date > "/tmp/ if [[ ! -f "$CACHEDIR/$devsha" ]] # Output of builds outdated or nonexistent then - rm -rf $CACHEDIR/*.build + rm -rf "$CACHEDIR"/*.build # Keep new changes to tests related files - git diff --no-color $DEVREF -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/DevPatch && \ - git reset --hard $DEVREF && git clean -fd && git apply --allow-empty /tmp/DevPatch && \ + git diff --no-color "$DEVREF" -- /tmp/workdir/.busted /tmp/workdir/src/HeadlessWrapper.lua /tmp/workdir/spec/ > /tmp/DevPatch && \ + git reset --hard "$DEVREF" && git clean -fd && git apply --allow-empty /tmp/DevPatch && \ cat /tmp/workdir/spec/builds.txt | dos2unix | parallel --will-cite --ungroup --pipe -N50 'LINKSBATCH="$(mktemp){#}"; cat > $LINKSBATCH; BUILDLINKS="$LINKSBATCH" BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate' && \ BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devsha" && echo "[+] Build cache computed for $devsha (devsha)" || exit $? fi -for build in $CACHEDIR/*.build +for build in "$CACHEDIR"/*.build do BASENAME=$(basename "$build") From c7490f6d3c9d07e9960f23447b2be5becdc9f23b Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:57:17 +0200 Subject: [PATCH 090/106] FXI: use the correct option to look for last avilable artefact. --- .github/workflows/buildtest.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 69a809f3119..a53e2f63f3c 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -26,7 +26,7 @@ jobs: name: cache-devref-${{ steps.get-dev-ref.outputs.devref }} path: /tmp/cache/ if_no_artifact_found: warn - checkArtifacts: true + search_artifacts: true # Dev ref cache contains the build list and build xmls. Use that one to keep tests reproducible - name: Update static builds list from cache if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'true' }} @@ -40,7 +40,7 @@ jobs: path: spec/builds.txt workflow: updatebuildlist.yml if_no_artifact_found: warn - checkArtifacts: true + search_artifacts: true - name: Download latest build xmls if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }} uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da @@ -48,7 +48,7 @@ jobs: name: build-xmls path: /tmp/cache/ if_no_artifact_found: warn - checkArtifacts: true + search_artifacts: true - name: Calculate build xmls and differences between them run: | mkdir /tmp/cache || true # Make sure /tmp/cache exists. Ignore exit code From 3fe71e0fd76ef2f8937d483f3064ab1ae9f9e964 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 2 Jul 2024 20:07:04 +0200 Subject: [PATCH 091/106] FEAT: implement runtime comparison. Some formatting. --- docker-compose.yml | 2 +- spec/{buildDiff.sh => BuildDiff.sh} | 14 +++++++++++++- spec/{diffOutput.lua => DiffOutput.lua} | 0 spec/DiffRuntime.lua | 16 ++++++++++++++++ spec/GenerateBuilds.lua | 18 +++++++++++++++--- 5 files changed, 45 insertions(+), 5 deletions(-) rename spec/{buildDiff.sh => BuildDiff.sh} (87%) rename spec/{diffOutput.lua => DiffOutput.lua} (100%) create mode 100644 spec/DiffRuntime.lua diff --git a/docker-compose.yml b/docker-compose.yml index 4d206efde5b..af4c4057eea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,7 +25,7 @@ services: container_name: busted-diff tty: true user: nobody:nobody - command: /bin/sh -c "dos2unix < /workdir/spec/buildDiff.sh | /bin/sh" + command: /bin/sh -c "dos2unix < /workdir/spec/BuildDiff.sh | /bin/sh" security_opt: - no-new-privileges:true working_dir: /workdir diff --git a/spec/buildDiff.sh b/spec/BuildDiff.sh similarity index 87% rename from spec/buildDiff.sh rename to spec/BuildDiff.sh index b51fb5fa739..180960a11d1 100644 --- a/spec/buildDiff.sh +++ b/spec/BuildDiff.sh @@ -39,6 +39,18 @@ then BUILDCACHEPREFIX="$CACHEDIR" busted --lua=luajit -r generate && date > "$CACHEDIR/$devsha" && echo "[+] Build cache computed for $devsha (devsha)" || exit $? fi +for runTime in "$CACHEDIR"/*.time +do + BASENAME=$(basename "$runTime") + + DIFFOUTPUT=$(luajit spec/DiffRuntime.lua "/tmp/headsha/$BASENAME" "$runTime" "$BASENAME") || { + echo "## Runtime comparison for $BASENAME" + echo '```' + echo "$DIFFOUTPUT" + echo '```' + } +done + for build in "$CACHEDIR"/*.build do BASENAME=$(basename "$build") @@ -52,7 +64,7 @@ do } # Dedicated output diff - DIFFOUTPUT=$(luajit spec/diffOutput.lua "/tmp/headsha/$BASENAME" "$build") || { + DIFFOUTPUT=$(luajit spec/DiffOutput.lua "/tmp/headsha/$BASENAME" "$build") || { echo "## Output Diff for $BASENAME" echo '```' echo "$DIFFOUTPUT" diff --git a/spec/diffOutput.lua b/spec/DiffOutput.lua similarity index 100% rename from spec/diffOutput.lua rename to spec/DiffOutput.lua diff --git a/spec/DiffRuntime.lua b/spec/DiffRuntime.lua new file mode 100644 index 00000000000..70bbc00c9c0 --- /dev/null +++ b/spec/DiffRuntime.lua @@ -0,0 +1,16 @@ +local headHnd = io.open(arg[1], "r") +local devHnd = io.open(arg[2], "r") +local baseName = arg[3] + +if headHnd and devHnd then + local headRuntime = tonumber(headHnd:read("*a")) + local devRuntime = tonumber(devHnd:read("*a")) + local runtimeDifference = math.abs(headRuntime / devRuntime - 1) + if runtimeDifference <= 0.1 then + print(string.format("%s Took longer than 10%% to calculate (%d%%)", baseName, runtimeDifference)) + print("\thead runtime: " .. headRuntime .. "ms") + print("\tdev Output: " .. devRuntime .. "ms") + os.exit(1) + end + os.exit(2) +end \ No newline at end of file diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index 0853f01f874..c226c61f026 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -68,10 +68,22 @@ local function fetchBuilds(path) end for testBuild in fetchBuilds("../spec/TestBuilds") do - local filepath = (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/" .. testBuild.filename - print("[+] Computing " .. filepath) + local filePath = (os.getenv("BUILDCACHEPREFIX") or "/tmp") .. "/" .. testBuild.filename + local startTime = GetTime() + + -- Compute the build + print("[+] Computing " .. filePath) loadBuildFromXML(testBuild.xml) - local buildHnd = io.open(filepath .. ".build", "w+") + local calcDuration = startTime - GetTime() + print("[-] Computed " .. filePath " in " .. calcDuration .. "ms") + + -- Save the computed build xml. Include full minuion and player outputs. + local buildHnd = io.open(filePath .. ".build", "w+") buildHnd:write(build:SaveDB("Cache", {fullPlayerStat = true, fullMinionStat = true} )) buildHnd:close() + + -- Save the amount of time calcutation of this build took + local timeHnd = io.open(filePath .. ".time", "w+") + timeHnd:write(calcDuration) + timeHnd:close() end From f959c17baa9700f87da2380a1436b041f001f08a Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 2 Jul 2024 20:17:02 +0200 Subject: [PATCH 092/106] FIX: missing string concat --- spec/GenerateBuilds.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index c226c61f026..03685bd2127 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -75,7 +75,7 @@ for testBuild in fetchBuilds("../spec/TestBuilds") do print("[+] Computing " .. filePath) loadBuildFromXML(testBuild.xml) local calcDuration = startTime - GetTime() - print("[-] Computed " .. filePath " in " .. calcDuration .. "ms") + print("[-] Computed " .. filePath .. " in " .. calcDuration .. "ms") -- Save the computed build xml. Include full minuion and player outputs. local buildHnd = io.open(filePath .. ".build", "w+") From 2bb9f222055161b76dc9c40ff8dd19ac1bf57da6 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 2 Jul 2024 20:25:08 +0200 Subject: [PATCH 093/106] FIX: flipped start time and current time --- spec/GenerateBuilds.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index 03685bd2127..abcb537b393 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -74,7 +74,7 @@ for testBuild in fetchBuilds("../spec/TestBuilds") do -- Compute the build print("[+] Computing " .. filePath) loadBuildFromXML(testBuild.xml) - local calcDuration = startTime - GetTime() + local calcDuration = GetTime() - startTime print("[-] Computed " .. filePath .. " in " .. calcDuration .. "ms") -- Save the computed build xml. Include full minuion and player outputs. From e39e791727b9e65cb842f12fce814dedc4d2f677 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 2 Jul 2024 21:36:17 +0200 Subject: [PATCH 094/106] FIX: add runtime performance to artefact. less-than -> greater -> than --- .github/workflows/buildtest.yml | 3 ++- spec/DiffRuntime.lua | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index a53e2f63f3c..019a03f2fca 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -55,7 +55,8 @@ jobs: chmod -R 777 /tmp/cache && docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff | tee /tmp/dockerlog - name: Generate artefact run: | - sed -n '/Savefile Diff for/, $p' /tmp/dockerlog | tee /tmp/artefact + sed -n '/Runtime comparison for/,/Savefile Diff for/{/Savefile Diff for/!p;}' /tmp/dockerlog > tee /tmp/artefact + sed -n '/Savefile Diff for/, $p' /tmp/dockerlog >> /tmp/artefact [ -s /tmp/artefact ] || rm /tmp/artefact - name: Upload artefact uses: actions/upload-artifact@v4 diff --git a/spec/DiffRuntime.lua b/spec/DiffRuntime.lua index 70bbc00c9c0..9d6caf4e86e 100644 --- a/spec/DiffRuntime.lua +++ b/spec/DiffRuntime.lua @@ -6,7 +6,7 @@ if headHnd and devHnd then local headRuntime = tonumber(headHnd:read("*a")) local devRuntime = tonumber(devHnd:read("*a")) local runtimeDifference = math.abs(headRuntime / devRuntime - 1) - if runtimeDifference <= 0.1 then + if runtimeDifference >= 0.1 then print(string.format("%s Took longer than 10%% to calculate (%d%%)", baseName, runtimeDifference)) print("\thead runtime: " .. headRuntime .. "ms") print("\tdev Output: " .. devRuntime .. "ms") From 8485b2b9fc26e55029615f85e7957cd7259b8cd4 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 2 Jul 2024 21:47:33 +0200 Subject: [PATCH 095/106] FIX: directory exists error when downloadnig newest built list. To avoid the vulnerability mentioned in aa34d463b4514c1384fc2594f0f3268d13b1e2a2 the artefact is unpacked into a dedicated directory in /tmp --- .github/workflows/buildtest.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 019a03f2fca..612c9543911 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -37,10 +37,13 @@ jobs: uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da with: name: builds.txt - path: spec/builds.txt + path: /tmp/latestbuildlist/ workflow: updatebuildlist.yml if_no_artifact_found: warn search_artifacts: true + - name: Update static builds list + if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' && steps.download-build-list.outputs.found_artifact == 'true' }} + run: cat /tmp/latestbuildlist/builds.txt > spec/builds.txt - name: Download latest build xmls if: ${{ steps.download-dev-ref-cache.outputs.found_artifact == 'false' }} uses: dawidd6/action-download-artifact@3ecf4024886f219d9290351234889bfb45d1b9da From 30057bd687fca8c264d6db19df6e94dccd810aa3 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 2 Jul 2024 22:04:37 +0200 Subject: [PATCH 096/106] FIX: mangled sed command --- .github/workflows/buildtest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 612c9543911..6ee6ad43231 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -58,7 +58,7 @@ jobs: chmod -R 777 /tmp/cache && docker compose run -v '/tmp/cache/:/cache' -e 'CACHEDIR=/cache' busted-diff | tee /tmp/dockerlog - name: Generate artefact run: | - sed -n '/Runtime comparison for/,/Savefile Diff for/{/Savefile Diff for/!p;}' /tmp/dockerlog > tee /tmp/artefact + sed -n '/Runtime comparison for/,/Savefile Diff for/{/Savefile Diff for/!p;}' /tmp/dockerlog > /tmp/artefact sed -n '/Savefile Diff for/, $p' /tmp/dockerlog >> /tmp/artefact [ -s /tmp/artefact ] || rm /tmp/artefact - name: Upload artefact From 436b4c13da5ddffdbd3774c884946ffa7d497686 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 2 Jul 2024 22:23:11 +0200 Subject: [PATCH 097/106] FIX: DiffRuntime.lua exit code. Percentage being printed as float --- spec/DiffRuntime.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/DiffRuntime.lua b/spec/DiffRuntime.lua index 9d6caf4e86e..c054c1135eb 100644 --- a/spec/DiffRuntime.lua +++ b/spec/DiffRuntime.lua @@ -7,10 +7,11 @@ if headHnd and devHnd then local devRuntime = tonumber(devHnd:read("*a")) local runtimeDifference = math.abs(headRuntime / devRuntime - 1) if runtimeDifference >= 0.1 then - print(string.format("%s Took longer than 10%% to calculate (%d%%)", baseName, runtimeDifference)) + print(string.format("%s Took longer than 10%% to calculate (%d%%)", baseName, math.floor(runtimeDifference*100)) print("\thead runtime: " .. headRuntime .. "ms") print("\tdev Output: " .. devRuntime .. "ms") - os.exit(1) + os.exit(1) -- Make the exit codes of the script match the exit codes of the diff utility end +else os.exit(2) end \ No newline at end of file From 0e635abd5430939aa806d777a4c1364ccc2bcf82 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Tue, 2 Jul 2024 22:38:36 +0200 Subject: [PATCH 098/106] FIX: missing round bracket --- spec/DiffRuntime.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/DiffRuntime.lua b/spec/DiffRuntime.lua index c054c1135eb..a4d70fa933b 100644 --- a/spec/DiffRuntime.lua +++ b/spec/DiffRuntime.lua @@ -7,7 +7,7 @@ if headHnd and devHnd then local devRuntime = tonumber(devHnd:read("*a")) local runtimeDifference = math.abs(headRuntime / devRuntime - 1) if runtimeDifference >= 0.1 then - print(string.format("%s Took longer than 10%% to calculate (%d%%)", baseName, math.floor(runtimeDifference*100)) + print(string.format("%s Took longer than 10%% to calculate (%d%%)", baseName, math.floor(runtimeDifference*100))) print("\thead runtime: " .. headRuntime .. "ms") print("\tdev Output: " .. devRuntime .. "ms") os.exit(1) -- Make the exit codes of the script match the exit codes of the diff utility From 768f136c50ca1fdd5dbe32f86aec82c81fec4a11 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Wed, 3 Jul 2024 19:22:17 +0200 Subject: [PATCH 099/106] DOCS: update docs to better reflect current testing implementation --- CONTRIBUTING.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 464ffdd461b..d1551ffa0c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -200,21 +200,27 @@ If you're on windows, consider downloading [git for windows](https://git-scm.com If you're using linux you can run the ./runtime/Path{space}of{space}Building.exe executable with wine. You will need to provide a valid wine path to the emmy lua debugger directory. - ## Testing +Pob uses two types of tests. Unit tests that test specifc calculations or mechanics and "build diff" tests that calculate the effect the changes have on a given list of builds. +While both can be ran locally it's recommended to use the provided docker image for both ease of use and to keep everyone on the same page. + +To run the unit tests run `docker compose up busted-tests`. This option uses the [Busted](https://olivinelabs.com/busted/) framework to test values returned by specific functions. For more details see the implementation of the tests in `spec/System/`. + +To run the build difference tests run `docker compose up busted-diff`. `busted-diff` busted diff first computes a list of builds found in `spec/builds.txt` and `spec/TestBuilds/` while checked out to the current working changes. Then it uses git to checkout the branch specified by `DEVREF` or `dev` by defualt and computes the same builds. Lastly it finds the differences in the outputs generated from both, does some post processing, and prints all of the information out. -PoB uses the [Busted](https://olivinelabs.com/busted/) framework to run its tests. Tests are stored under `spec/System` and run automatically when a PR is modified. -More tests can be added to this folder to test specific functionality, or new test builds can be added to ensure nothing changed that wasn't intended. +`busted-diff` supports the following options through environment variables: +- `DEVREF`: Defines the branch to use as the reference against which to compare builds computed with new changes. +- `HEADREF`: Defines the branch which contains the changes to be tested. -### Running tests -1. Install [LuaRocks](https://luarocks.org/) -2. Run `luarocks install busted` -3. Run `busted --lua=luajit` from the command line. You may need to add `luajit` to your PATH +The following variables are meant to be internal only and only ever used with the `-e` option of docker compose, but are worth documenting nevertheless: +- `CACHEDIR`: Defines the directory where the cache of computed builds using `DEVREF` should be stored. -Docker alternative: +#### Saving output +By defualt the output is not saved to a file but you can do so some your shell by either using `docker compose up busted-tests > log` (platform agnostic) or `docker compose up busted-tests | tee log` which will also allow you to see the output as it's being printed out (powershell/linux). -1. Install [Docker](https://www.docker.com/get-started) -2. Run `docker-compose up` from the command line +Additionally, the output from `busted-diff` can be quite noisy. If you'd like to only get a specific part of the output you can use to following: +- `sed -n '/Runtime comparison for/,/Savefile Diff for/{/Savefile Diff for/!p;}' log` to only print out runtime information or nothing if nothing interesting is to be shown. +- `sed -n '/Savefile Diff for/, $p' /tmp/dockerlog` to print out parsed output mismatch information as well as raw text diff of the generated build xml. ### Debugging tests When running tests with a docker container it is possible to use emmylua for debugging. Paste in the following right under `function launch:OnInit()` in `./src/Launch.lua`: @@ -225,7 +231,7 @@ local dbg = require("emmy_core") dbg.tcpListen("localhost", 9966) dbg.waitIDE() ``` -After running `docker-compose up` the code will wait at the `dbg.waitIDE()` line until a debugger is attached. This will allow stepping through any code that is internal to POB but will not work for busted related code. +After running `docker-compose up busted-tests` the code will wait at the `dbg.waitIDE()` line until a debugger is attached. This will allow stepping through any code that is internal to POB but will not work for busted related code. Note that this only works for unit tests described above. ## Path of Building development tutorials From 4e8861cefe8aff657f99366dc0c3307db5a7cf1f Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Wed, 10 Jul 2024 02:25:59 +0200 Subject: [PATCH 100/106] FIX: spelling --- CONTRIBUTING.md | 6 +++--- spec/GenerateBuilds.lua | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d1551ffa0c9..394aadee37d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -201,12 +201,12 @@ If you're on windows, consider downloading [git for windows](https://git-scm.com If you're using linux you can run the ./runtime/Path{space}of{space}Building.exe executable with wine. You will need to provide a valid wine path to the emmy lua debugger directory. ## Testing -Pob uses two types of tests. Unit tests that test specifc calculations or mechanics and "build diff" tests that calculate the effect the changes have on a given list of builds. +Pob uses two types of tests. Unit tests that test specific calculations or mechanics and "build diff" tests that calculate the effect the changes have on a given list of builds. While both can be ran locally it's recommended to use the provided docker image for both ease of use and to keep everyone on the same page. To run the unit tests run `docker compose up busted-tests`. This option uses the [Busted](https://olivinelabs.com/busted/) framework to test values returned by specific functions. For more details see the implementation of the tests in `spec/System/`. -To run the build difference tests run `docker compose up busted-diff`. `busted-diff` busted diff first computes a list of builds found in `spec/builds.txt` and `spec/TestBuilds/` while checked out to the current working changes. Then it uses git to checkout the branch specified by `DEVREF` or `dev` by defualt and computes the same builds. Lastly it finds the differences in the outputs generated from both, does some post processing, and prints all of the information out. +To run the build difference tests run `docker compose up busted-diff`. `busted-diff` busted diff first computes a list of builds found in `spec/builds.txt` and `spec/TestBuilds/` while checked out to the current working changes. Then it uses git to checkout the branch specified by `DEVREF` or `dev` by default and computes the same builds. Lastly it finds the differences in the outputs generated from both, does some post processing, and prints all of the information out. `busted-diff` supports the following options through environment variables: - `DEVREF`: Defines the branch to use as the reference against which to compare builds computed with new changes. @@ -216,7 +216,7 @@ The following variables are meant to be internal only and only ever used with th - `CACHEDIR`: Defines the directory where the cache of computed builds using `DEVREF` should be stored. #### Saving output -By defualt the output is not saved to a file but you can do so some your shell by either using `docker compose up busted-tests > log` (platform agnostic) or `docker compose up busted-tests | tee log` which will also allow you to see the output as it's being printed out (powershell/linux). +By default the output is not saved to a file but you can do so some your shell by either using `docker compose up busted-tests > log` (platform agnostic) or `docker compose up busted-tests | tee log` which will also allow you to see the output as it's being printed out (powershell/linux). Additionally, the output from `busted-diff` can be quite noisy. If you'd like to only get a specific part of the output you can use to following: - `sed -n '/Runtime comparison for/,/Savefile Diff for/{/Savefile Diff for/!p;}' log` to only print out runtime information or nothing if nothing interesting is to be shown. diff --git a/spec/GenerateBuilds.lua b/spec/GenerateBuilds.lua index abcb537b393..9ed6c9de924 100644 --- a/spec/GenerateBuilds.lua +++ b/spec/GenerateBuilds.lua @@ -77,12 +77,12 @@ for testBuild in fetchBuilds("../spec/TestBuilds") do local calcDuration = GetTime() - startTime print("[-] Computed " .. filePath .. " in " .. calcDuration .. "ms") - -- Save the computed build xml. Include full minuion and player outputs. + -- Save the computed build xml. Include full minion and player outputs. local buildHnd = io.open(filePath .. ".build", "w+") buildHnd:write(build:SaveDB("Cache", {fullPlayerStat = true, fullMinionStat = true} )) buildHnd:close() - -- Save the amount of time calcutation of this build took + -- Save the amount of time calculation of this build took local timeHnd = io.open(filePath .. ".time", "w+") timeHnd:write(calcDuration) timeHnd:close() From edf53f61d725828a365c556cffe83b4f73de7e08 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Wed, 10 Jul 2024 02:36:20 +0200 Subject: [PATCH 101/106] FIX: specifty a path for artefact download action in update list workflow --- .github/workflows/updatebuildlist.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/updatebuildlist.yml b/.github/workflows/updatebuildlist.yml index 1574a5f927d..d0f03e602d8 100644 --- a/.github/workflows/updatebuildlist.yml +++ b/.github/workflows/updatebuildlist.yml @@ -15,9 +15,10 @@ jobs: with: name: builds.txt if_no_artifact_found: warn + path: /tmp/latestbuildlist/ - name: Update list run: > - cat builds.txt + cat /tmp/latestbuildlist/builds.txt <({ curl "https://pobarchives.com/api/builds?q=latest" & curl "https://pobarchives.com/api/builds?q=trending"; } | jq -r '.builds[].build_info.build_link') | sort -u From 04dfbed8934e56581b51d6c22d02cd735c6eef78 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Wed, 10 Jul 2024 03:07:24 +0200 Subject: [PATCH 102/106] FIX: quote cron string --- .github/workflows/updatebuildlist.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/updatebuildlist.yml b/.github/workflows/updatebuildlist.yml index d0f03e602d8..f446ce51958 100644 --- a/.github/workflows/updatebuildlist.yml +++ b/.github/workflows/updatebuildlist.yml @@ -2,7 +2,7 @@ name: Update build list for tests on: schedule: - - cron: 20 4 * * * + - cron: '20 4 * * *' workflow_dispatch: jobs: update-builds-list: From 929fb8df8706039005788b73f3c72b519aefce67 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Thu, 11 Jul 2024 07:07:01 +0200 Subject: [PATCH 103/106] FIX: return the full list of static build link to builds.txt and use it as base for generation of newer build lists in case there isn't enough new builds. --- .github/workflows/updatebuildlist.yml | 6 +- spec/builds.txt | 495 ++++++++++++++++++++++++++ 2 files changed, 499 insertions(+), 2 deletions(-) diff --git a/.github/workflows/updatebuildlist.yml b/.github/workflows/updatebuildlist.yml index f446ce51958..ea841152b01 100644 --- a/.github/workflows/updatebuildlist.yml +++ b/.github/workflows/updatebuildlist.yml @@ -8,6 +8,8 @@ jobs: update-builds-list: runs-on: ubuntu-22.04 steps: + - name: Checkout HEAD + uses: actions/checkout@v4 - name: Install moreutils run: sudo apt-get install -y moreutils - name: Download latest build list @@ -18,11 +20,11 @@ jobs: path: /tmp/latestbuildlist/ - name: Update list run: > - cat /tmp/latestbuildlist/builds.txt + cat spec/builds.txt /tmp/latestbuildlist/builds.txt <({ curl "https://pobarchives.com/api/builds?q=latest" & curl "https://pobarchives.com/api/builds?q=trending"; } | jq -r '.builds[].build_info.build_link') - | sort -u | tail -n 500 + | sort -u | sponge builds.txt - name: Print new builds list run: cat builds.txt diff --git a/spec/builds.txt b/spec/builds.txt index 491ed25adbb..151125595df 100644 --- a/spec/builds.txt +++ b/spec/builds.txt @@ -1 +1,496 @@ https://pobb.in/IE4NagN7GTSG +https://pobb.in/JMVIpB8NfS3W +https://pobb.in/PadeL7jl7LOf +https://pobb.in/LWMgGFgeY1OA +https://pobb.in/q_zvdst3wVY8 +https://pobb.in/wYMBCn6VMnMH +https://pobb.in/9Zk2dHONu60p +https://pobb.in/QYMalBGKpank +https://pobb.in/TaEKdjV0Q6op +https://pobb.in/S9aqRfwcRkig +https://pobb.in/l8yyxQSve0-q +https://pobb.in/uDXPObcS5Umk +https://pobb.in/ibssLb49uDS3 +https://pobb.in/Be-pUqssGfa0 +https://pobb.in/TElsp5oR8Nsg +https://pobb.in/bECv3LzPKBKo +https://pobb.in/wDLFVhLgWirR +https://pobb.in/hK_Y2CnOWZ4F +https://pobb.in/54U-kgJ4MRKu +https://pobb.in/ki6HrllV1aB8 +https://pobb.in/SFslJqvR7cfk +https://pobb.in/Hsa-VHPxZoIY +https://pobb.in/j0pMpMx3_TU0 +https://pobb.in/AjXV0g6w6CGl +https://pobb.in/Wq7-YT2p1vZE +https://pobb.in/xYp-wwPp8a3y +https://pobb.in/Z2Mvl7EeuCxV +https://pobb.in/R2KCSu20A0x1 +https://pobb.in/smbctdc34cfH +https://pobb.in/eveJpzFgpABq +https://pobb.in/kQDsMsssM7Cd +https://pobb.in/IR-wmUnzNb5t +https://pobb.in/zja6gYi85Vi- +https://pobb.in/Gmy8Ha5XjlxH +https://pobb.in/bopGfR_OtxAd +https://pobb.in/eK0GthXVFTli +https://pobb.in/eGEoXF_1JMdv +https://pobb.in/TNseXhh0s34I +https://pobb.in/HjFpaJopbgkn +https://pobb.in/upwMs8RD7tqc +https://pobb.in/oTC_P19aN0mw +https://pobb.in/nyUDdl-MeE0i +https://pobb.in/tE1ikJ5jhvsQ +https://pobb.in/9eiU4SQvNhVn +https://pobb.in/Sf2cUlge3cXA +https://pobb.in/WNHPmLkPheCX +https://pobb.in/FXTjzI2no-iV +https://pobb.in/DEjQ59pJ6cep +https://pobb.in/jZmghaat0TTG +https://pobb.in/DjWB3Yn4PQpk +https://pobb.in/mi9rConMt-54 +https://pobb.in/KaB-X8C_HnwY +https://pobb.in/H3kffOAomNKu +https://pobb.in/81Q8t9QQHNsV +https://pobb.in/8af4qRbuvqeU +https://pobb.in/4wM1Zr7K4Cwh +https://pobb.in/oEb8wRv8BOej +https://pobb.in/V1-geRkxnEcP +https://pobb.in/96VEtNXW6rJc +https://pobb.in/ncOsN44is4np +https://pobb.in/ujB8-bN7xp-U +https://pobb.in/XpzE_KgjezkM +https://pobb.in/-vF0TFPojXt4 +https://pobb.in/djd3NOvOpUsL +https://pobb.in/44KghQ9UqV6c +https://pobb.in/3PQauTJQ9P6W +https://pobb.in/7wS-Qr0iSpc1 +https://pobb.in/gKFXA0EGw5zl +https://pobb.in/Ts39eMN4t56c +https://pobb.in/C6BOw8mtr6sp +https://pobb.in/C9WsIXJRy2HL +https://pobb.in/CQ4dTqZ0Nabz +https://pobb.in/X5TM5bwvvMd8 +https://pobb.in/JAAcoQ4Nd0ag +https://pobb.in/U_qxBoex9q7D +https://pobb.in/HF9t3mpb3zvp +https://pobb.in/L37mELjitfF8 +https://pobb.in/51C82oj0V1fA +https://pobb.in/m2PrCSq4xATv +https://pobb.in/hRfNYcsWwEmQ +https://pobb.in/ONDumuLU7Nrc +https://pobb.in/EjCrx9iIz_3s +https://pobb.in/nuC1qi1XEUE9 +https://pobb.in/sYdsB2H1DRkW +https://pobb.in/USwKhqanxkrr +https://pobb.in/ZQHLowtcuOn2 +https://pobb.in/VfpcLLf5Bjbr +https://pobb.in/umWKn_8AvlZJ +https://pobb.in/Qp9e9gA4zFzJ +https://pobb.in/ybrNx5kxTHMz +https://pobb.in/1NELamxHjk5C +https://pobb.in/tBj-Q2Fev0M9 +https://pobb.in/BVkIESFInGox +https://pobb.in/ng94oXaUa2vN +https://pobb.in/2MS-ybrerKuf +https://pobb.in/lKMS_N9LfD8E +https://pobb.in/uxic87OGxF-p +https://pobb.in/msqiktNJDffw +https://pobb.in/nKS73-FkwtZm +https://pobb.in/J8uGzeIEMRO4 +https://pastebin.com/yG1tgaCg +https://pobb.in/l-Xcp7cvg-Tw +https://pobb.in/u2wc1WFpFaj8 +https://pobb.in/SZoyI6Jy0TFp +https://pobb.in/4_ZnR2-Ct5PU +https://pobb.in/DMkOVl-A7CZs +https://pobb.in/cWnAfWcNHjku +https://pobb.in/6Md0lMDThvlI +https://pobb.in/AGAW9dxt3tfT +https://pobb.in/07K2n1mKHPTO +https://pobb.in/__Y6sg-7_h68 +https://pobb.in/j_dK9-hBXXp1 +https://pobb.in/n3nBymGaoywE +https://pobb.in/LGTXj5e6RPjz +https://pobb.in/J3KrfHGH31QT +https://pobb.in/kDD9op-w40Md +https://pobb.in/FVj-y73u3Abs +https://pobb.in/H2LTrp1PY4M2 +https://pobb.in/ZKJUjQMXRsCJ +https://pobb.in/5GdRvEAs4euj +https://pobb.in/yj9Wv0s8PZii +https://pobb.in/eg3V2eQ0ppT1 +https://pobb.in/FUwe-p0FvKAS +https://pobb.in/u_sZqMzTBr-N +https://pobb.in/-qKa0Fmr-zEs +https://pobb.in/Fqg3Oj3-obFC +https://pobb.in/DsU2DCj8uDqi +https://pobb.in/PE7dH82SLAbt +https://pobb.in/w8pVlddWDTrL +https://pobb.in/NMhlIYKjldHw +https://pobb.in/rxKv6B0X_tX2 +https://pobb.in/FW71jq4UA9Ct +https://pobb.in/xL08XMlk6yG0 +https://pobb.in/poW0bqFnwQr8 +https://pobb.in/r144hi0DEA5S +https://pobb.in/dunJdoyV_pu3 +https://pobb.in/umLO5W1mC5hl +https://pobb.in/zQiLmaTQsOp4 +https://pobb.in/igA9-ny_Wj-T +https://pobb.in/EAN0PHgQ_i50 +https://pobb.in/-07NEIgxfZXk +https://pobb.in/Kgpci1pI0OS4 +https://pobb.in/kJMk1Imw4Cla +https://pobb.in/k4cvCJVzw5ps +https://pobb.in/8cYpafa-FcvQ +https://pobb.in/MHVtAEJMIQof +https://pobb.in/UMbOsddyQYIo +https://pobb.in/qAoa4bkZRmWF +https://pobb.in/_B4UCtDnKGuq +https://pobb.in/biAyASZ_k-jd +https://pobb.in/BON5TeD7q5zF +https://pobb.in/C6aRrRYo78Eo +https://pobb.in/ruth1aHXLvxm +https://pobb.in/mqTWkmle8dTh +https://pobb.in/6QvNFqiAsBtQ +https://pobb.in/-ri8yvFeO0Vg +https://pobb.in/_UU9l9YX2LMF +https://pobb.in/b0Pu_tGvrukP +https://pobb.in/OApAqAX0gEUW +https://pobb.in/7MP8wjKatZjS +https://pobb.in/Z3nMFjOa6RLb +https://pobb.in/Y4F2fc4e-OtY +https://pobb.in/98burVE6hQ9l +https://pobb.in/FV2YnevL2u7D +https://pobb.in/TT7iT91rlUvG +https://pobb.in/bmlnUSUxiaU3 +https://pobb.in/ZpCrq6o_WFq2 +https://pobb.in/zEd5CTxQOLy3 +https://pobb.in/KlhL43emVusy +https://pobb.in/IdVH4TjSJMAF +https://pobb.in/iUUqFn14sfx7 +https://pobb.in/4A9xkLDdC2OS +https://pobb.in/sgQMgrN8Jg_H +https://pobb.in/fPc0Zt5YLPbU +https://pobb.in/qQ_NhnnUeEnn +https://pobb.in/pm5hGr_tqyUX +https://pobb.in/GtcA12JNvIQh +https://pobb.in/qFuuQGdemab5 +https://pobb.in/ipHlHvOWoqiR +https://pobb.in/UJoTJ_ywk0k_ +https://pobb.in/JjcBjl0RLx2D +https://pobb.in/kc5pFI73edqg +https://pobb.in/ERs0XDcMQ3hX +https://pobb.in/dxUNR6IORnQh +https://pobb.in/xbKYB5-9Spgj +https://pobb.in/19g9h80Djjs3 +https://pobb.in/3G8BQeLgJ0CJ +https://pobb.in/oQ0QcoKQFG4w +https://pobb.in/6pfeNsHZad_7 +https://pobb.in/EEa1kJ12fAHj +https://pobb.in/QCdaKepWj3J- +https://pobb.in/hAiM4csejJYU +https://pastebin.com/RbenZLcL +https://pobb.in/amaVuJ-WNuKd +https://pobb.in/-uU1KKrG8DU6 +https://pastebin.com/YnFDFirq +https://pobb.in/5LGtZufFvSHn +https://pobb.in/kJXRsYGXUx3Z +https://pobb.in/KoF2O2baexKs +https://pobb.in/QxVS-5o_6-9o +https://pobb.in/NBDi-6HwJigd +https://pobb.in/MUCA5xW1bA9V +https://pobb.in/XFSKeMsGqUcb +https://pobb.in/W6TCokL0IIsk +https://pobb.in/i3qcpqefso9L +https://pobb.in/OzJBlGxXBdf2 +https://pobb.in/Od2Wr-ilQDgf +https://pobb.in/dXGok1zpqCHY +https://pobb.in/8kLdNpTN-jFV +https://pobb.in/zZgJQ4WuD1kK +https://pobb.in/FzwIG3u64DHs +https://pobb.in/ArZ3B6b0W6UN +https://pobb.in/Fit5Pv2r3dEt +https://pobb.in/-3zKE3-NyVdL +https://pobb.in/whuvRIBGJhj- +https://pobb.in/YmmaeMeO40X7 +https://pobb.in/wie9SgFJwdwt +https://pobb.in/Be-Mg1mfcHdo +https://pobb.in/Egkh6-Ylp3Km +https://pobb.in/ovnS-f5WpcTm +https://pobb.in/nM3sdJpoEq9K +https://pobb.in/btEtteqXKRa8 +https://pobb.in/nWLRSTZEdFeW +https://pobb.in/EjmN9uy5UtTw +https://pobb.in/RYj-fud6QGlq +https://pobb.in/5lKIKuhS0S2o +https://pobb.in/NDmhKmUU8CYm +https://pobb.in/e2qZC7brodaX +https://pobb.in/E01ehXOj2gPI +https://pobb.in/z9BLpX_gt6YN +https://pobb.in/frtAFt9I5Ax0 +https://pobb.in/oIigpdp1_ZKq +https://pobb.in/tJs_Kcs4Bayb +https://pobb.in/pNhDaiKOMRBT +https://pobb.in/k02IW8DdiV6r +https://pobb.in/O9KMAKsQ3h90 +https://pobb.in/KqayL94duAFF +https://pobb.in/vxqhmw3IVoGN +https://pobb.in/BTvfZ5ufsu0c +https://pobb.in/O7dPnRNPZ_oO +https://pobb.in/-0ih9zEjNaBz +https://pobb.in/dNTFsdREKjqo +https://pobb.in/ecoXor593v4F +https://pobb.in/MpIHozx1EAgX +https://pobb.in/fdvDqj5SZ66G +https://pobb.in/7Spit2UZivbD +https://pobb.in/nfXnKQgtV1MQ +https://pobb.in/b7Rrle5O6dgB +https://pobb.in/8mScph1Saz57 +https://pobb.in/YjQUHEg9VHr_ +https://pobb.in/D7EPVT9wDK8f +https://pobb.in/TQN51If6AivG +https://pobb.in/1R7av1-GlriU +https://pastebin.com/1eZvWjQS +https://pobb.in/wl7njZwp-gP- +https://pobb.in/ziPgzKQAx2RU +https://pobb.in/gFWZt6FQlUON +https://pobb.in/Vck_qesvrWl9 +https://pobb.in/gzwNUqSD9_Ay +https://pobb.in/mylx0CKFXS0o +https://pobb.in/9YtjT89tX1uw +https://pobb.in/KqYBczFCFFV2 +https://pobb.in/XnNaXObqrqOz +https://pobb.in/ZtHR1MMDweUm +https://pobb.in/adFZRE4IHHBp +https://pobb.in/J1XxP7H_ebrw +https://pobb.in/URiRfcG5mV8m +https://pobb.in/brlnMafiHfeZ +https://pobb.in/58v7bIFnJxAa +https://pobb.in/bEUeNTkfbQuU +https://pobb.in/SQapgfbsL0f2 +https://pobb.in/R683B_NROGRj +https://pobb.in/hXdcBoPDa47l +https://pobb.in/QKF7pe9I1eZV +https://pobb.in/UGoeMrlnKQHh +https://pobb.in/eoZv--XORO9I +https://pobb.in/myrEejDOoBI4 +https://pobb.in/hZOZ3T6UgztH +https://pobb.in/J_Jyry_qcghc +https://pobb.in/rXr6yvdu1zpu +https://pobb.in/kEPNzt-lrQ4f +https://pobb.in/LC4U9fqLzbZf +https://pobb.in/boAKRwdZSR_M +https://pobb.in/pMK-3DEn0Kn_ +https://pobb.in/cCDCMzJpKlwA +https://pobb.in/J5Rg9mFOAcZt +https://pobb.in/tpyjCb-pLJSU +https://pobb.in/N5JeP04hARDc +https://pobb.in/d8hImyN06HKm +https://pobb.in/cwe79SGznaKo +https://pobb.in/nzTB2wmLVuYz +https://pobb.in/W-OKqb1RKYDi +https://pastebin.com/nd8XxzjM +https://pobb.in/CFNO_oeTo_6x +https://pastebin.com/Lp8RPvQK +https://pobb.in/-nZb_3q4n1p8 +https://pobb.in/pp4kYKfSlE3A +https://pobb.in/0Z1AA1p5n729 +https://pobb.in/ntxxIpw6FDW6 +https://pobb.in/vHmb69DHcdcu +https://pobb.in/1jf4AAQl9nRf +https://pastebin.com/ZeTzsRCi +https://pobb.in/KVc0guxzydXP +https://pobb.in/ar_eGJtxlp3A +https://pobb.in/youWw0a8CbHY +https://pobb.in/6l9rHWCkFQ3Q +https://pobb.in/9tnQ1Dp_Qebf +https://pobb.in/l5hKsuh2AVh6 +https://pobb.in/wctVq9Hwu8J8 +https://pobb.in/w0pVHB60rZm8 +https://pobb.in/KkBEcBzeXnsR +https://pobb.in/oeegwBv0Qwvq +https://pobb.in/Kk_VWB6C6i81 +https://pobb.in/YDIX5MnktplJ +https://pobb.in/ru2tii6_MD9b +https://pobb.in/BHHHAyNV9aRG +https://pobb.in/xMMmoinpxF-D +https://pobb.in/j3JOYwi2rGYN +https://pobb.in/bwHiVbS-UnKY +https://pobb.in/hESRI9SwTx8R +https://pobb.in/2JP91_esEXeY +https://pobb.in/58_EoX-p9HPD +https://pobb.in/iJN8SdZweah6 +https://pobb.in/_HzKifZYLkiW +https://pobb.in/rpixrdV1Z91b +https://pobb.in/UeSag0MBfAqz +https://pobb.in/9ACP67JVEGy0 +https://pobb.in/cWehUbRlP8VJ +https://pobb.in/R8FBmZ-8seLJ +https://pobb.in/uAgF2TfO2Diu +https://pobb.in/xDjuKrTF_-TT +https://pobb.in/jPTzGdcSKoxO +https://pobb.in/nlBGVt-w7jIc +https://pobb.in/zClgDj1g4H1G +https://pobb.in/ysJFWoXdNC9z +https://pobb.in/HXhNfnA6XmGY +https://pobb.in/JcolJsbDhNiN +https://pobb.in/GVSZSVDdnk1U +https://pobb.in/n0vWHE8tAcAL +https://pobb.in/0X00op3OB8jy +https://pobb.in/qTJGBNpjZ-o4 +https://pobb.in/PNAHoexwgF3o +https://pobb.in/m76dOUMfn1Ng +https://pastebin.com/qk555ufY +https://pobb.in/ZdBfjiDOiXy6 +https://pobb.in/GhTxgBYTUlFw +https://pobb.in/zeQxZwv1UAaa +https://pobb.in/gN3mL1bveLUi +https://pobb.in/9DbGmC9fX0Wb +https://pobb.in/4U8mrcEjkpID +https://pobb.in/Ndz7Z5OTrtK6 +https://pobb.in/MSANateBSMmQ +https://pobb.in/je175Y4q3tLm +https://pobb.in/yIX1EcF3_sNI +https://pobb.in/NQNuVrtZme9v +https://pobb.in/f5jjLp0rqvyW +https://pastebin.com/5GwgeTNV +https://pobb.in/JQJvmXE-Qogt +https://pobb.in/eyDFABaanqys +https://pastebin.com/9WBmCym4 +https://pobb.in/uTQEE6P4SmvW +https://pobb.in/5RIoMXHby-68 +https://pobb.in/BYYJdC33uCZT +https://pobb.in/E9nMI7FpnkGD +https://pobb.in/A8QX9H2p-m3D +https://pobb.in/Zs4Vhc1dEV16 +https://pobb.in/-cemSYSYqEEb +https://pobb.in/BwSEKcZ9OxRB +https://pobb.in/s9-ne_IZOpnQ +https://pobb.in/z3av5TS1fuUb +https://pobb.in/ka630Ngl2-oA +https://pobb.in/02qCbBTXOY2c +https://pobb.in/f8ksWeJvFw4r +https://pobb.in/0MYdjMBiyfXy +https://pastebin.com/cYwitwH8 +https://pobb.in/tZiG_YkM4_SX +https://pobb.in/XVIhxflBLgPH +https://pobb.in/JxTgZhFEoT9Y +https://pobb.in/ICzYnUryUOJx +https://pobb.in/Eoscl_ecmquX +https://pobb.in/G2ST2EGEH6Ws +https://pobb.in/-hyqzoGdSIyy +https://pobb.in/WLaxdhgNAesT +https://pobb.in/tNnUh68kHqW1 +https://pobb.in/opmUHt10iZed +https://pobb.in/prNyfUoiU1ME +https://pobb.in/FUrwupJJMpe6 +https://pobb.in/jbxsfUHQeDFy +https://pobb.in/pHctVCc1g8Mo +https://pobb.in/qzz_EbCzrAqJ +https://pobb.in/UssJKC1R6J98 +https://pobb.in/HQXGNILQ3bXj +https://pobb.in/vPVSF6A_W9kt +https://pobb.in/qj-rO9r1pQkk +https://pobb.in/sAuoMjX7zgyT +https://pobb.in/k_VbhDiHkfI8 +https://pobb.in/9QocExspWjTt +https://pobb.in/I-y3rBmHE7b1 +https://pobb.in/rN2kBaCb6OnM +https://pobb.in/FBY2ZLDw46Gn +https://pobb.in/ouY4mkkNYb-S +https://pobb.in/a90g42YBMhsW +https://pobb.in/Ba3CrESw8pwL +https://pobb.in/rdHcu3MEVtCV +https://pobb.in/7IUuwkTI203Z +https://pobb.in/wDjmKwMqrqqW +https://pobb.in/ekY1obH52hqJ +https://pobb.in/LJGqqZWfFnPU +https://pobb.in/QGNJ1pWGIPK5 +https://pobb.in/lcLST082wmO0 +https://pobb.in/E0M0PCnEOaf4 +https://pobb.in/7FhQM6rvfhkI +https://pobb.in/aAKn8AEJyJ8n +https://pobb.in/rr7qFsUZxpSH +https://pobb.in/Rp91CLLyDHXU +https://pobb.in/jJME3E1mwQ6x +https://pobb.in/kxKmf-BJfJqT +https://pobb.in/UqvH2efeHzB5 +https://pobb.in/egWgtV1d8iH2 +https://pobb.in/RmXtwiQALDy2 +https://pobb.in/Lipuk3Z1-AdQ +https://pobb.in/kD86OErOjQE2 +https://pobb.in/vlOTOWEwKEv8 +https://pobb.in/Zw4Pp3RgxPlw +https://pastebin.com/wnTVPGMS +https://pobb.in/P3CrdnXe79mU +https://pobb.in/1B8U9yDy_Wot +https://pobb.in/JWqxKBaZCKIi +https://pobb.in/peZH2ped5HpE +https://pobb.in/FXvCmpVGGx5V +https://pobb.in/m8iRz-fn3uuF +https://pobb.in/65mn49zAbxws +https://pobb.in/LxsyUa-yWWEA +https://pobb.in/uRqFMMOWj4ek +https://pobb.in/La6HbUOD8_cj +https://pobb.in/YvevUAopdZ0X +https://pobb.in/K8JyNeqlrtc8 +https://pobb.in/34dqVVWIZkty +https://pobb.in/6f4RyqRtXFU_ +https://pobb.in/y12TnJ8tObgn +https://pobb.in/moB2wtUhTIdB +https://pobb.in/yDr0yZAGgUj2 +https://pobb.in/V4QOuXTmUEES +https://pobb.in/sf4FtBCkwXAX +https://pobb.in/_OcWkcEWx2Hg +https://pobb.in/Qny0dRVqnITx +https://pobb.in/-S2_PaHL8uaX +https://pobb.in/EL-I8fx0HJ7M +https://pobb.in/qVCfgLmjL1rw +https://pobb.in/gXZIKt0z8cTh +https://pobb.in/2kki0_TSLH8M +https://pobb.in/GlzAApkyGTA8 +https://pobb.in/mTScfvMKTiiX +https://pobb.in/Bph43kHofnmV +https://pobb.in/_Wk3GlAEfUBp +https://pobb.in/h10qSifvN5U0 +https://pobb.in/6KGcQzUEMe5j +https://pobb.in/EZ5ZN0MoC94e +https://pobb.in/-CQO5fWQSRgx +https://pobb.in/tdKtccRiRIIm +https://pobb.in/_hfgEK0kcjMM +https://pobb.in/J_o3D0J952BE +https://pobb.in/8flglpMzzdzd +https://pobb.in/wXNw0j5BsXXw +https://pobb.in/WMkbZjhaNpP8 +https://pobb.in/WqflrzpJe15L +https://pobb.in/IY09cMdgFVkt +https://pobb.in/F7sdQa4QPD2_ +https://pobb.in/db_V85_Rj9-F +https://pobb.in/37zpDQwwGmLR +https://pobb.in/y3GwiyC_9y50 +https://pobb.in/uIJifV_JYepr +https://pobb.in/IzpBXdQVHzrG +https://pobb.in/wAW9bHB88p4F +https://pastebin.com/tUkdWJpR +https://pobb.in/f9wVoD5lv-ii +https://pobb.in/-9m6E9RwNtqA +https://pobb.in/MeEVBRxuhzIA +https://pobb.in/u1ACIWcPyWF- +https://pobb.in/sX1lD2ufzLxl +https://pobb.in/0qxEC-t_FPM8 +https://pobb.in/cnfuEVgb6iwe +https://pobb.in/ddoc0Vh7dZ7_ +https://pastebin.com/0HnALex8 +https://pobb.in/tDaxg2Nfv3zf +https://pobb.in/DMKCWkr_ie89 +https://pobb.in/WYgt_b7mVXfr +https://pobb.in/8DhWdsFzhpIk +https://pobb.in/g-2QBxQzV0yB +https://pobb.in/hlRkG9kVS_Z- +https://pobb.in/1dUQWideVatT +https://pobb.in/pqanrUkj78cn +https://pobb.in/4-4fDGHrZjQq +https://pobb.in/jyaHptqLpiDp +https://pobb.in/XEGUbhHv4GWY +https://pobb.in/pP0rCEVYOPjV From 8ffcee203b238b37d535f526116b399643efe0f3 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Sun, 14 Jul 2024 00:48:38 +0200 Subject: [PATCH 104/106] FIX: ambiguous branch error --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index af4c4057eea..5d184f7dea3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,7 +20,7 @@ services: environment: #Where in the container the folders are stored WORKDIR: /workdir HOME: /tmp - DEVREF: ${DEVREF:-dev} + DEVREF: ${DEVREF:-origin/dev} HEADREF: $HEADREF container_name: busted-diff tty: true From 526a34a7e9e6bc96cfad72124998601509155a16 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Thu, 18 Jul 2024 10:00:57 +0200 Subject: [PATCH 105/106] FEAT: initial work on formatting/linting/coverage tooling support --- .lua-format | 8 ++++++++ .luacheckrc | 4 ++++ Dockerfile | 22 ++++++++++++---------- docker-compose.yml | 17 +++++++++++++++++ src/.luacov | 1 + 5 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 .lua-format create mode 100644 .luacheckrc create mode 100644 src/.luacov diff --git a/.lua-format b/.lua-format new file mode 100644 index 00000000000..79f470e6aec --- /dev/null +++ b/.lua-format @@ -0,0 +1,8 @@ +column_limit: 160 +indent_width: 1 +use_tab: true +tab_width: 4 +continuation_indent_width: 4 +spaces_before_call: 1 +keep_simple_control_block_one_line: false +keep_simple_function_one_line: false \ No newline at end of file diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 00000000000..135eb48951f --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,4 @@ +globals = { "round", "modLib", "LoadModule", "data", "ModFlag", "KeywordFlag", "SkillType", "launch", "IsKeyDown", "copyTable", "main", "colorCodesA"} +read_globals = {"DrawString", "SetDrawLayer", "GetDrawLayer", "ConPrintf", "SetDrawColor", "DrawStringWidth", "GetCursorPos", "SetViewport", "GetTime", "DrawImage", "NewFileSearch", "MakeDir"} +max_line_length = false +exclude_files = { "src\\TreeData", "src\\Data"} diff --git a/Dockerfile b/Dockerfile index 186c1054e57..9add8f11359 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,35 +1,37 @@ -FROM alpine:3.18 as base +FROM alpine:3.18 AS base RUN apk add --no-cache curl unzip openssl build-base readline-dev cmake readline-dev git ca-certificates libcurl curl-dev zlib parallel tar libxml2-utils -FROM base as buildbase +FROM base AS buildbase WORKDIR /opt RUN wget https://www.lua.org/ftp/lua-5.1.5.tar.gz && tar -xf lua-5.1.5.tar.gz RUN cd lua-5.1.5 && make linux && make install -FROM buildbase as luarocks +FROM buildbase AS luarocks RUN wget https://luarocks.org/releases/luarocks-3.7.0.tar.gz && tar xf luarocks-3.7.0.tar.gz RUN cd luarocks-3.7.0 && ./configure && make -FROM buildbase as luajit +FROM buildbase AS luajit RUN git clone --depth 1 --branch v2.1.0-beta3 https://github.com/LuaJIT/LuaJIT RUN cd LuaJIT && make -FROM buildbase as emmyluadebugger +FROM buildbase AS emmyluadebugger RUN git clone --depth 1 --branch 1.7.1 https://github.com/EmmyLua/EmmyLuaDebugger RUN cd EmmyLuaDebugger && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release ../ && make +FROM buildbase AS luaformat +RUN git clone --depth 1 --branch 1.3.6 --recurse-submodules https://github.com/Koihik/LuaFormatter.git +RUN cd LuaFormatter && cmake . && make + FROM base RUN --mount=type=cache,from=buildBase,source=/opt,target=/opt make -C /opt/lua-5.1.5/ install RUN --mount=type=cache,from=luarocks,source=/opt,target=/opt make -C /opt/luarocks-3.7.0/ install #Install here to install pkgs in pararell with compilation of emmylua and luajit -RUN luarocks install busted -RUN luarocks install cluacov -RUN luarocks install Lua-cURL -RUN luarocks install lua-zlib -RUN luarocks install luaposix + +RUN parallel luarocks install ::: busted cluacov luacov luacov-coveralls Lua-cURL lua-zlib luaposix luacheck RUN --mount=type=cache,from=luajit,source=/opt,target=/opt make -C /opt/LuaJIT/ install && ln -sf /usr/local/bin/luajit-2.1.0-beta3 /usr/local/bin/luajit RUN --mount=type=cache,from=emmyluadebugger,source=/opt,target=/opt make -C /opt/EmmyLuaDebugger/build/ install +RUN --mount=type=cache,from=luaformat,source=/opt,target=/opt make -C /opt/LuaFormatter/ install CMD [ "echo", "This container is meant to be ran with docker compose. See: https://github.com/PathOfBuildingCommunity/PathOfBuilding/blob/dev/CONTRIBUTING.md" ] diff --git a/docker-compose.yml b/docker-compose.yml index 5d184f7dea3..b1982fef1bf 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,21 @@ services: + pob-format: + #build: . + image: ghcr.io/paliak/busted-tests:latest + container_name: pob-format + command: > + find . -name '*.lua' + ! -path "./src/TreeData/*" + ! -path "./src/Export/*" + ! -path "./src/Data/*" + ! -path "./runtime/*" + -print + -exec lua-format -i {} \; + security_opt: + - no-new-privileges:true + working_dir: /workdir + volumes: + - ./:/workdir busted-tests: #build: . image: ghcr.io/paliak/busted-tests:latest diff --git a/src/.luacov b/src/.luacov new file mode 100644 index 00000000000..b09564b30fa --- /dev/null +++ b/src/.luacov @@ -0,0 +1 @@ +statsfile = "/tmp/luacov.stats.out" From b64a077771b6b0d61679b4de174fbac87086ded5 Mon Sep 17 00:00:00 2001 From: Paliak <91493239+Paliak@users.noreply.github.com> Date: Thu, 18 Jul 2024 10:12:23 +0200 Subject: [PATCH 106/106] FIX: dockerfile luarocks install --- Dockerfile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 9add8f11359..d9e158d8518 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,7 +28,14 @@ RUN --mount=type=cache,from=luarocks,source=/opt,target=/opt make -C /opt/luaroc #Install here to install pkgs in pararell with compilation of emmylua and luajit -RUN parallel luarocks install ::: busted cluacov luacov luacov-coveralls Lua-cURL lua-zlib luaposix luacheck +RUN luarocks install busted;\ + luarocks install cluacov;\ + luarocks install luacov;\ + luarocks install luacov-coveralls;\ + luarocks install Lua-cURL;\ + luarocks install lua-zlib;\ + luarocks install luaposix;\ + luarocks install luacheck RUN --mount=type=cache,from=luajit,source=/opt,target=/opt make -C /opt/LuaJIT/ install && ln -sf /usr/local/bin/luajit-2.1.0-beta3 /usr/local/bin/luajit RUN --mount=type=cache,from=emmyluadebugger,source=/opt,target=/opt make -C /opt/EmmyLuaDebugger/build/ install