Skip to content

Draft: Introduce tests of the binary #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/actions/os-info/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# OS Info GitHub Action

This action detects and outputs information about the current operating system and architecture directly to stdout.

## Information Provided

The action outputs the following information directly to the console:

| Information | Description |
|-------------|-------------|
| OS | The operating system (Linux, macOS, Windows) |
| Architecture | The architecture (amd64, arm64, etc.) |
| OS Version | The OS version or distribution |

## Example Usage

```yaml
jobs:
example-job:
runs-on: ubuntu-latest
steps:
- name: Get OS Info
uses: launchrctl/launchr/.github/actions/os-info@main
# The action will output OS information directly to the console
# No need to capture or use outputs in subsequent steps

- uses: actions/checkout@v4
```
41 changes: 41 additions & 0 deletions .github/actions/os-info/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: 'OS Info'
description: 'Get information about the current operating system and architecture'

runs:
using: "composite"
steps:
- name: OS and Architecture (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
# Set OS
echo "OS Type: Linux"
echo "Architecture: $(uname -m)"
echo "Kernel version: $(uname -r)"
if [ -f /etc/os-release ]; then
. /etc/os-release
echo "OS Version: $NAME $VERSION_ID"
else
echo "OS Version: unknown"
fi

- name: OS and Architecture (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
echo "OS: macOS"
echo "Architecture: $(uname -m)"
# Get OS Version
OS_VERSION="$(sw_vers -productName) $(sw_vers -productVersion)"
echo "OS Version: $OS_VERSION"

- name: OS and Architecture (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$arch = [System.Environment]::GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")
$winVer = [System.Environment]::OSVersion.Version.ToString()

Write-Host "OS: Windows"
Write-Host "Architecture: $arch"
Write-Host "OS Version: Windows $winVer"
16 changes: 16 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: CI
on:
push:
branches:
- '**'
paths-ignore:
- 'README.md'
- 'LICENSE'
- '.gitignore'
- 'example/**'
- 'docs/**'

jobs:
common-tests:
name: Test
uses: ./.github/workflows/common-tests.yaml
62 changes: 62 additions & 0 deletions .github/workflows/common-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Test
on:
workflow_call:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: Test ${{ matrix.name }}
strategy:
matrix:
include:
- name: Linux (amd64)
os: ubuntu-latest
- name: Linux (arm64)
os: ubuntu-24.04-arm
- name: MacOS (amd64)
os: macos-13
- name: MacOS (arm64)
os: macos-latest
- name: Windows (amd64)
os: windows-latest
continue-on-error: true # TODO: Windows is not well supported
- name: Windows (arm64)
os: windows-11-arm
continue-on-error: true
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.continue-on-error || false }}
steps:
- uses: actions/checkout@v4

- name: OS Info
uses: ./.github/actions/os-info

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 'stable'

- name: Prepare dependencies
run: go mod download

- name: Test
id: run-tests
run: |
go test ./...

lint:
name: Lint code
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 'stable'

- name: Test
id: run-tests
run: make lint
52 changes: 52 additions & 0 deletions .github/workflows/debug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Debug with SSH Access

on:
workflow_dispatch:
inputs:
os:
description: 'Operating System'
required: true
default: 'Ubuntu LTS (amd64)'
type: choice
options:
- 'Ubuntu LTS (amd64)'
- 'Ubuntu LTS (arm64)'
- 'macOS Latest (arm64)'
- 'macOS 13 (amd64)'
- 'Windows Latest (amd64)'
- 'Windows Latest (arm64)'

jobs:
debug:
name: Debug Environment
runs-on: >-
${{
{
'Ubuntu LTS (amd64)': 'ubuntu-latest',
'Ubuntu LTS (arm64)': 'ubuntu-24.04-arm',
'macOS Latest (arm64)': 'macos-latest',
'macOS 13 (amd64)': 'macos-13',
'Windows Latest (amd64)': 'windows-latest'
'Windows Latest (arm64)': 'windows-11-arm'
}[github.event.inputs.os]
}}

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 'stable'

- name: Install dependencies
run: |
go mod download
go install github.com/go-delve/delve/cmd/dlv@latest

- name: Setup debug session
uses: mxschmitt/action-tmate@v3
with:
limit-access-to-actor: true
timeout-minutes: 30
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ deps:
.PHONY: test
test:
$(info Running tests...)
go test ./...
go test -short ./...

# Build launchr
.PHONY: build
Expand Down
File renamed without changes.
12 changes: 12 additions & 0 deletions docs/test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Application test

[//]: # (TODO: lint)
[//]: # (TODO: go test unit)
[//]: # (TODO: testscript in go)
[//]: # (TODO: testscript separaterly)
[//]: # (TODO: Reusing GitHub workflow)
[//]: # (TODO: Local tests of other OS
Linux: win/macos - docker container dockur/windows and dockur/macos. lima for other linux distro.
MacOS: win - UTM free, Parallels paid. Linux - lima.
Windows: WSL2 for linux + dockur/macos for macos.
)
2 changes: 1 addition & 1 deletion gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (app *appImpl) gen() error {
// Set absolute paths.
config.WorkDir = launchr.MustAbs(config.WorkDir)
config.BuildDir = launchr.MustAbs(config.BuildDir)
// Change working directory to the selected.
// Change the working directory to the selected.
err = os.Chdir(config.WorkDir)
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/moby/sys/signal v0.7.1
github.com/moby/term v0.5.2
github.com/pterm/pterm v0.12.80
github.com/rogpeppe/go-internal v1.14.1
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
Expand Down Expand Up @@ -70,6 +71,7 @@ require (
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/term v0.29.0 // indirect
golang.org/x/time v0.7.0 // indirect
golang.org/x/tools v0.26.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect
gotest.tools/v3 v3.5.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
Expand Down Expand Up @@ -523,6 +525,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
35 changes: 34 additions & 1 deletion internal/launchr/filepath.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
osuser "os/user"
"path/filepath"
"reflect"
"strings"
)

// MustAbs returns absolute filepath and panics on error.
Expand Down Expand Up @@ -62,7 +63,20 @@ func EnsurePath(parts ...string) error {

// IsHiddenPath checks if a path is hidden path.
func IsHiddenPath(path string) bool {
return isHiddenPath(path)
return isDotPath(path) || isHiddenPath(path)
}

func isDotPath(path string) bool {
if path == "." {
return false
}
dirs := strings.Split(filepath.ToSlash(path), "/")
for _, v := range dirs {
if v[0] == '.' {
return true
}
}
return false
}

// IsSystemPath checks if a path is a system path.
Expand Down Expand Up @@ -157,6 +171,16 @@ func MkdirTemp(pattern string) (string, error) {
if dirPath == "" {
return "", fmt.Errorf("failed to create temp directory")
}
return dirPath, nil
}

// MkdirTempWithCleanup creates a temporary directory with MkdirTemp.
// The temp directory is removed when the app terminates.
func MkdirTempWithCleanup(pattern string) (string, error) {
dirPath, err := MkdirTemp(pattern)
if err != nil {
return "", err
}

// Make sure the dir is cleaned on finish.
RegisterCleanupFn(func() error {
Expand All @@ -165,3 +189,12 @@ func MkdirTemp(pattern string) (string, error) {

return dirPath, nil
}

// EscapePathString escapes characters that may be
// incorrectly treated as a string like backshash "\" in a Windows path.
func EscapePathString(s string) string {
if filepath.Separator == '/' {
return s
}
return strings.Replace(s, "\\", "\\\\", -1)
}
2 changes: 1 addition & 1 deletion internal/launchr/filepath_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

func TestMkdirTemp(t *testing.T) {
t.Parallel()
dir, err := MkdirTemp("test")
dir, err := MkdirTempWithCleanup("test")
require.NoError(t, err)
require.NotEmpty(t, dir)
stat, err := os.Stat(dir)
Expand Down
13 changes: 1 addition & 12 deletions internal/launchr/filepath_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package launchr

import (
"path/filepath"
"strings"
)

var skipRootDirs = []string{
Expand Down Expand Up @@ -46,17 +45,7 @@ var skipUserDirs = []string{
}

func isHiddenPath(path string) bool {
if path == "." {
return false
}
dirs := strings.Split(path, string(filepath.Separator))
for _, v := range dirs {
if v[0] == '.' {
return true
}
}

return false
return isDotPath(path)
}

func isRootPath(path string) bool {
Expand Down
2 changes: 1 addition & 1 deletion internal/launchr/lockedfile_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (f *LockedFile) unlock() {
ol := new(windows.Overlapped)
err := windows.UnlockFileEx(windows.Handle(f.file.Fd()), 0, allBytes, allBytes, ol)
if err != nil {
Log().Warn("unlock is called on a not locked file: %s", err)
Log().Warn("unlock is called on a not locked file", "err", err)
}
f.locked = false
}
1 change: 1 addition & 0 deletions internal/launchr/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ type AppVersion struct {
CoreVersion string
CoreReplace string
Plugins []string
PluginsRepl []string
}

// PluginInfo provides information about the plugin and is used as a unique data to identify a plugin.
Expand Down
Loading