Skip to content
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

ref(proxy): implement transparent with profile (#80) #81

Merged
merged 1 commit into from
Dec 23, 2023
Merged
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
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"--fast"
],
"cSpell.words": [
"arity",
"beezledub",
"bodyclose",
"chardata",
Expand Down
65 changes: 52 additions & 13 deletions src/app/proxy/controller-sampler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,21 @@ func doMockViper(config *cmocks.MockViperConfig) {
func resetFS(index string, silent bool) (vfs storage.VirtualFS, root string) {
vfs = storage.UseMemFS()
root = helpers.Scientist(vfs, index, silent)
// ??? Expect(matchers.AsDirectory(root)).To(matchers.ExistInFS(vfs))
Expect(matchers.AsDirectory(root)).To(matchers.ExistInFS(vfs))

return vfs, root
}

type controllerTE struct {
given string
should string
args []string
profile string
relative string
expected []string
given string
should string
args []string
profile string
relative string
expected []string
intermediate string
supplement string
inputs []string
}

type samplerTE struct {
Expand Down Expand Up @@ -272,6 +275,20 @@ var _ = Describe("SamplerController", Ordered, func() {
// eventually, we should assert on files created in the virtual
// file system, using entry.expected
//
if entry.inputs != nil {
intermediate := helpers.Path(root, entry.intermediate)
supplement := helpers.Path(intermediate, entry.supplement)

for _, original := range entry.inputs {
originalPath := filepath.Join(supplement, original)
Expect(matchers.AsFile(originalPath)).To(matchers.ExistInFS(vfs))

// We can't assert this until an actual output is created:
// output := helpers.Path(root, entry.intermediate)
// resultPath := filepath.Join(intermediate, output, original)
// Expect(matchers.AsFile(resultPath)).To(matchers.ExistInFS(vfs))
}
}
},
func(entry *samplerTE) string {
return fmt.Sprintf("🧪 ===> given: '%v', should: '%v'",
Expand All @@ -281,22 +298,44 @@ var _ = Describe("SamplerController", Ordered, func() {

Entry(nil, &samplerTE{
controllerTE: controllerTE{
given: "profile",
should: "sample(first) with glob filter using the defined profile",
given: "run transparent adhoc",
should: "sample(first) with glob filter, result file takes place of input",
relative: backyardWorldsPlanet9Scan01,
args: []string{
"--sample",
"--no-files", "4",
"--files-gb", "*Backyard Worlds*",
"--profile", "adaptive",
"--gaussian-blur", "0.51",
"--interlace", "line",
},
expected: backyardWorldsPlanet9Scan01First4,
expected: backyardWorldsPlanet9Scan01First4,
intermediate: "nasa/exo/Backyard Worlds - Planet 9/sessions/scan-01",
supplement: "ADHOC/TRASH",
inputs: backyardWorldsPlanet9Scan01First4,
},
}),

Entry(nil, &samplerTE{
controllerTE: controllerTE{
given: "run transparent with profile",
should: "sample(first) with glob filter, result file takes place of input",
relative: backyardWorldsPlanet9Scan01,
args: []string{
"--sample",
"--no-files", "4",
"--files-gb", "*Backyard Worlds*",
"--profile", "adaptive",
"--gaussian-blur", "0.51",
"--interlace", "line",
},
expected: backyardWorldsPlanet9Scan01First4,
intermediate: "nasa/exo/Backyard Worlds - Planet 9/sessions/scan-01",
supplement: "adaptive/TRASH",
inputs: backyardWorldsPlanet9Scan01First4,
},
}),

XEntry(nil, &samplerTE{
controllerTE: controllerTE{
given: "profile",
should: "sample(last) with glob filter using the defined profile",
Expand All @@ -312,7 +351,7 @@ var _ = Describe("SamplerController", Ordered, func() {
},
}),

Entry(nil, &samplerTE{
XEntry(nil, &samplerTE{
controllerTE: controllerTE{
given: "profile without no-files in args",
should: "sample(first) with glob filter, using no-files from config",
Expand Down Expand Up @@ -344,7 +383,7 @@ var _ = Describe("SamplerController", Ordered, func() {

// ===

Entry(nil, &samplerTE{
XEntry(nil, &samplerTE{
controllerTE: controllerTE{
given: "scheme",
should: "sample all profiles in the scheme",
Expand Down
13 changes: 9 additions & 4 deletions src/app/proxy/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

type controller struct {
shared *SharedControllerInfo
local localControllerInfo
}

func (c *controller) profileSequence(
Expand Down Expand Up @@ -94,8 +95,11 @@ func (c *controller) Run(item *nav.TraverseItem, sequence Sequence) error {
)

iterator := collections.ForwardRunIt[Step, error](sequence, zero)
each := func(s Step) error {
return s.Run(c.shared)
each := func(step Step) error {
return step.Run(&RunStepInfo{
Item: item,
Source: c.local.destination,
})
}
while := func(_ Step, err error) bool {
if resultErr == nil {
Expand All @@ -115,8 +119,8 @@ func (c *controller) Run(item *nav.TraverseItem, sequence Sequence) error {
// Perhaps we have an error policy including one that implements
// a retry.
//
if err := c.shared.fileManager.Setup(item); err != nil {
return err
if c.local.destination, resultErr = c.shared.fileManager.Setup(item); resultErr != nil {
return resultErr
}

iterator.RunAll(each, while)
Expand All @@ -125,4 +129,5 @@ func (c *controller) Run(item *nav.TraverseItem, sequence Sequence) error {
}

func (c *controller) Reset() {
c.local.destination = ""
}
10 changes: 10 additions & 0 deletions src/app/proxy/enter-shrink.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,23 @@ func (e *ShrinkEntry) createFinder() *PathFinder {
output: &inlineOutputStrategy{},
deletion: &inlineDeletionStrategy{},
},
arity: 1,
}

if finder.Scheme != "" {
schemeCFG, _ := e.SamplerCFG.Scheme(finder.Scheme)
finder.arity = len(schemeCFG.Profiles)
}

if e.Inputs.ParamSet.Native.OutputPath != "" {
finder.Output = e.Inputs.ParamSet.Native.OutputPath
finder.behaviours.output = &ejectOutputStrategy{}
} else {
finder.transparentInput = true
}

if e.Inputs.ParamSet.Native.TrashPath != "" {
finder.Trash = e.Inputs.ParamSet.Native.TrashPath
finder.behaviours.deletion = &ejectOutputStrategy{}
}

Expand Down
42 changes: 34 additions & 8 deletions src/app/proxy/execution-step.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
package proxy

import (
"path/filepath"

"github.com/snivilised/cobrass/src/clif"
"github.com/snivilised/extendio/xfs/nav"
)

// Step
type Step interface {
Run(*SharedControllerInfo) error
}
type (
RunStepInfo struct {
Item *nav.TraverseItem
Source string
}

// Sequence
type Sequence []Step
Step interface {
Run(rsi *RunStepInfo) error
}

// Sequence
Sequence []Step
)

// magickStep knows how to combine parameters together so that the program
// can be invoked correctly; but it does not know how to compose the input
Expand All @@ -27,8 +37,24 @@ type magickStep struct {
}

// Run
func (s *magickStep) Run(*SharedControllerInfo) error {
positional := []string{s.sourcePath}
func (s *magickStep) Run(rsi *RunStepInfo) error {
folder, file := s.shared.finder.Result(&resultInfo{
pathInfo: pathInfo{
item: rsi.Item,
origin: rsi.Item.Extension.Parent,
},
scheme: s.scheme,
profile: s.profile,
})
result := filepath.Join(folder, file)
input := []string{rsi.Source}

// if transparent, then we need to ask the fm to move the
// existing file out of the way. But shouldn't that already have happened
// during setup? See, which mean setup in not working properly in
// this scenario.

return s.shared.program.Execute(clif.Expand(positional, s.thirdPartyCL, s.outputPath)...)
return s.shared.program.Execute(
clif.Expand(input, s.thirdPartyCL, result)...,
)
}
52 changes: 35 additions & 17 deletions src/app/proxy/file-manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (
)

const (
beezledub = os.FileMode(0o666)
beezledub = os.FileMode(0o666)
errorDestination = ""
)

// FileManager knows how to translate requests into invocations on the file
Expand All @@ -23,40 +24,57 @@ type FileManager struct {

// Setup prepares for operation by moving existing file out of the way,
// if applicable.
func (fm *FileManager) Setup(item *nav.TraverseItem) error {
func (fm *FileManager) Setup(item *nav.TraverseItem) (destination string, err error) {
if !fm.finder.transparentInput {
// Any result file must not clash with the input file, so the input
// file must stay in place
return item.Path, nil
}

// https://pkg.go.dev/os#Rename LinkError may result
//
// this might not be right. it may be that we want to leave the
// original alone and create other outputs; in this scenario
// we don't want to rename/move the source...
//
from := &destinationInfo{
item: item,
origin: item.Parent.Path,
transparent: true, // might come from a flag
from := &pathInfo{
item: item,
origin: item.Parent.Path,
}

if folder, file := fm.finder.Destination(from); folder != "" {
if err := fm.vfs.MkdirAll(folder, beezledub); err != nil {
return errors.Wrapf(err, "could not create parent setup for '%v'", item.Path)
if err = fm.vfs.MkdirAll(folder, beezledub); err != nil {
return errorDestination, errors.Wrapf(
err, "could not create parent setup for '%v'", item.Path,
)
}

destination := filepath.Join(folder, file)
// THIS DESTINATION IS NOT REPORTED BACK
// TO BE USED AS THE INPUT
destination = filepath.Join(folder, file)

if !fm.vfs.FileExists(item.Path) {
return fmt.Errorf("source file: '%v' does not exist", item.Path)
return errorDestination, fmt.Errorf(
"source file: '%v' does not exist", item.Path,
)
}

if fm.vfs.FileExists(destination) {
return fmt.Errorf("destination file: '%v' already exists", destination)
}

if err := fm.vfs.Rename(item.Path, destination); err != nil {
return errors.Wrapf(err, "could not complete setup for '%v'", item.Path)
if item.Path != destination {
if fm.vfs.FileExists(destination) {
return errorDestination, fmt.Errorf(
"destination file: '%v' already exists", destination,
)
}

if err := fm.vfs.Rename(item.Path, destination); err != nil {
return errorDestination, errors.Wrapf(
err, "could not complete setup for '%v'", item.Path,
)
}
}
}

return nil
return destination, nil
}

func (fm *FileManager) move(from, to string) error {
Expand Down
Loading