Skip to content

Commit

Permalink
Port to Windows (#216)
Browse files Browse the repository at this point in the history
This change set addresses #94 and ports baur to Windows. The `make release` command will create a _baur.exe_ file.
Things to note:
1. A [breaking change](golang/go#34610) was introduced to golang.org/x/sys that prevents github.com/docker/docker from compiling. This issue in github.com/docker/docker will not be [fixed](moby/moby#40021) until v20 of github.com/docker/docker is released. In the meantime I have pinned golang.org/x/sys to the latest version before the breaking change was introduced.
2. Some of the existing tests used commands specific to Unix. These have either been replaced with equivalent commands available directly on both Unix and Windows or run via `cmd /C` on Windows.
3. Windows does not allow files that are in use to be deleted in the same way as Unix. In some tests files and folders had to be released so the test cleanup succeeds.
4. Expected paths have been updated to use OS specific path separators where required.
5. CircleCI does not provide Windows containers but does provide Windows VMs
    * The pre-installed version of golang is 1.12.7, this needs to be updated on every build. See [software-pre-installed-in-the-windows-image](https://circleci.com/docs/2.0/hello-world-windows/#software-pre-installed-in-the-windows-image)
    * I could not access Unix docker containers from within the Windows job so postgres is installed on the VM via chocolatey and the default "postgres" database is used.
    * The tests are much slower to run on Windows than Unix, the test timeout has been increased to accommodate this.
    * The `-race` flag has been removed from the Windows `go test` command as a gcc compiler is not installed. I figured this wasn't a problem as it is used in the existing test job. This could be addressed later if necessary.
  • Loading branch information
dil-spayne authored Oct 21, 2020
1 parent 7fd2b6c commit 692dc80
Show file tree
Hide file tree
Showing 232 changed files with 91,053 additions and 21,740 deletions.
60 changes: 52 additions & 8 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Golang CircleCI 2.0 configuration file
# Check https://circleci.com/docs/2.0/language-go/ for more details
version: 2
version: 2.1

orbs:
win: circleci/[email protected]

jobs:
test:
test_linux:
docker:
- image: circleci/golang:1
environment:
Expand Down Expand Up @@ -48,7 +52,46 @@ jobs:
- store_test_results:
path: /tmp/test-results

build:
test_windows:
executor: win/default

environment:
GOFLAGS: -mod=vendor
TEST_RESULTS: ~/test-results
BAUR_TEST_POSTGRESQL_URL: "postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable"

working_directory: ~/baur

steps:
- checkout

- run:
name: Preparing Test Environment
command: |
choco install golang --version=1.15.2 -y
choco install postgresql12 --params '/Password:postgres' -y
New-Item -ItemType Directory -Force -Path $Env:TEST_RESULTS
- run:
name: Run Tests
command: |
$go111module = $Env:GO111MODULE
$Env:GO111MODULE="off"
go get github.com/jstemmer/go-junit-report
$Env:GO111MODULE=$go111module
git config --global user.email "[email protected]"
git config --global user.name "baur"
$testResultDir = Resolve-Path $Env:TEST_RESULTS
$testOutputPath = Join-Path $testResultDir "go-test.out"
$testReportPath = Join-Path $testResultDir "go-test-report.xml"
try { go test --tags=dbtest -v -timeout 5m .\... | Tee-Object -FilePath $testOutputPath } `
finally { Get-Content -Path $testOutputPath | go-junit-report > $testReportPath; `
[System.Io.File]::ReadAllText($testReportPath) | Out-File -FilePath $testReportPath -Encoding utf8 }
- store_test_results:
path: ~\test-results

build_linux:
docker:
- image: circleci/golang:1

Expand All @@ -60,7 +103,7 @@ jobs:
name: Building baur
command: make baur

static_analysis:
static_analysis_linux:
docker:
- image: golangci/golangci-lint:v1.31.0

Expand All @@ -73,9 +116,10 @@ jobs:
command: golangci-lint run

workflows:
version: 2
version: 2.1
workflow:
jobs:
- build
- test
- static_analysis
- build_linux
- test_linux
- test_windows
- static_analysis_linux
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ dist/linux_amd64/baur:
$(info * creating $(@D)/baur-linux_amd64-$(VERSION).tar.xz.sha256)
@(cd $(@D) && sha256sum baur-linux_amd64-$(VERSION).tar.xz > baur-linux_amd64-$(VERSION).tar.xz.sha256)

.PHONY: dist/windows_amd64/baur.exe
dist/windows_amd64/baur.exe:
$(info * building $@)
@CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build \
$(BUILDFLAGS) -o "$@" cmd/baur/main.go

.PHONY: dirty_worktree_check
dirty_worktree_check:
Expand All @@ -51,7 +56,7 @@ dirty_worktree_check:
fi

.PHONY: release
release: clean dirty_worktree_check dist/linux_amd64/baur dist/darwin_amd64/baur
release: clean dirty_worktree_check dist/linux_amd64/baur dist/darwin_amd64/baur dist/windows_amd64/baur.exe
@echo
@echo next steps:
@echo - git tag v$(VERSION)
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ require (
google.golang.org/protobuf v1.25.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
)

replace golang.org/x/sys => golang.org/x/sys v0.0.0-20190830141801-acfa387b8d69
29 changes: 2 additions & 27 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -436,33 +436,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c h1:38q6VNPWR010vN82/SB121GujZNIfAUb4YttE2rhGuc=
golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190830141801-acfa387b8d69 h1:Wdn4Yb8d5VrsO3jWgaeSZss09x1VLVBMePDh4VW/xSQ=
golang.org/x/sys v0.0.0-20190830141801-acfa387b8d69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
Expand Down
3 changes: 2 additions & 1 deletion internal/command/diff_inputs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package command
import (
"encoding/csv"
"fmt"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -392,7 +393,7 @@ func TestDifferencesOutputWithCorrectState(t *testing.T) {
executeWithoutError(t, diffInputsCmd)

expectedOutput := [][]string{
{"D", "app_one/diff_test.txt", originalDigest.String(), newDigest.String()},
{"D", filepath.FromSlash("app_one/diff_test.txt"), originalDigest.String(), newDigest.String()},
{"-", "string:run_one", "sha384:95e52b4c9863a13d596d34df980988cb78bea9ec3381ba981e1656a84cc1c7456f6830bca0e8931be5f0f48593cb5d06", ""},
{"+", "string:run_two", "", "sha384:f3d5e46502641c5591563a0d3157f19a9739616f07bdb4bbc0285cb0a12bd511c026db94f12c719378a20d0ffe85090e"},
}
Expand Down
2 changes: 1 addition & 1 deletion internal/command/testdata/var_in_include/tasks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
include_id = "build"
includes = ["$ROOT/inputs.toml#input"]
name = "build"
command = ["ls", "$APPNAME.txt"]
command = ["more", "$APPNAME.txt"]
18 changes: 16 additions & 2 deletions internal/command/upgrade_configs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package command
import (
"os"
"path/filepath"
"runtime"
"strings"
"testing"

Expand All @@ -21,9 +22,18 @@ func TestUpgrade(t *testing.T) {

initTest(t)

tempdir := t.TempDir()
// When running on Windows we need to change the working directory back to the original
// working directory so the temporary directory that is used can be deleted
var originalDir string
var err error
if runtime.GOOS == "windows" {
originalDir, err = os.Getwd()
assert.NoError(t, err)
}

gitDir := filepath.Join(tempdir, "git")
tempDir := t.TempDir()

gitDir := filepath.Join(tempDir, "git")

require.NoError(t, os.Chdir("/"))
gittest.Clone(t, gitDir, gitURL, commit)
Expand Down Expand Up @@ -57,4 +67,8 @@ func TestUpgrade(t *testing.T) {
assert.Contains(t, taskIDs, "myredis.build")
assert.Contains(t, taskIDs, "random.build")
assert.Contains(t, taskIDs, "unixtime.build")

if runtime.GOOS == "windows" {
require.NoError(t, os.Chdir(originalDir))
}
}
2 changes: 2 additions & 0 deletions internal/digest/sha384/sha384_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ func TestHashingNonExistingFileFails(t *testing.T) {
if err != nil {
t.Fatal("creating tempfile failed:", err.Error())
}
// The file must be closed before it can be deleted on Windows
file.Close()
os.Remove(file.Name())

sha := sha384.New()
Expand Down
39 changes: 34 additions & 5 deletions internal/exec/exec_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
package exec

import (
"fmt"
"runtime"
"testing"
)

func TestEchoStdout(t *testing.T) {
const echoStr = "hello world!"

res, err := Command("echo", "-n", echoStr).Run()
// Windows returns StrOutput with surrounding quotation marks
var expected string
if runtime.GOOS == "windows" {
expected = fmt.Sprintf("\"%s\"", echoStr)
} else {
expected = echoStr
}

var res *Result
var err error
if runtime.GOOS == "windows" {
res, err = Command("cmd", "/C", "echo", echoStr).Run()
} else {
res, err = Command("echo", "-n", echoStr).Run()
}

if err != nil {
t.Fatal(err)
}
Expand All @@ -16,13 +33,19 @@ func TestEchoStdout(t *testing.T) {
t.Fatalf("cmd exited with code %d, expected 0", res.ExitCode)
}

if res.StrOutput() != echoStr {
t.Errorf("expected output '%s', got '%s'", echoStr, res.StrOutput())
if res.StrOutput() != expected {
t.Errorf("expected output '%s', got '%s'", expected, res.StrOutput())
}
}

func TestCommandFails(t *testing.T) {
res, err := Command("false").Run()
var res *Result
var err error
if runtime.GOOS == "windows" {
res, err = Command("cmd", "/C", "exit", "1").Run()
} else {
res, err = Command("false").Run()
}
if err != nil {
t.Fatal(err)
}
Expand All @@ -37,7 +60,13 @@ func TestCommandFails(t *testing.T) {
}

func TestExpectSuccess(t *testing.T) {
res, err := Command("false").ExpectSuccess().Run()
var res *Result
var err error
if runtime.GOOS == "windows" {
res, err = Command("cmd", "/C", "exit", "1").ExpectSuccess().Run()
} else {
res, err = Command("false").ExpectSuccess().Run()
}
if err == nil {
t.Fatal("Command did not return an error")
}
Expand Down
5 changes: 5 additions & 0 deletions internal/fs/fileglob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ func Test_Resolve(t *testing.T) {
for _, tc := range testcases {
tempdir := t.TempDir()

// The path separators in the test cases are Unix style "/", they need to be converted to "\" when running on Windows
for i := range tc.expectedMatches {
tc.expectedMatches[i] = filepath.FromSlash(tc.expectedMatches[i])
}

if len(tc.dir) != 0 {
err := os.MkdirAll(filepath.Join(tempdir, tc.dir), os.ModePerm)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions internal/resolve/gosource/gosource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ func TestResolve(t *testing.T) {

for i := range testCfg.ExpectedResults {
testCfg.ExpectedResults[i] = strings.Replace(testCfg.ExpectedResults[i], "$WORKDIR", cwd, -1)
// The path separators in the test config are Unix style "/", they need to be converted to "\" when running on Windows
testCfg.ExpectedResults[i] = filepath.FromSlash(testCfg.ExpectedResults[i])
}

resolvedFiles, err := NewResolver(t.Logf).Resolve(
Expand Down
Loading

0 comments on commit 692dc80

Please sign in to comment.