~nromdotcom/gemif

4c94d45e7720019d36b86b3b4b7ee1ead26f6669 — Norm MacLennan 11 months ago 2d33af0
Minor refactor in gemifc
2 files changed, 119 insertions(+), 107 deletions(-)

A cmd/gemifc/filemanager.go
M cmd/gemifc/main.go
A cmd/gemifc/filemanager.go => cmd/gemifc/filemanager.go +111 -0
@@ 0,0 1,111 @@
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"

	"git.sr.ht/~nromdotcom/gemif/pkg/gamemanager"
	"gopkg.in/yaml.v2"
)

func readFile(path string) (string, error) {
	contents, err := ioutil.ReadFile(path)
	if err != nil {
		return "", fmt.Errorf("couldn't read file: %w", err)
	}

	return string(contents), nil
}

func findFilesWithExtension(root, pattern string) ([]string, error) {
	var matches []string

	err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return fmt.Errorf("couldn't load directory %s: %w", root, err)
		}

		if info.IsDir() {
			return nil
		}

		if matched, err := filepath.Match(pattern, filepath.Base(path)); err != nil {
			return fmt.Errorf("couldn't check name of file %s: %w", path, err)
		} else if matched {
			matches = append(matches, path)
		}

		return nil
	})
	if err != nil {
		return nil, fmt.Errorf("problem walking directory: %w", err)
	}

	return matches, nil
}

func processFile(path string) ([]gamemanager.Room, error) {
	roomParser := newRoomParser()
	fileRooms := []gamemanager.Room{}

	thisFile, err := readFile(path)
	if err != nil {
		return fileRooms, fmt.Errorf("couldn't read .gemif file: %w", err)
	}

	sceneSeparator := regexp.MustCompile("(?m)^---")
	for _, room := range sceneSeparator.Split(thisFile, -1) {
		if room == "" {
			continue
		}

		currentRoom, err := roomParser.findRoomInfo(room)
		if err != nil {
			log.Fatal(err)
		}

		currentRoom.Exits, err = roomParser.processExits(room)
		if err != nil {
			log.Fatal(err)
		}

		currentRoom.Description = roomParser.getRoomDescription(room)
		fileRooms = append(fileRooms, currentRoom)
		currentRoom = gamemanager.Room{}
	}

	return fileRooms, nil
}

func writeStory(story *gamemanager.Story, file string) error {
	storyOut, err := yaml.Marshal(story)
	if err != nil {
		return fmt.Errorf("couldn't serialize story: %w", err)
	}

	err = ioutil.WriteFile(file, storyOut, 0644) // #nosec G306
	if err != nil {
		return fmt.Errorf("couldn't write compiled output: %w", err)
	}

	return nil
}

func loadMetadata(path string) (*gamemanager.StoryMetadata, error) {
	var metadata *gamemanager.StoryMetadata

	fileContents, err := readFile(fmt.Sprintf("%s/metadata.yml", path))
	if err != nil {
		return metadata, fmt.Errorf("couldn't read metadata file: %w", err)
	}

	if err := yaml.Unmarshal([]byte(fileContents), &metadata); err != nil {
		return metadata, fmt.Errorf("malformed metadata.yml: %w", err)
	}

	return metadata, nil
}

M cmd/gemifc/main.go => cmd/gemifc/main.go +8 -107
@@ 5,142 5,43 @@ package main
import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"regexp"

	"git.sr.ht/~nromdotcom/gemif/pkg/gamemanager"
	"gopkg.in/yaml.v2"
)

//nolint:gochecknoglobals
var (
	appName    string = "GemIF"
	appName    string = "GemIFC"
	appVersion string = "0.0.0"
	appCommit  string = "local"
	buildTime  string = "just now!"
)

func readFile(path string) (string, error) {
	contents, err := ioutil.ReadFile(path)
	if err != nil {
		return "", fmt.Errorf("couldn't read file: %w", err)
	}

	return string(contents), nil
}

