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

Abstract "task" API: spell incantation, kind and caster #15

Merged
merged 1 commit into from
Nov 17, 2020

Conversation

svengreb
Copy link
Owner

Resolves #14

The "wand" API is inspired by the fantasy novel "Harry Potter" [1] and
uses an abstract view to define interfaces. The main motivation to
create a matching naming to the overall "magic" topic and the actual
target project Mage [2]. This might be too abstract for some, but is
kept understandable insofar as it should allow everyone to use the
"task" API and to derive their own tasks from it.

- <I> `cast.Caster` - A `interface` type that casts a
  `spell.Incantation` using a command for a specific `spell.Kind`:
  - `Cast(spell.Incantation) error` - casts a spell incantation.
  - `Handles() spell.Kind` - returns the spell kind that can be casted.
  - `Validate() error` - validates the caster command.
- <I> `cast.BinaryCaster` - A `interface` type that composes
  `cast.Caster` to run commands using a binary executable:
  - `GetExec() string` - returns the path to the binary executable of
    the command.
- <I> `spell.Incantation` - A `interface` type that is the abstract
  representation of parameters for a command or action:
  - `Formula() []string` - returns all parameters of a spell.
  - `Kind() Kind` - returns the Kind of a spell.
  - `Options() interface{}` - return the options of a spell.
- <I> `cast.Binary` - A `interface` type that composes `cast.Caster` for
  commands which are using a binary executable:
  - `Env() map[string]string` - returns additional environment
    variables.
- <I> `cast.GoCode` - A `interface` type that composes `cast.Caster` for
  actions that can be casted without a `cast.Caster`:
  - `Cast() (interface{}, error)` - casts itself
- <I> `cast.GoModule` - A `interface` type that composes `cast.Binary`
  for commands that are compiled from a [Go module][3]:
  - `GoModuleID() *project.GoModuleID` - returns the identifier of a Go
    module.
- <T> `spell.Kind` - A `struct` type that defines the kind of a spell.

The API components can be roughly translated to their purpose:

- `cast.Caster` -> a executable command
  It validates the command and defines which `spell.Kind` can be handled
  by this caster. It could be executed without parameters
  (`spell.Incantation`), but in most cases needs at least one parameter.
  - `cast.BinaryCaster` -> a composed `cast.Caster` to run commands
    using a binary executable.
    It ensures that the executable file exists and stores information
    like the path. It could also be executed without parameters
    (`spell.Incantation`), but would not have any effect im many cases.
- `spell.Incantation` -> the parameters of a executable command
  It assemble all parameters based on the given options and ensures the
  they are correctly formatted for the execution in a shell environment.
  Except for special incantations like `spell.GoCode` a incantation
  cannot be used alone but must be passed to a `cast.Caster` that is
  able to handle the `spell.Kind` of this incantation.
  - `spell.Binary` -> a composed `spell.Incantation` to run commands
    that are using binary executable.
    It can inject or override environment variables in the shell
    environment in which the the command will be run.
  - `spell.GoCode` -> a composed `spell.Incantation` for pure Go code
    instead of a (binary) executable command.
    It can “cast itself“, e.g. to simply delete a directory using
    packages like `os` from the Go standard library. It has been
    designed this way to also allow such tasks to be handled by the
    incantation API.
  - `spell.GoModule` -> a composed `spell.Binary` to run binary commands
    managed by a [Go module][3], in other words executables installed in
    `GOBIN` or received via `go get`.
    It requires the module identifier (`path@version`) in order to
    download and run the executable.

[1]: https://en.wikipedia.org/wiki/Harry_Potter
[2]: https://magefile.org
[3]: https://golang.org/ref/mod

GH-14
@svengreb svengreb added this to the 0.1.0 milestone Nov 17, 2020
@svengreb svengreb self-assigned this Nov 17, 2020
@svengreb svengreb merged commit 2b13b84 into main Nov 17, 2020
@svengreb svengreb deleted the feature/gh-abstract-task-api branch November 17, 2020 10:45
@svengreb svengreb removed their assignment Nov 17, 2020
@svengreb svengreb mentioned this pull request Nov 17, 2020
svengreb added a commit that referenced this pull request Nov 17, 2020
In GH-15 [1] some parts of the "wand" API have been implemented in form
of spell "incantations", "kinds" and "casters", inspired by the fantasy
novel "Harry Potter" [2] as an abstract view to define interfaces.
In GH-9 [3] and GH-11 [4] the API implementations for an application
configuration store as well as project and VCS repository metadata were
introduced.
These implementations are now usable in a combined form via the basic
"wand" API that consists of the following types:

- <I> `wand.Wand` - A `interface` type that manages a project and its
  applications and stores their metadata. Applications are registered
  using a unique name and the stored metadata can be received based on
  this name:
  - `GetAppConfig(appName string) (app.Config, error)` - returns an
    application configuration.
  - `GetProjectMetadata() project.Metadata` - returns the project
    metadata.
  - `RegisterApp(name, displayName, pathRel string) error` - registers a
    new application.
- <T> `wand.ctxKey` - A `struct` type that serves as context key used to
  wrap a `wand.Wand`.
- <F> `wand.GetCtxKey() interface{}` - A `func` type that returns the
  key used to wrap a `wand.Wand`.
- <F> `wand.WrapCtx(context.Context,Wand) context.Context` - A `func`
  type that wraps the given `wand.Wand` into the parent context.
  Use `wand.GetCtxKey() interface{}` to receive the key used to wrap
  the `wand.Wand`.

[1]: #15
[2]: https://en.wikipedia.org/wiki/Harry_Potter
[3]: #9
[4]: #11

GH-16
svengreb added a commit that referenced this pull request Nov 17, 2020
In GH-15 [1] some parts of the "wand" API have been implemented in form
of spell "incantations", "kinds" and "casters", inspired by the fantasy
novel "Harry Potter" [2] as an abstract view to define interfaces.
In GH-9 [3] and GH-11 [4] the API implementations for an application
configuration store as well as project and VCS repository metadata were
introduced.
These implementations are now usable in a combined form via the basic
"wand" API that consists of the following types:

- <I> `wand.Wand` - A `interface` type that manages a project and its
  applications and stores their metadata. Applications are registered
  using a unique name and the stored metadata can be received based on
  this name:
  - `GetAppConfig(appName string) (app.Config, error)` - returns an
    application configuration.
  - `GetProjectMetadata() project.Metadata` - returns the project
    metadata.
  - `RegisterApp(name, displayName, pathRel string) error` - registers a
    new application.
- <T> `wand.ctxKey` - A `struct` type that serves as context key used to
  wrap a `wand.Wand`.
- <F> `wand.GetCtxKey() interface{}` - A `func` type that returns the
  key used to wrap a `wand.Wand`.
- <F> `wand.WrapCtx(context.Context,Wand) context.Context` - A `func`
  type that wraps the given `wand.Wand` into the parent context.
  Use `wand.GetCtxKey() interface{}` to receive the key used to wrap
  the `wand.Wand`.

[1]: #15
[2]: https://en.wikipedia.org/wiki/Harry_Potter
[3]: #9
[4]: #11

GH-16
svengreb added a commit that referenced this pull request Nov 17, 2020
In GH-15 [1] some parts of the "wand" API have been implemented in form
of spell "incantations", "kinds" and "casters", inspired by the fantasy
novel "Harry Potter" [2] as an abstract view to define interfaces.
In GH-9 [3] and GH-11 [4] the API implementations for an application
configuration store as well as project and VCS repository metadata were
introduced.
These implementations are now usable in a combined form via the basic
"wand" API that consists of the following types:

- <I> `wand.Wand` - A `interface` type that manages a project and its
  applications and stores their metadata. Applications are registered
  using a unique name and the stored metadata can be received based on
  this name:
  - `GetAppConfig(appName string) (app.Config, error)` - returns an
    application configuration.
  - `GetProjectMetadata() project.Metadata` - returns the project
    metadata.
  - `RegisterApp(name, displayName, pathRel string) error` - registers a
    new application.
- <T> `wand.ctxKey` - A `struct` type that serves as context key used to
  wrap a `wand.Wand`.
- <F> `wand.GetCtxKey() interface{}` - A `func` type that returns the
  key used to wrap a `wand.Wand`.
- <F> `wand.WrapCtx(context.Context,Wand) context.Context` - A `func`
  type that wraps the given `wand.Wand` into the parent context.
  Use `wand.GetCtxKey() interface{}` to receive the key used to wrap
  the `wand.Wand`.

[1]: #15
[2]: https://en.wikipedia.org/wiki/Harry_Potter
[3]: #9
[4]: #11

Closes GH-16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Abstract "task" API: spell incantation, kind and caster
1 participant