diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..4cd6873 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,55 @@ +name: Build & Test Gamma + +on: + workflow_call: + inputs: + compiler_version: + type: string + required: true + build_type: + type: string + required: false + default: "debug" + +jobs: + build: + name: build & test Gamma + strategy: + matrix: + os: [Windows, Linux, MacOS] + include: + - os: Windows + runner: windows-latest + upload-path: ./gamma.exe + upload-name: gamma.windows-amd64.exe + - os: Linux + runner: ubuntu-latest + upload-path: ./gamma + upload-name: gamma.linux-amd64 + - os: MacOS + runner: macOS-latest + upload-path: ./gamma + upload-name: gamma.macos-amd64 + + runs-on: ${{ matrix.runner }} + + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Install LDC compiler for building gamma + uses: dlang-community/setup-dlang@v1 + with: + compiler: ${{ inputs.compiler_version }} + + - name: Build & run tests + run: | + dub build --build=${{inputs.build_type}} + dub test --build=unittest --config=example + + - name: Upload executables to workflow run page + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.upload-name }} + path: ${{ matrix.upload-path }} + retention-days: 1 diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..818c7a3 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,28 @@ +name: Check Gamma Project + +on: + workflow_call: + inputs: + compiler_version: + type: string + required: true + +jobs: + check: + name: Check Style + runs-on: ubuntu-latest + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Install D compiler + uses: dlang-community/setup-dlang@v1 + with: + compiler: ${{ inputs.compiler_version }} + + - run: | + dub fetch dscanner@0.14.0 + + - name: Check style + run: | + dub run dscanner -- --styleCheck src test diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 963d7a7..07eaf6c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,38 +1,20 @@ name: CI + on: push: + branches: + - "*" pull_request: jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - uses: dlang-community/setup-dlang@v1 - with: - compiler: dmd-2.103.1 - - - name: Build - run: | - dub build --compiler=$DC - - name: Test - run: | - dub test --compiler=$DC --config=example + build: + name: build & test + uses: ./.github/workflows/build.yml + with: + compiler_version: ldc-1.37.0 check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - uses: dlang-community/setup-dlang@v1 - with: - compiler: dmd-latest - - - run: | - dub fetch dscanner@0.14.0 - - - name: Check Style - run: | - dub run dscanner -- --styleCheck src test + uses: ./.github/workflows/check.yml + with: + compiler_version: dmd-2.107.1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..42c6954 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,19 @@ +name: Release + +on: + release: + types: [published] + +jobs: + + build: + name: build & test + uses: ./.github/workflows/build.yml + with: + compiler_version: ldc-1.33.0 + build_type: release-gamma + + upload: + uses: ./.github/workflows/upload.yml + secrets: inherit + needs: build diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml new file mode 100644 index 0000000..361beb5 --- /dev/null +++ b/.github/workflows/upload.yml @@ -0,0 +1,37 @@ +name: Upload release binaries + +on: + workflow_call: + +jobs: + upload: + name: Upload release binary + strategy: + matrix: + os: [Windows, Linux, MacOS] + include: + - os: Windows + exe-name: gamma.windows-amd64.exe + rename: mv ./gamma.exe + - os: Linux + exe-name: gamma.linux-amd64 + rename: mv ./gamma + - os: MacOS + exe-name: gamma.macos-amd64 + rename: mv ./gamma + + runs-on: ubuntu-latest + steps: + - name: Download binary from previous build job + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.exe-name }} + + - name: Give binary a unique name + run: ${{ matrix.rename }} ${{ matrix.exe-name }} + + - name: Upload release binary + uses: AButler/upload-release-assets@v3.0 + with: + files: ${{ matrix.exe-name }} + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/dub.json b/dub.json index 79e4d7c..5c67601 100644 --- a/dub.json +++ b/dub.json @@ -8,6 +8,11 @@ "importPaths": ["include", "src"], "mainSourceFile": "src/gamma/main.d", "stringImportPaths": ["fix/epsilon"], + "buildTypes": { + "release-gamma": { + "buildOptions": ["debugMode", "optimize", "inline", "debugInfo"] + } + }, "configurations": [ { "name": "gamma", diff --git a/src/gamma/main.d b/src/gamma/main.d index 47acca8..4e31a99 100755 --- a/src/gamma/main.d +++ b/src/gamma/main.d @@ -241,8 +241,9 @@ void build(string[] fileNames, string outputDirectory) if (!outputDirectory.empty) { args ~= format!"-od=%s"(outputDirectory); - args ~= format!"-of=%s"(fileNames.front.stripExtension); + args ~= format!"-of=%s"(fileNames.front.stripExtension.executableName); } + info!"%s"(args.join(' ')); auto pid = spawnProcess(args); @@ -251,3 +252,11 @@ void build(string[] fileNames, string outputDirectory) if (status) exit(status); } + +private string executableName(const string name) +{ + version(Windows) + return name ~ ".exe"; + else + return name; +} diff --git a/test/helper.d b/test/helper.d index 7367256..c4cfa7c 100644 --- a/test/helper.d +++ b/test/helper.d @@ -28,7 +28,18 @@ Result run(string fmt, A...)(lazy A args) import std.process : executeShell; import std.stdio : writeln; - const command = format!fmt(args); + auto command = format!fmt(args); + + version(Windows) + { + import std.string : translate; + dchar[dchar] translation = ['/': '\\']; + command = translate(command, translation); + + import std.regex : regex, replaceAll, replaceFirst; + command = replaceFirst(command, regex("echo\\s+\\|"), "echo. |"); + command = replaceAll(command, regex("\\bcat\\b"), "type"); + } writeln(command); return executeShell(command); @@ -57,3 +68,11 @@ Result shouldFailWith(Result result, string pattern) } return result; } + +string asSingleLineDosInput(string multiLineInput) +{ + import std.string : translate; + + string[dchar] translation = ['\n' : " ", '|' : "^|", '<' : "^<", '>' : "^>"]; + return translate(multiLineInput, translation); +} diff --git a/test/issues.d b/test/issues.d index 206df82..7b6f8fe 100644 --- a/test/issues.d +++ b/test/issues.d @@ -15,8 +15,17 @@ unittest A: 'a' A. `.outdent; - run!"cat < %s\\input.eag && type %s\\input.eag | ./gamma --output-directory %s" + (directory, eag.asSingleLineDosInput, directory, directory, directory) + .shouldFailWith("error: start symbol S is unproductive"); + } + else + { + run!"cat <: A | 'b'. A: 'a' A. `.outdent; - - run!"cat < %s\\input.eag && type %s\\input.eag | ./gamma --output-directory %s" + (directory, eag.asSingleLineDosInput, directory, directory, directory) + .shouldPassWith("warn: A is unproductive"); + } + else + { + run!"cat <: 'a' S 'b'. `.outdent; - - run!"cat < %s\\input.eag && type %s\\input.eag | ./gamma --output-directory %s" + (directory, eag.asSingleLineDosInput, directory, directory, directory) + .shouldPassWith("S grammar is SLAG"); + } + else + { + run!"cat <