func findFilesWithExtension(root, pattern string) ([]string, error) {
	var matches []string

	err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return fmt.Errorf("couldn't load directory %s: %w", root, err)
		}

		if info.IsDir() {
			return nil
		}

		if matched, err := filepath.Match(pattern, filepath.Base(path)); err != nil {
			return fmt.Errorf("couldn't check name of file %s: %w", path, err)
		} else if matched {
			matches = append(matches, path)
		}

		return nil
	})
	if err != nil {
		return nil, fmt.Errorf("problem walking directory: %w", err)
	}

	return matches, nil
}

func processFile(path string) ([]gamemanager.Room, error) {
	roomParser := newRoomParser()
	fileRooms := []gamemanager.Room{}

	thisFile, err := readFile(path)
	if err != nil {
		return fileRooms, fmt.Errorf("couldn't read .gemif file: %w", err)
	}

	sceneSeparator := regexp.MustCompile("(?m)^---")
	for _, room := range sceneSeparator.Split(thisFile, -1) {
		if room == "" {
			continue
		}

		currentRoom, err := roomParser.findRoomInfo(room)
		if err != nil {
			log.Fatal(err)
		}

		currentRoom.Exits, err = roomParser.processExits(room)
		if err != nil {
			log.Fatal(err)
		}

		currentRoom.Description = roomParser.getRoomDescription(room)
		fileRooms = append(fileRooms, currentRoom)
		currentRoom = gamemanager.Room{}
	}

	return fileRooms, nil
}

func writeStory(story *gamemanager.Story, file string) error {
	storyOut, err := yaml.Marshal(story)
	if err != nil {
		return fmt.Errorf("couldn't serialize story: %w", err)
	}

	err = ioutil.WriteFile(file, storyOut, 0644) // #nosec G306
	if err != nil {
		return fmt.Errorf("couldn't write compiled output: %w", err)
	}

	return nil
}

// Temporarily ignore this function's length while we work on
// refactoring some stuff.
//nolint:funlen
func main() {
	var inputPath string

	var outputPath string

	versionFlag := flag.Bool("version", false, "Print version information and exit")
	flag.StringVar(&inputPath, "in", "", "The path of the story source directory")
	flag.StringVar(&outputPath, "out", "", "The path to write the compile story")
	inputPath := flag.String("in", "", "The path of the story source directory")
	outputPath := flag.String("out", "", "The path to write the compile story")
	flag.Parse()

	if *versionFlag {
		fmt.Printf("%s %s (%s) - built %s\n\n", appName, appVersion, appCommit, buildTime)
		os.Exit(0)
	} else if inputPath == "" || outputPath == "" {
	} else if *inputPath == "" || *outputPath == "" {
		fmt.Printf("%v, %v\n\n", inputPath, outputPath)
		flag.PrintDefaults()
		os.Exit(1)
	}

	fmt.Printf("Compiling story %s to %s\n", inputPath, outputPath)
	fmt.Printf("Compiling story %s to %s\n", *inputPath, *outputPath)

	fileContents, err := readFile(fmt.Sprintf("%s/metadata.yml", inputPath))
	metadata, err := loadMetadata(*inputPath)
	if err != nil {
		log.Fatalf("Couldn't read metadata file: %s", err)
	}

	var metadata *gamemanager.StoryMetadata
	if err := yaml.Unmarshal([]byte(fileContents), &metadata); err != nil {
		log.Fatalf("Malformed metadata.yml: %s", err)
	}

	files, err := findFilesWithExtension(inputPath, "*.gemif")
	files, err := findFilesWithExtension(*inputPath, "*.gemif")
	if err != nil {
		log.Fatalf("Couldn't load *.gemif files %s", err)
	}


@@ 172,7 73,7 @@ Finished loading story:

	fmt.Println("Serializing and writing to disk...")

	if err := writeStory(&story, fmt.Sprintf("%s/%s.yml", outputPath, story.Metadata.ID)); err != nil {
	if err := writeStory(&story, fmt.Sprintf("%s/%s.yml", *outputPath, story.Metadata.ID)); err != nil {
		log.Fatalf("Couldn't save story: %s", err)
	}