Skip to content

Commit

Permalink
Convert input paths to relative format
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhuGongpu committed Jul 7, 2020
1 parent d5d6d78 commit 8a5ab44
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 68 deletions.
56 changes: 18 additions & 38 deletions internal/cmdexport/cmdexport.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ package cmdexport
import (
"fmt"
"os"
"path"
"strings"

"github.com/GoogleContainerTools/kpt/internal/cmdexport/orchestrators"
"github.com/GoogleContainerTools/kpt/internal/cmdexport/types"
Expand Down Expand Up @@ -63,7 +61,8 @@ func GetExportRunner() *ExportRunner {

return nil
},
RunE: r.runE,
PreRunE: r.preRunE,
RunE: r.runE,
}

c.Flags().StringSliceVar(
Expand All @@ -87,12 +86,24 @@ type ExportRunner struct {
Pipeline orchestrators.Pipeline
}

// runE generates the pipeline and writes it into a file or stdout.
func (r *ExportRunner) runE(c *cobra.Command, args []string) error {
if err := r.checkFnPaths(); err != nil {
return err
func (r *ExportRunner) preRunE(cmd *cobra.Command, args []string) (err error) {
r.CWD, err = os.Getwd()
if err != nil {
return
}

err = r.CheckFnPaths()
if err != nil {
return
}

err = r.PipelineConfig.UseRelativePaths()

return
}

// runE generates the pipeline and writes it into a file or stdout.
func (r *ExportRunner) runE(c *cobra.Command, args []string) error {
pipeline, e := r.Pipeline.Init(r.PipelineConfig).Generate()

if e != nil {
Expand All @@ -114,34 +125,3 @@ func (r *ExportRunner) runE(c *cobra.Command, args []string) error {
return err
}

// checkPaths checks if fnPaths exist within the current directory.
func (r *ExportRunner) checkFnPaths() error {
cwd, err := os.Getwd()
if err != nil {
return err
}
cwd = fmt.Sprintf("%s%s", cwd, string(os.PathSeparator))

for _, fnPath := range r.FnPaths {
p := fnPath
if !path.IsAbs(p) {
p = path.Join(cwd, p)
}

if !strings.HasPrefix(p, cwd) {
return fmt.Errorf(
"function path (%s) is not within the current working directory",
fnPath,
)
}

if _, err := os.Stat(p); os.IsNotExist(err) {
return fmt.Errorf(
`function path (%s) does not exist`,
fnPath,
)
}
}

return nil
}
60 changes: 51 additions & 9 deletions internal/cmdexport/cmdexport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,35 +133,72 @@ steps:
- run
- .
- --fn-path
- functions/
- functions
`,
},
{
description: "fails to export a Cloud Build pipeline with non-exist function path",
description: "fails to export a Cloud Build pipeline with outside function paths",
params: []string{
"cloud-build",
".",
"--fn-path",
"functions.yaml",
"../functions/functions.yaml",
"--fn-path",
"../functions/functions2.yaml",
"--output",
"cloudbuild.yaml",
},
err: "function path (functions.yaml) does not exist",
err: `
function paths are not within the current working directory:
../functions/functions.yaml
../functions/functions2.yaml`,
},
{
description: "fails to export a Cloud Build pipeline with outside function path",
description: "converts input paths into relative format",
files: map[string]string{
"functions/function.yaml": "",
},
params: []string{
"cloud-build",
".",
// NOTE: `{DIR}` is a macro variable and will be replaced with cwd before test cases are executed.
"{DIR}",
"--fn-path",
"../functions/functions.yaml",
"{DIR}/functions/",
"--output",
"cloudbuild.yaml",
},
err: "function path (../functions/functions.yaml) is not within the current working directory",
expected: `
steps:
- name: gongpu/kpt:latest
args:
- fn
- run
- .
- --fn-path
- functions
`,
},
}

// ReplaceDIRMacro replaces all `{DIR}` macros in params with cwd.
func (t *TestCase) ReplaceDIRMacro() error {
cwd, err := os.Getwd()
if err != nil {
return err
}

var params []string
for _, param := range t.params {
param = strings.Replace(param, "{DIR}", cwd, -1)

params = append(params, param)
}

t.params = params

return nil
}

func setupTempDir(files files) (dir string, err error) {
tempDir, err := ioutil.TempDir("", "kpt-fn-export-test")
if err != nil {
Expand Down Expand Up @@ -200,7 +237,11 @@ func TestCmdExport(t *testing.T) {
err = os.Chdir(tempDir)
assert.NilError(t, err)

err = testCase.ReplaceDIRMacro()
assert.NilError(t, err)

t.Run(testCase.description, func(t *testing.T) {

r := GetExportRunner()
r.Command.SetArgs(testCase.params)

Expand All @@ -211,7 +252,8 @@ func TestCmdExport(t *testing.T) {
err := r.Command.Execute()

if testCase.err != "" {
assert.Error(t, err, testCase.err)
expectedError := strings.TrimLeft(testCase.err, "\n")
assert.Error(t, err, expectedError)
} else {
assert.NilError(t, err)

Expand Down
21 changes: 0 additions & 21 deletions internal/cmdexport/types/PipelineConfig.go

This file was deleted.

83 changes: 83 additions & 0 deletions internal/cmdexport/types/pipelineconfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
"fmt"
"path"
"strings"

"github.com/GoogleContainerTools/kpt/internal/util/pathutil"
)

// PipelineConfig describes configuration of a pipeline.
type PipelineConfig struct {
Dir string
FnPaths []string
// Current working directory.
CWD string
}

// UseRelativePaths converts all paths to relative paths to the current working directory.
func (config *PipelineConfig) UseRelativePaths() (err error) {
config.Dir, err = pathutil.Rel(config.CWD, config.Dir, config.CWD)
if err != nil {
return err
}

var relativeFnPaths []string
for _, fnPath := range config.FnPaths {
fnPath, err = pathutil.Rel(config.CWD, fnPath, config.CWD)
if err != nil {
return err
}

relativeFnPaths = append(relativeFnPaths, fnPath)
}
config.FnPaths = relativeFnPaths

return nil
}

// checkPaths checks if fnPaths are within the current directory.
func (config *PipelineConfig) CheckFnPaths() (err error) {
var invalidPaths []string

for _, fnPath := range config.FnPaths {
// fnPath might be outside cwd here, e.g. `../functions`
absoluteFnPath := fnPath
if !path.IsAbs(fnPath) {
absoluteFnPath = path.Join(config.CWD, fnPath)
}

within, err := pathutil.IsInsideDir(absoluteFnPath, config.CWD)
if err != nil {
return err
}
if !within {
invalidPaths = append(invalidPaths, fnPath)
}
}

if len(invalidPaths) > 0 {

err = fmt.Errorf(
"function paths are not within the current working directory:\n%s",
strings.Join(invalidPaths, "\n"),
)
}

return
}

0 comments on commit 8a5ab44

Please sign in to comment.