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

theme config migration #132

Merged
merged 8 commits into from
Nov 8, 2022
76 changes: 59 additions & 17 deletions cmd/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"os"
"path"

"github.com/spf13/afero"
"github.com/spf13/cobra"
"github.com/sveltinio/sveltin/internal/markup"
"github.com/sveltinio/sveltin/internal/migrations"
Expand All @@ -23,6 +24,7 @@ import (
const (
ProjectSettingsMigrationID string = "projectSettings"
DefaultsConfigMigrationID string = "defaultsConfig"
ThemeConfigMigrationID string = "themeConfig"
)

//=============================================================================
Expand All @@ -47,16 +49,24 @@ func RunUpgradeCmd(cmd *cobra.Command, args []string) {
cfg.log.Plain(markup.H1(fmt.Sprintf("Upgrading your project to sveltin v%s", CliVersion)))
migrationManager := migrations.NewMigrationManager()

// FILE: <project_root>/sveltin.config.json
pathToProjectSettingsFile := path.Join(cwd, ProjectSettingsFile)
addProjectSettingsMigration := handleMigration(ProjectSettingsMigrationID, migrationManager, pathToProjectSettingsFile)
addProjectSettingsMigration := handleMigration(ProjectSettingsMigrationID, migrationManager, cfg, pathToProjectSettingsFile)
err := addProjectSettingsMigration.Execute()
utils.ExitIfError(err)

// FILE: <project_root>/config/defaults.js.ts
pathToDefaultsConfigFile := path.Join(cwd, cfg.pathMaker.GetConfigFolder(), DefaultsConfigFile)
updateDefaultsConfigMigration := handleMigration(DefaultsConfigMigrationID, migrationManager, pathToDefaultsConfigFile)
updateDefaultsConfigMigration := handleMigration(DefaultsConfigMigrationID, migrationManager, cfg, pathToDefaultsConfigFile)
err = updateDefaultsConfigMigration.Execute()
utils.ExitIfError(err)

// FILE: <project_root>/themes/<theme_name>/theme.config.js
pathToThemeConfigFile := path.Join(cwd, cfg.pathMaker.GetThemesFolder(), retrieveThemeName(cfg), cfg.settings.GetThemeConfigFilename())
updateThemeConfigMigration := handleMigration(ThemeConfigMigrationID, migrationManager, cfg, pathToThemeConfigFile)
err = updateThemeConfigMigration.Execute()
utils.ExitIfError(err)

cfg.log.Success(fmt.Sprintf("Your project is ready for sveltin v%s\n", CliVersion))
}

Expand All @@ -66,43 +76,75 @@ func init() {

//=============================================================================

func handleMigration(migrationType string, migrationManager *migrations.MigrationManager, pathToFile string) migrations.Migration {
func handleMigration(migrationType string, migrationManager *migrations.MigrationManager, config appConfig, pathToFile string) migrations.Migration {
switch migrationType {
case ProjectSettingsMigrationID:
return newAddProjectSettingsMigration(migrationManager, pathToFile)
return newAddProjectSettingsMigration(migrationManager, config, pathToFile)
case DefaultsConfigMigrationID:
return newUpdateDefaultsConfigMigration(migrationManager, pathToFile)
return newUpdateDefaultsConfigMigration(migrationManager, config, pathToFile)
case ThemeConfigMigrationID:
return newUpdateThemeConfigMigration(migrationManager, config, pathToFile)
default:
return nil
}
}

func newAddProjectSettingsMigration(migrationManager *migrations.MigrationManager, pathTofile string) *migrations.AddProjectSettingsMigration {
func newAddProjectSettingsMigration(migrationManager *migrations.MigrationManager, config appConfig, pathTofile string) *migrations.AddProjectSettingsMigration {
return &migrations.AddProjectSettingsMigration{
Mediator: migrationManager,
Fs: cfg.fs,
FsManager: cfg.fsManager,
PathMaker: cfg.pathMaker,
Logger: cfg.log,
Fs: config.fs,
FsManager: config.fsManager,
PathMaker: config.pathMaker,
Logger: config.log,
Data: &migrations.MigrationData{
PathToFile: pathTofile,
CliVersion: CliVersion,
ProjectCliVersion: cfg.projectSettings.CLI.Version,
ProjectCliVersion: config.projectSettings.CLI.Version,
},
}
}

func newUpdateDefaultsConfigMigration(migrationManager *migrations.MigrationManager, pathTofile string) *migrations.UpdateDefaultsConfigMigration {
func newUpdateDefaultsConfigMigration(migrationManager *migrations.MigrationManager, config appConfig, pathTofile string) *migrations.UpdateDefaultsConfigMigration {
return &migrations.UpdateDefaultsConfigMigration{
Mediator: migrationManager,
Fs: cfg.fs,
FsManager: cfg.fsManager,
PathMaker: cfg.pathMaker,
Logger: cfg.log,
Fs: config.fs,
FsManager: config.fsManager,
PathMaker: config.pathMaker,
Logger: config.log,
Data: &migrations.MigrationData{
PathToFile: pathTofile,
CliVersion: CliVersion,
ProjectCliVersion: cfg.projectSettings.CLI.Version,
ProjectCliVersion: config.projectSettings.CLI.Version,
},
}
}

func newUpdateThemeConfigMigration(migrationManager *migrations.MigrationManager, config appConfig, pathTofile string) *migrations.UpdateThemeConfigMigration {
return &migrations.UpdateThemeConfigMigration{
Mediator: migrationManager,
Fs: config.fs,
FsManager: config.fsManager,
PathMaker: config.pathMaker,
Logger: config.log,
Data: &migrations.MigrationData{
PathToFile: pathTofile,
CliVersion: CliVersion,
ProjectCliVersion: config.projectSettings.CLI.Version,
},
}
}

//=============================================================================

func retrieveThemeName(config appConfig) string {
files, err := afero.ReadDir(config.fs, config.pathMaker.GetThemesFolder())
utils.ExitIfError(err)

var themeName string
for _, file := range files {
if file.IsDir() {
themeName = file.Name()
}
}
return themeName
}
4 changes: 2 additions & 2 deletions common/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func DirExists(fs afero.Fs, path string) bool {
func FileExists(fs afero.Fs, path string) (bool, error) {
exists, _ := afero.Exists(fs, path)
if !exists {
return false, sveltinerr.NewFileNotFoundError()
return false, sveltinerr.NewFileNotFoundError(path)
}

isDir, _ := afero.IsDir(fs, path)
Expand Down Expand Up @@ -91,7 +91,7 @@ func MoveFile(efs *embed.FS, fs afero.Fs, sourceFile string, saveTo string, back
func CopyFileFromEmbeddedFS(efs *embed.FS, fs afero.Fs, pathToFile string, saveTo string) error {
content, err := efs.ReadFile(pathToFile)
if err != nil {
return sveltinerr.NewFileNotFoundError()
return sveltinerr.NewFileNotFoundError(pathToFile)
}
pathToSaveFile := filepath.Join(saveTo)
if err := WriteToDisk(fs, pathToSaveFile, bytes.NewReader(content)); err != nil {
Expand Down
7 changes: 6 additions & 1 deletion common/fs_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package common

import (
"fmt"
"path/filepath"
"testing"

Expand Down Expand Up @@ -151,7 +152,11 @@ func TestCopyFileFromEmbeddedFS(t *testing.T) {
err := CopyFileFromEmbeddedFS(&resources.SveltinFS, memFS, tc.pathToFile, tc.saveTo)
re := err.(*sveltinerr.SveltinError)
is.Equal(10, int(re.Code))
is.Equal("please, check the file path", re.Message)
placeholderText := `file not found! Please, check the file path:

%s`
msg := fmt.Sprintf(placeholderText, tc.pathToFile)
is.Equal(msg, re.Message)

}

Expand Down
2 changes: 1 addition & 1 deletion config/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func (c *SveltinSettings) GetAPIFilename() string {
// GetThemesPath returns a string representing the path to the 'themes' folder
// relative to the current working directory.
func (c *SveltinSettings) GetThemesPath() string {
return filepath.Join(c.GetProjectRoot(), c.Paths.Themes)
return c.Paths.Themes
}

// GetThemeConfigFilename returns a string representing the path to the 'themes/theme.config.js'
Expand Down
10 changes: 5 additions & 5 deletions config/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ func TestPaths(t *testing.T) {
want string
}{
{path: settings.GetBuildPath(), want: filepath.Join(pwd, "build")},
{path: settings.GetConfigPath(), want: filepath.Join("config")},
{path: settings.GetContentPath(), want: filepath.Join("content")},
{path: settings.GetStaticPath(), want: filepath.Join("static")},
{path: settings.GetSrcPath(), want: filepath.Join("src")},
{path: settings.GetConfigPath(), want: "config"},
{path: settings.GetContentPath(), want: "content"},
{path: settings.GetStaticPath(), want: "static"},
{path: settings.GetSrcPath(), want: "src"},
{path: settings.GetRoutesPath(), want: filepath.Join("src", "routes")},
{path: settings.GetLibPath(), want: filepath.Join("src", "lib")},
{path: settings.GetParamsPath(), want: filepath.Join("src", "params")},
{path: settings.GetAPIPath(), want: filepath.Join("src", "routes", "api")},
{path: settings.GetThemesPath(), want: filepath.Join(pwd, "themes")},
{path: settings.GetThemesPath(), want: "themes"},
}

for _, tc := range tests {
Expand Down
10 changes: 6 additions & 4 deletions helpers/templates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ func TestExecSveltinTpl(t *testing.T) {
tplConfig := BuildTemplate(pathToTplFile, nil, &data)
retrievedContent := tplConfig.Run(&resources.SveltinFS)

validContent := `// theme.config.js file for your sveltin theme
const config = {
name: 'white',
validContent := `import { theme } from '../../sveltin.config.json';

// theme.config.js file for your sveltin theme
const themeConfig = {
name: theme.name,
version: '0.1',
license: 'MIT',
licenselink: 'https://github.com/yourname/yourtheme/blob/master/LICENSE',
Expand All @@ -73,7 +75,7 @@ const config = {
},
};

export default config
export { themeConfig }
`
is.Equal(validContent, string(retrievedContent))
}
4 changes: 2 additions & 2 deletions internal/errors/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ func NewNotValidGitHubRepoURL(input string) error {
}

// NewFileNotFoundError ...
func NewFileNotFoundError() error {
err := errors.New("please, check the file path")
func NewFileNotFoundError(pathToFile string) error {
err := fmt.Errorf("file not found! Please, check the file path:\n\n%s", pathToFile)
return newSveltinError(fileNotFoundError, "FileNotFoundError", "File Not Found", err.Error(), err)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/errors/wrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestErrors(t *testing.T) {
is.Equal(1, int(re.Code))
is.Equal("DefaultError", re.Name)

errVar = NewFileNotFoundError()
errVar = NewFileNotFoundError("test.example")
re = errVar.(*SveltinError)
is.Equal("FileNotFoundError", re.Name)

Expand Down
29 changes: 16 additions & 13 deletions internal/migrations/defaults-config-migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/sveltinio/sveltin/common"
"github.com/sveltinio/sveltin/internal/fsm"
"github.com/sveltinio/sveltin/internal/pathmaker"
"github.com/sveltinio/sveltin/utils"
"github.com/sveltinio/yinlog"
)

Expand All @@ -44,37 +43,37 @@ func (m UpdateDefaultsConfigMigration) Execute() error {

func (m *UpdateDefaultsConfigMigration) up() error {
if !m.Mediator.canRun(m) {
//m.Logger.Important("DefaultsConfigMigration: awaiting")
return nil
}

exists, err := common.FileExists(m.Fs, m.Data.PathToFile)
utils.ExitIfError(err)
if err != nil {
return err
}

if exists {
// regex for semantic versioning - https://ihateregex.io/expr/semver/
pattern := regexp.MustCompile(`(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?`)

if isMigrationRequired(m, pattern) {
if isDefaultsConfigMigrationRequired(m, pattern) {
m.Logger.Info(fmt.Sprintf("Migrating %s file", filepath.Base(m.Data.PathToFile)))
err := migrateConfigFile(m, pattern)
utils.ExitIfError(err)
if err := updateConfigFile(m, pattern); err != nil {
return err
}
}
}

//m.Logger.Plain("DefaultsConfigMigration: Up")
return nil
}

func (m *UpdateDefaultsConfigMigration) down() error {
//m.Logger.Plain("UpdateDefaultsConfigMigration: down")
if err := m.Mediator.notifyAboutCompletion(); err != nil {
return err
}
return nil
}

func (m *UpdateDefaultsConfigMigration) allowUp() error {
//m.Logger.Plain("UpdateDefaultsConfigMigration: allowUp")
if err := m.up(); err != nil {
return err
}
Expand All @@ -83,9 +82,11 @@ func (m *UpdateDefaultsConfigMigration) allowUp() error {

//=============================================================================

func isMigrationRequired(m *UpdateDefaultsConfigMigration, pattern *regexp.Regexp) bool {
func isDefaultsConfigMigrationRequired(m *UpdateDefaultsConfigMigration, pattern *regexp.Regexp) bool {
content, err := afero.ReadFile(m.Fs, m.Data.PathToFile)
utils.ExitIfError(err)
if err != nil {
return false
}

lines := strings.Split(string(content), "\n")
for _, line := range lines {
Expand All @@ -97,9 +98,11 @@ func isMigrationRequired(m *UpdateDefaultsConfigMigration, pattern *regexp.Regex
return false
}

func migrateConfigFile(m *UpdateDefaultsConfigMigration, pattern *regexp.Regexp) error {
func updateConfigFile(m *UpdateDefaultsConfigMigration, pattern *regexp.Regexp) error {
content, err := afero.ReadFile(m.Fs, m.Data.PathToFile)
utils.ExitIfError(err)
if err != nil {
return err
}

lines := strings.Split(string(content), "\n")
for i, line := range lines {
Expand Down
5 changes: 1 addition & 4 deletions internal/migrations/project-settings-migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ func (m AddProjectSettingsMigration) Execute() error {

func (m *AddProjectSettingsMigration) up() error {
if !m.Mediator.canRun(m) {
//m.Logger.Important("AddProjectSettingsMigration: awaiting")
return nil
}

Expand All @@ -58,23 +57,21 @@ func (m *AddProjectSettingsMigration) up() error {
m.Logger.Info(fmt.Sprintf("Creating %s file", filepath.Base(m.Data.PathToFile)))
return addProjectSettingsFile(m)
} else if exists && m.Data.ProjectCliVersion != m.Data.CliVersion {
m.Logger.Info(fmt.Sprintf("Bump sveltin cli version in %s", filepath.Base(m.Data.PathToFile)))
m.Logger.Info(fmt.Sprintf("Bumping Sveltin CLI version in %s", filepath.Base(m.Data.PathToFile)))
return updateFileContent(m)
}

return nil
}

func (m *AddProjectSettingsMigration) down() error {
//m.Logger.Plain("AddProjectSettingsMigration: down")
if err := m.Mediator.notifyAboutCompletion(); err != nil {
return err
}
return nil
}

func (m *AddProjectSettingsMigration) allowUp() error {
//m.Logger.Plain("AddProjectSettingsMigration: allowUp")
if err := m.up(); err != nil {
return err
}
Expand Down
Loading