Compare commits
4 Commits
b05ae25809
...
dc6485cf6b
Author | SHA1 | Date | |
---|---|---|---|
|
dc6485cf6b | ||
|
b8389eceb0 | ||
|
f2b9e9af75 | ||
|
8eca4b0e27 |
4
.github/workflows/ci-build.yml
vendored
4
.github/workflows/ci-build.yml
vendored
@ -54,6 +54,10 @@ jobs:
|
||||
env:
|
||||
DOCKER_API_VERSION: "1.45"
|
||||
run: mise run test_integration_ci
|
||||
- name: upload coverage report
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
release:
|
||||
needs:
|
||||
- lint
|
||||
|
@ -26,6 +26,23 @@ archives:
|
||||
- goos: windows
|
||||
formats: [zip]
|
||||
|
||||
brews:
|
||||
- name: octoplex
|
||||
description: "Octoplex is a live video restreamer for the terminal."
|
||||
homepage: "https://github.com/rfwatson/octoplex"
|
||||
repository:
|
||||
owner: rfwatson
|
||||
name: homebrew-octoplex
|
||||
install: |
|
||||
bin.install "octoplex"
|
||||
test: |
|
||||
system "#{bin}/octoplex -h"
|
||||
|
||||
release:
|
||||
github:
|
||||
owner: rfwatson
|
||||
name: octoplex
|
||||
|
||||
changelog:
|
||||
use: github
|
||||
filters:
|
||||
|
13
README.md
13
README.md
@ -46,7 +46,18 @@ MacOS: https://docs.docker.com/desktop/setup/install/mac-install/
|
||||
|
||||
### Octoplex
|
||||
|
||||
Download the latest build for your platform from the [releases page](https://github.com/rfwatson/octoplex/releases).
|
||||
#### Homebrew
|
||||
|
||||
Octoplex can be installed using Homebrew on MacOS or Linux.
|
||||
|
||||
```
|
||||
$ brew tap rfwatson/octoplex
|
||||
$ brew install octoplex
|
||||
```
|
||||
|
||||
#### From Github
|
||||
|
||||
Alternatively, grab the latest build for your platform from the [releases page](https://github.com/rfwatson/octoplex/releases).
|
||||
|
||||
Unarchive the `octoplex` binary and copy it somewhere in your $PATH.
|
||||
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"git.netflux.io/rob/octoplex/internal/mediaserver"
|
||||
"git.netflux.io/rob/octoplex/internal/replicator"
|
||||
"git.netflux.io/rob/octoplex/internal/terminal"
|
||||
"github.com/docker/docker/client"
|
||||
)
|
||||
|
||||
// RunParams holds the parameters for running the application.
|
||||
@ -69,7 +70,15 @@ func Run(ctx context.Context, params RunParams) error {
|
||||
containerClient, err := container.NewClient(ctx, params.DockerClient, logger.With("component", "container_client"))
|
||||
if err != nil {
|
||||
err = fmt.Errorf("create container client: %w", err)
|
||||
ui.ShowFatalErrorModal(err)
|
||||
|
||||
var errString string
|
||||
if client.IsErrConnectionFailed(err) {
|
||||
errString = "Could not connect to Docker. Is Docker installed and running?"
|
||||
} else {
|
||||
errString = err.Error()
|
||||
}
|
||||
ui.ShowFatalErrorModal(errString)
|
||||
|
||||
emptyUI()
|
||||
<-ui.C()
|
||||
return err
|
||||
@ -86,7 +95,7 @@ func Run(ctx context.Context, params RunParams) error {
|
||||
})
|
||||
if err != nil {
|
||||
err = fmt.Errorf("create mediaserver: %w", err)
|
||||
ui.ShowFatalErrorModal(err)
|
||||
ui.ShowFatalErrorModal(err.Error())
|
||||
emptyUI()
|
||||
<-ui.C()
|
||||
return err
|
||||
|
@ -791,3 +791,42 @@ func TestIntegrationDockerClientError(t *testing.T) {
|
||||
|
||||
<-done
|
||||
}
|
||||
func TestIntegrationDockerConnectionError(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(t.Context(), 10*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
logger := testhelpers.NewTestLogger(t).With("component", "integration")
|
||||
dockerClient, err := dockerclient.NewClientWithOpts(dockerclient.WithHost("http://docker.example.com"))
|
||||
require.NoError(t, err)
|
||||
|
||||
configService := setupConfigService(t, config.Config{Sources: config.Sources{RTMP: config.RTMPSource{Enabled: true}}})
|
||||
screen, screenCaptureC, getContents := setupSimulationScreen(t)
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer func() {
|
||||
done <- struct{}{}
|
||||
}()
|
||||
|
||||
err := app.Run(ctx, buildAppParams(t, configService, dockerClient, screen, screenCaptureC, logger))
|
||||
require.ErrorContains(t, err, "dial tcp: lookup docker.example.com")
|
||||
require.ErrorContains(t, err, "no such host")
|
||||
}()
|
||||
|
||||
require.EventuallyWithT(
|
||||
t,
|
||||
func(t *assert.CollectT) {
|
||||
assert.True(t, contentsIncludes(getContents(), "An error occurred:"), "expected to see error message")
|
||||
assert.True(t, contentsIncludes(getContents(), "Could not connect to Docker. Is Docker installed"), "expected to see message")
|
||||
},
|
||||
5*time.Second,
|
||||
time.Second,
|
||||
"expected to see fatal error modal",
|
||||
)
|
||||
printScreen(t, getContents, "Ater displaying the fatal error modal")
|
||||
|
||||
// Quit the app, this should cause the done channel to receive.
|
||||
sendKey(t, screen, tcell.KeyEnter, ' ')
|
||||
|
||||
<-done
|
||||
}
|
||||
|
@ -386,13 +386,13 @@ func (ui *UI) ShowDestinationErrorModal(name string, err error) {
|
||||
|
||||
// ShowFatalErrorModal displays the provided error. It sends a CommandQuit to the
|
||||
// command channel when the user selects the Quit button.
|
||||
func (ui *UI) ShowFatalErrorModal(err error) {
|
||||
func (ui *UI) ShowFatalErrorModal(errString string) {
|
||||
ui.app.QueueUpdateDraw(func() {
|
||||
ui.showModal(
|
||||
pageNameModalFatalError,
|
||||
fmt.Sprintf(
|
||||
"An error occurred:\n\n%s",
|
||||
err,
|
||||
errString,
|
||||
),
|
||||
[]string{"Quit"},
|
||||
false,
|
||||
|
@ -16,7 +16,7 @@ alias = "ti"
|
||||
[tasks.test_ci]
|
||||
description = "Run tests in CI"
|
||||
dir = "{{cwd}}"
|
||||
run = "go test -v -count 1 -race ./..."
|
||||
run = "go test -v -count 1 -race -coverprofile=coverage.txt ./..."
|
||||
|
||||
[tasks.test_integration_ci]
|
||||
description = "Run integration tests in CI"
|
||||
|
Loading…
x
Reference in New Issue
Block a user