Skip to content

Commit

Permalink
Printing saved files info
Browse files Browse the repository at this point in the history
  • Loading branch information
roblaszczak committed Jan 16, 2022
1 parent 78bcbdb commit 332ce71
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 38 deletions.
35 changes: 29 additions & 6 deletions trainings/files/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/hexops/gotextdiff"
"github.com/hexops/gotextdiff/myers"
Expand All @@ -24,41 +25,63 @@ func (i InvalidFilePathError) Error() string {
return fmt.Sprintf("invalid file.Path '%s'", i.pathValue)
}

type savedFile struct {
Name string
Lines int
}

func (f Files) WriteExerciseFiles(filesToCreate []*genproto.File, trainingRootFs afero.Fs, exerciseDir string) error {
if !f.dirOrFileExists(trainingRootFs, exerciseDir) {
if err := trainingRootFs.MkdirAll(exerciseDir, 0755); err != nil {
return errors.Wrapf(err, "can't create %s", exerciseDir)
}
}

for _, file := range filesToCreate {
var savedFiles []savedFile

for _, fileFromServer := range filesToCreate {
// We should never trust the remote server.
// Writing files based on external name is a vector for Path Traversal attack.
// For more info please check: https://owasp.org/www-community/attacks/Path_Traversal
//
// To avoid that we are using afero.BasePathFs with base on training root.
fullFilePath := filepath.Join(exerciseDir, file.Path)
fullFilePath := filepath.Join(exerciseDir, fileFromServer.Path)

shouldWrite, err := f.shouldWriteFile(trainingRootFs, fullFilePath, file)
shouldWrite, err := f.shouldWriteFile(trainingRootFs, fullFilePath, fileFromServer)
if err != nil {
return err
}
if !shouldWrite {
continue
}

f, err := trainingRootFs.Create(fullFilePath)
file, err := trainingRootFs.Create(fullFilePath)
if err != nil {
return errors.Wrapf(err, "can't create %s", fullFilePath)
}

if _, err := f.WriteString(file.Content); err != nil {
if _, err := file.WriteString(fileFromServer.Content); err != nil {
return errors.Wrapf(err, "can't write to %s", fullFilePath)
}

if err := f.Close(); err != nil {
if err := file.Close(); err != nil {
return errors.Wrapf(err, "can't close %s", fullFilePath)
}

linesAdded := len(strings.Split(fileFromServer.Content, "\n"))

savedFiles = append(savedFiles, savedFile{
Name: fullFilePath,
Lines: linesAdded,
})
}

for _, file := range savedFiles {
fmt.Fprintf(f.stdout, "+ %s (%d lines)\n", file.Name, file.Lines)
}

if len(savedFiles) > 0 {
fmt.Fprintf(f.stdout, "%d files saved\n\n", len(savedFiles))
}

return nil
Expand Down
10 changes: 5 additions & 5 deletions trainings/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,17 @@ func (h *Handlers) Init(ctx context.Context, trainingName string) error {
var ErrInterrupted = errors.New("interrupted")

func (h *Handlers) startTraining(ctx context.Context, trainingName string, trainingRoot string) error {
if err := h.showTrainingStartPrompt(); err != nil {
return err
}

alreadyExistingTrainingRoot, err := h.config.FindTrainingRoot(trainingRoot)
if err == nil {
fmt.Println(color.BlueString("Training was already started. Training root:" + alreadyExistingTrainingRoot))
fmt.Println(color.BlueString("Training was already initialised. Training root:" + alreadyExistingTrainingRoot))
trainingRoot = alreadyExistingTrainingRoot
} else if !errors.Is(err, config.TrainingRootNotFoundError) {
return errors.Wrap(err, "can't check if training root exists")
} else {
if err := h.showTrainingStartPrompt(); err != nil {
return err
}

logrus.Debug("No training root yet")
}

Expand Down
29 changes: 2 additions & 27 deletions trainings/next.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package trainings
import (
"context"
"fmt"
"os"
"path/filepath"

"github.com/fatih/color"
"github.com/pkg/errors"
Expand All @@ -18,7 +16,6 @@ import (
"github.com/ThreeDotsLabs/cli/internal"
"github.com/ThreeDotsLabs/cli/trainings/config"
"github.com/ThreeDotsLabs/cli/trainings/genproto"
"github.com/ThreeDotsLabs/cli/trainings/web"
)

func (h *Handlers) nextExercise(ctx context.Context, currentExerciseID string, dir string) error {
Expand Down Expand Up @@ -47,7 +44,7 @@ func (h *Handlers) nextExercise(ctx context.Context, currentExerciseID string, d
return err
}

return h.showExerciseTips(trainingRoot, resp.Dir)
return h.showExerciseTips()
}

func (h *Handlers) getNextExercise(ctx context.Context, currentExerciseID string, trainingRootFs afero.Fs) (finished bool, resp *genproto.NextExerciseResponse, err error) {
Expand Down Expand Up @@ -81,30 +78,8 @@ func (h *Handlers) writeExerciseFiles(resp *genproto.NextExerciseResponse, train
)
}

func (h *Handlers) showExerciseTips(trainingRoot string, exerciseDir string) error {
exerciseAbsDir := filepath.Join(trainingRoot, exerciseDir)

pwd, err := os.Getwd()
if err != nil {
return errors.Wrap(err, "can't get working directory")
}
cdRequired := pwd != exerciseAbsDir

relExpectedDir, err := filepath.Rel(pwd, exerciseAbsDir)
if err != nil {
return errors.Wrapf(err, "can't generate rel path for %s and %s", pwd, exerciseAbsDir)
}

if cdRequired {
fmt.Printf("Exercise files were created in '%s' directory.\n", relExpectedDir)
fmt.Println("Please execute", internal.SprintCommand("cd "+relExpectedDir), "to get there.")
}

fmt.Printf("\nPlase go to %s see exercise content.\n", web.Website)
func (h *Handlers) showExerciseTips() error {
fmt.Printf("To run solution, please execute " + internal.SprintCommand("tdl training run"))
if cdRequired {
fmt.Print(" in ", relExpectedDir)
}
fmt.Println()

return nil
Expand Down

0 comments on commit 332ce71

Please sign in to comment.