Skip to content

Commit 2672b17

Browse files
authored
feat: sftp (#51)
* feat: sftp test: add tests for ftp and sftp * chore: ci fixes * chore: potential race fix * fix: simplify existence checks * fix: split path differently for ftp * fix: 🤷 * chore: add debug print * chore: lint * chore: idk dude * chore: ? * chore: more logs * chore: wipe mods before tests * chore: logs * chore: wat * chore: wait? * chore: no errors * chore: gh actions are 💩 * fix: always sync after copy * chore: remove some test logs * chore: remove test progress watcher * refactor: change progress to writer * chore: logs * chore: different logs * chore: whoops * chore: moar logs * chore: even moar logs * chore: what is life * chore: why are we here * chore: we are just bags of water floating through space * chore: are you real? * chore: ? * chore: if you get a single update now I call bs * chore: ok what if we just do one? * chore: ok what if we do two? * chore: this should not work * chore: wait no, this one * chore: fml * chore: remove logs * chore: what if we just wait a little * chore: retry * chore: move error * chore: verbose log * chore: remove explicit sleep * chore: remove debug * fix: linux pathing on windows * fix: clean paths properly * fix: fuck ftp * fix: send update on vanilla * feat: parallel ftp * fix: remove potential credential leak
1 parent baacde4 commit 2672b17

16 files changed

Lines changed: 675 additions & 196 deletions

File tree

.github/workflows/push.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ jobs:
8282
- name: Install Satisfactory Dedicated Server
8383
run: steamcmd +login anonymous +force_install_dir ${{ github.workspace }}/SatisfactoryDedicatedServer +app_update 1690800 validate +quit
8484

85+
- name: Change directory permissions
86+
if: ${{ matrix.os == 'ubuntu-latest' }}
87+
run: mkdir -p ${{ github.workspace }}/SatisfactoryDedicatedServer/FactoryGame/Mods && chmod -R 777 ${{ github.workspace }}/SatisfactoryDedicatedServer
88+
8589
- name: List directory (linux)
8690
if: ${{ matrix.os == 'ubuntu-latest' }}
8791
run: ls -lR
@@ -90,6 +94,10 @@ jobs:
9094
if: ${{ matrix.os == 'windows-latest' }}
9195
run: tree /F
9296

97+
- name: Boot ftp and sftp
98+
if: ${{ matrix.os == 'ubuntu-latest' }}
99+
run: docker-compose -f docker-compose-test.yml up -d
100+
93101
- name: Download GQL schema
94102
run: "npx graphqurl https://api.ficsit.dev/v2/query --introspect -H 'content-type: application/json' > schema.graphql"
95103

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,5 @@ dist/
128128
/.graphqlconfig
129129
schema.graphql
130130
*.log
131-
.direnv
131+
.direnv
132+
/SatisfactoryDedicatedServer

cfg/test_defaults.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package cfg
22

33
import (
4+
"log/slog"
5+
"os"
46
"path/filepath"
57
"runtime"
68

@@ -18,4 +20,8 @@ func SetDefaults() {
1820
viper.SetDefault("api-base", "https://api.ficsit.dev")
1921
viper.SetDefault("graphql-api", "/v2/query")
2022
viper.SetDefault("concurrent-downloads", 5)
23+
24+
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
25+
Level: slog.LevelDebug,
26+
})))
2127
}

cli/cache/download.go

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ import (
44
"errors"
55
"fmt"
66
"io"
7+
"log/slog"
78
"net/http"
89
"os"
910
"path/filepath"
1011
"sync"
12+
"time"
1113

14+
"github.com/avast/retry-go"
1215
"github.com/puzpuzpuz/xsync/v3"
1316
"github.com/spf13/viper"
1417

@@ -84,7 +87,11 @@ func DownloadOrCache(cacheKey string, hash string, url string, updates chan<- ut
8487
outer:
8588
for {
8689
select {
87-
case update := <-upstreamUpdates:
90+
case update, ok := <-upstreamUpdates:
91+
if !ok {
92+
break outer
93+
}
94+
8895
for _, u := range group.updates {
8996
u <- update
9097
}
@@ -94,11 +101,29 @@ func DownloadOrCache(cacheKey string, hash string, url string, updates chan<- ut
94101
}
95102
}()
96103

97-
size, err := downloadInternal(cacheKey, location, hash, url, upstreamUpdates, downloadSemaphore)
104+
var size int64
105+
106+
err := retry.Do(func() error {
107+
var err error
108+
size, err = downloadInternal(cacheKey, location, hash, url, upstreamUpdates, downloadSemaphore)
109+
if err != nil {
110+
return fmt.Errorf("internal download error: %w", err)
111+
}
112+
return nil
113+
},
114+
retry.Attempts(5),
115+
retry.Delay(time.Second),
116+
retry.DelayType(retry.FixedDelay),
117+
retry.OnRetry(func(n uint, err error) {
118+
if n > 0 {
119+
slog.Info("retrying download", slog.Uint64("n", uint64(n)), slog.String("cacheKey", cacheKey))
120+
}
121+
}),
122+
)
98123
if err != nil {
99124
group.err = err
100125
close(group.wait)
101-
return nil, 0, err
126+
return nil, 0, err // nolint
102127
}
103128

104129
close(upstreamWaiter)
@@ -175,16 +200,17 @@ func downloadInternal(cacheKey string, location string, hash string, url string,
175200
}
176201

177202
progresser := &utils.Progresser{
178-
Reader: resp.Body,
179203
Total: resp.ContentLength,
180204
Updates: updates,
181205
}
182206

183-
_, err = io.Copy(out, progresser)
207+
_, err = io.Copy(io.MultiWriter(out, progresser), resp.Body)
184208
if err != nil {
185209
return 0, fmt.Errorf("failed writing file to disk: %w", err)
186210
}
187211

212+
_ = out.Sync()
213+
188214
if updates != nil {
189215
updates <- utils.GenericProgress{Completed: resp.ContentLength, Total: resp.ContentLength}
190216
}

cli/context.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"fmt"
5+
"log/slog"
56

67
"github.com/Khan/genqlient/graphql"
78
"github.com/spf13/viper"
@@ -87,6 +88,8 @@ func (g *GlobalContext) ReInit() error {
8788

8889
// Wipe will remove any trace of ficsit anywhere
8990
func (g *GlobalContext) Wipe() error {
91+
slog.Info("wiping global context")
92+
9093
// Wipe all installations
9194
for _, installation := range g.Installations.Installations {
9295
if err := installation.Wipe(); err != nil {

0 commit comments

Comments
 (0)