jeftadlvw / git-nest

Nest external repositories into your project without git being bothered.
https://github.com/jeftadlvw/git-nest
Apache License 2.0
1 stars 1 forks source link

🏗️ migration system for decoupled state changes #7

Closed jeftadlvw closed 4 months ago

jeftadlvw commented 4 months ago

Currently, state changes are made in actions, which are called by cli commands (one action per command). This works ok for adding and removing a nested module, but will cause some issues as soon as we begin to implement the synchronization part of git-nest (= updating the internal context state or nested module state).

This is because state-decision logic and state-updating logic are combined in one function. By splitting it into a migration-like system, state-decision logic and state-updating logic are split. Updating the state will be a cause after deciding what to update. This results in cleaner and more readable code.

Some design philosophy:

Example migration module:

package interfaces

/*
ModuleMigration defines an interface for performing migration on
nested modules.
*/
type ModuleMigration interface {

    /*
    Migrate migrates the module.
    */
    Migrate() error
}
package migrations

import "github.com/jeftadlvw/git-nest/models"

type AppendSubmodule struct {
    context   *models.NestContext
    submodule models.Submodule
}

func (c *AppendSubmodule) Migrate() error {
    if c.context == nil {
        return fmt.Errorf("migration contained nil context")
    }

    err := c.submodule.Validate()
    if err != nil {
        return fmt.Errorf("submodule validation error: %w", err)
    }

    c.context.Config.Submodules = append(c.context.Config.Submodules, c.submodule)
    return nil
}

Migrations should replace every state-changing operation.

Some furthergoing thoughts and notes: