Documentation
¶
Overview ¶
Package gen turns a module specification into Go source.
It is deterministic and it does not call a model: the same specification produces the same bytes, which is what makes golden files a real test rather than a formality. The specification comes from a YAML file a model wrote or from command-line flags. The generator does not care which, and that is the point -- the model never writes Go.
Index ¶
- func DefaultEventKey(typeName, aggregate string) string
- func DefaultEventName(typeName string) string
- func Exported(name string) string
- func Humanise(s string) string
- func IsExportedIdentifier(s string) bool
- func Kebab(s string) string
- func Merge(existing, generated []byte) []byte
- func Normalize(name string) string
- func TypeList() string
- func Write(root string, files []File, force bool) (written, skipped []string, err error)
- type Command
- type EnumSpec
- type EnumValue
- type EventSpec
- type FactoryField
- type FactorySpec
- type Field
- func (f Field) Bind(receiver string) string
- func (f Field) BlueprintMethod() string
- func (f Field) Column() string
- func (f Field) Display(receiver string) string
- func (f Field) Factory() FactoryField
- func (f Field) FormType() string
- func (f Field) FormValue(receiver string) string
- func (f Field) GoName() string
- func (f Field) GoType() string
- func (f Field) InputStep() string
- func (f Field) InputType() string
- func (f Field) IsBool() bool
- func (f Field) IsEmail() bool
- func (f Field) IsFraction() bool
- func (f Field) IsLongText() bool
- func (f Field) IsString() bool
- func (f Field) IsTime() bool
- func (f Field) IsWholeNumber() bool
- func (f Field) Label() string
- func (f Field) MaxLength() int
- func (f Field) Parse(receiver string) string
- func (f Field) SQLType() string
- func (f Field) SQLZero() string
- func (f Field) TimeLayout() string
- func (f Field) ViewType() string
- type File
- func Generate(m Module) ([]File, error)
- func GenerateCommand(c Command) ([]File, error)
- func GenerateController(s Stub) ([]File, error)
- func GenerateListener(l Listener) ([]File, error)
- func GenerateMiddleware(s Stub) ([]File, error)
- func GenerateModel(m Module, parts ModelParts) ([]File, error)
- func GenerateRequest(s Stub) ([]File, error)
- func RenderEnum(s EnumSpec) (File, error)
- func RenderEvent(s EventSpec) (File, error)
- func RenderFactory(s FactorySpec) (File, error)
- func RenderJob(s JobSpec) (File, error)
- func RenderMail(s MailSpec) ([]File, error)
- func RenderMigration(s MigrationSpec) (File, error)
- func RenderSeeder(s SeederSpec) (File, error)
- type JobSpec
- type Kind
- type Listener
- type MailSpec
- type MigrationSpec
- type ModelParts
- type Module
- func (m Module) BoolFields() []Field
- func (m Module) Controller() string
- func (m Module) Entity() string
- func (m Module) FirstField() Field
- func (m Module) FormStruct() string
- func (m Module) Human() string
- func (m Module) HumanTitle() string
- func (m Module) Humans() string
- func (m Module) HumansTitle() string
- func (m Module) MigrationID() string
- func (m Module) MigrationSpec() MigrationSpec
- func (m Module) MigrationType() string
- func (m Module) ModelsImport() string
- func (m Module) NeedsFractionParse() bool
- func (m Module) NeedsTimeParse() bool
- func (m Module) NeedsWholeParse() bool
- func (m Module) Plural() string
- func (m Module) PoliciesImport() string
- func (m Module) PolicyType() string
- func (m Module) Receiver() string
- func (m Module) RepositoriesImport() string
- func (m Module) RepositoryType() string
- func (m Module) RequestsImport() string
- func (m Module) Resource() string
- func (m Module) RestFields() []Field
- func (m Module) Route() string
- func (m Module) RowStruct() string
- func (m Module) Rules() []Rule
- func (m Module) ServiceType() string
- func (m Module) ServicesImport() string
- func (m Module) Sortable() []Field
- func (m Module) StoreRequest() string
- func (m Module) Table() string
- func (m Module) Unexported() string
- func (m Module) UniqueFields() []Field
- func (m Module) UpdateRequest() string
- func (m Module) Validate() error
- func (m Module) ViewData(page string) string
- func (m Module) ViewName(page string) string
- func (m Module) ViewsImport() string
- func (m Module) ViewsPackage() string
- type Rule
- type SeederSpec
- type Stub
- type Type
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultEventKey ¶ added in v0.12.0
DefaultEventKey derives the published key from the type and the aggregate: InvoicePaid on invoice becomes "invoice.paid".
func DefaultEventName ¶ added in v0.12.0
DefaultEventName derives the routing key from the type: SendInvoice becomes "send-invoice". It is a default rather than the only option, because the name somebody wants is usually "invoice.send" and only they know that.
func Exported ¶ added in v0.12.0
Exported turns any accepted spelling of a name into the Go type it names: "invoice_line", "invoice-line" and "InvoiceLine" all become InvoiceLine.
func IsExportedIdentifier ¶ added in v0.12.0
IsExportedIdentifier reports whether s can be a Go type name in a generated file. A generator that emitted an identifier Go refuses would emit a file that does not compile, which is worse than refusing here.
func Merge ¶
Merge carries the custom blocks of the existing file into the newly generated one, in order.
Blocks are matched by position, not by name, which is the honest limitation: reordering the generated file would shuffle them. That is why the marker appears once per file, at the end, where new blocks are appended rather than inserted.
func Normalize ¶ added in v0.12.0
Normalize accepts the two spellings of one name and returns the module one.
`aru make:module` takes a module name -- purchase_order -- while the habit from elsewhere is to type a class name -- PurchaseOrder. People type the second, and the generator needs the first, so both are accepted and converted here rather than in eight commands.
Types ¶
type Command ¶ added in v0.12.0
type Command struct {
// Name is the type name: CloseInvoices.
Name string
// Signature is what the person types: "invoice:close".
Signature string
// Description is the one line `aru` prints next to it.
Description string
// ModulePath is the project's module path, for the import.
ModulePath string
}
Command is one console command to write.
func (Command) DescriptionOrDefault ¶ added in v0.12.0
DescriptionOrDefault is the one line the console listing prints.
func (Command) Receiver ¶ added in v0.12.0
Receiver is the one-letter receiver, avoiding the names the signature binds.
func (Command) SignatureOrDefault ¶ added in v0.12.0
SignatureOrDefault is what the person types, derived from the name when the flag was left out. It is a method so the CLI can print the same value the generated file carries, instead of computing it a second time.
type EnumSpec ¶ added in v0.12.0
type EnumSpec struct {
// Type is the Go type name: "InvoiceStatus".
Type string
// Values are the members, in declaration order.
Values []EnumValue
// Int backs the enum with an integer instead of a string.
Int bool
}
EnumSpec is one enum.
func (EnumSpec) Names ¶ added in v0.12.0
Names lists the stored values, for the error message a parse failure carries.
type EnumValue ¶ added in v0.12.0
type EnumValue struct {
// Name is the value as stored: "draft". It is what a column holds and what
// every consumer of an event reads, so it is never derived from the constant.
Name string
// Number is the stored value when the enum is backed by an integer.
Number int
// Type is the enum's type name, so a value can spell its own constant.
Type string
}
EnumValue is one member of the closed set.
func ParseEnumValues ¶ added in v0.12.0
ParseEnumValues reads the --values flag: "draft,sent,paid,void", or "draft=1,sent=2,paid=3" when the numbers have to be pinned.
Why a number can be written down ¶
An --int enum is stored as an integer, so its numbers are the meaning of every row already written. Numbering by position alone made adding a value a data migration nobody was told about: `--values "draft,sent,paid" --force` on a file that had been generated as "draft,paid" moves paid from 2 to 3, and every row holding 2 silently becomes "sent". --force exists precisely so that re-running is how you add a value, so the intended workflow was the one that repointed the data.
Positional numbering is kept for the first run, where there is nothing to repoint and writing "=1,=2,=3" would be ceremony. Mixing the two forms in one flag is refused rather than guessed at: what the person meant by "draft,sent=7,paid" is not knowable, and a wrong guess is the same silent repointing.
type EventSpec ¶ added in v0.12.0
type EventSpec struct {
// Type is the Go type: "InvoicePaid". Past tense, always -- it is what the
// events package requires and what makes a consumer able to read a log.
Type string
// Aggregate is what it happened to: "invoice". Required, because an empty
// Aggregate produces an event no consumer can correlate and no error
// anywhere reports.
Aggregate string
// EventName is the published key: "invoice.paid".
EventName string
// Fields are the payload's columns.
Fields []Field
// ModulePath is the project's module path.
ModulePath string
}
EventSpec is one domain event.
What comes out is not a dispatcher: an event here is a row in the outbox, written in the same transaction as the write that caused it, and delivery belongs to the relay. So the generated file is a constructor of events.Event plus the constant that names it.
func (EventSpec) Const ¶ added in v0.12.0
Const is the name of the constant that carries the published key.
func (EventSpec) NeedsTime ¶ added in v0.12.0
NeedsTime reports whether the payload declares a date or a timestamp.
type FactoryField ¶ added in v0.12.0
FactoryField is one field of the entity, as the factory sees it.
It carries the Go type and not the DSL type, and that is the decision rather than an oversight: `aru make:model --factory` knows money and date, and `aru make:factory` reads the model and only ever sees int64 and time.Time. A default that depended on the DSL would make the same file come out two ways depending on which command wrote it, which is the definition of two shapes of one thing.
func FieldsFromModel ¶ added in v0.12.0
func FieldsFromModel(path, entity string) (fields []FactoryField, tenant bool, err error)
FieldsFromModel reads the entity's fields off app/Models/<Entity>.go.
The model is the schema here -- it is a struct, not a class that discovers its columns at runtime -- so the factory is derived from it rather than declared again. Two sources of truth about one set of columns is how they drift, which is the same reason make:policy reads the tenant off the repository instead of asking for it a second time.
ID, TenantID and CreatedAt are skipped: the first is generated by the repository, the second comes from the Grant, the third from the clock.
func (FactoryField) Column ¶ added in v0.12.0
func (f FactoryField) Column() string
Column is the field as the DSL spells it, which is what a generated string default reads like: "reference-1".
func (FactoryField) DefaultExpr ¶ added in v0.12.0
func (f FactoryField) DefaultExpr() string
DefaultExpr is the generated value, numbered by n so a batch has distinct values.
It is an index rather than a random draw: a fixture that differs between two runs is a test that fails one time in a hundred, and a test that fails one time in a hundred is a test the team deletes.
func (FactoryField) HasDefault ¶ added in v0.12.0
func (f FactoryField) HasDefault() bool
HasDefault reports whether Make generates a value when the caller did not set one. A boolean has no spare value to mean "unset", so it is taken as given.
func (FactoryField) Var ¶ added in v0.12.0
func (f FactoryField) Var() string
Var is the local variable the generated Make uses: "DeliveryDate" becomes "deliveryDate".
func (FactoryField) ZeroTest ¶ added in v0.12.0
func (f FactoryField) ZeroTest() string
ZeroTest is the condition under which Make generates a value.
type FactorySpec ¶ added in v0.12.0
type FactorySpec struct {
Entity string
Tenant bool
Fields []FactoryField
ModelsImport string
}
FactorySpec is what a factory needs to know, and it is deliberately less than a Module: the Go type of each field, and whether the entity has a tenant.
func (FactorySpec) Human ¶ added in v0.12.0
func (s FactorySpec) Human() string
Human is the entity in a sentence: "purchase order".
func (FactorySpec) Humans ¶ added in v0.12.0
func (s FactorySpec) Humans() string
Humans is the plural, for the doc comment.
func (FactorySpec) NeedsFmt ¶ added in v0.12.0
func (s FactorySpec) NeedsFmt() bool
NeedsFmt reports whether a generated default uses fmt.
func (FactorySpec) Path ¶ added in v0.12.0
func (s FactorySpec) Path() string
Path is where the file goes.
func (FactorySpec) Type ¶ added in v0.12.0
func (s FactorySpec) Type() string
Type is the generated type name.
func (FactorySpec) Validate ¶ added in v0.12.0
func (s FactorySpec) Validate() error
Validate reports what is wrong before a file is written.
type Field ¶
type Field struct {
Name string // as written by the user: "full_name"
Type Type
Required bool
Unique bool
}
Field is one column of the entity.
func ParseFields ¶
ParseFields reads the --fields flag: "name:string!,email:email!u,total:money".
The suffixes are "!" for required and "u" for unique. It is terse because it is typed on a command line; the YAML specification spells the same thing out, and produces the same Module.
func (Field) Bind ¶ added in v0.7.0
Bind renders the field as an argument to a statement.
A date goes through data.Day, which truncates to midnight UTC. DATE is the one type in the portable subset the engines do not agree about: PostgreSQL drops the time part on write and SQLite keeps it, so the same code returns different values on different engines. Everything else binds as it is.
func (Field) BlueprintMethod ¶ added in v0.34.0
BlueprintMethod is the Blueprint method that declares this column.
func (Field) Display ¶ added in v0.8.0
Display is the expression that turns the entity's field into the row's.
func (Field) Factory ¶ added in v0.12.0
func (f Field) Factory() FactoryField
Factory is how a specification field describes itself to a factory.
func (Field) FormType ¶ added in v0.8.0
FormType is how the field is declared in the view's form struct.
Everything is text except a boolean, because a form carries text: the value that comes back after a rejection has to be exactly what the person typed, including the "12,00" that failed to parse. A checkbox is the exception -- it is checked or it is not.
func (Field) FormValue ¶ added in v0.8.0
FormValue is the expression that fills the form struct from the entity, for the edit screen.
func (Field) InputStep ¶ added in v0.8.0
InputStep is the step attribute of a numeric input: cents for money, any for a decimal, and whole units for an integer.
func (Field) IsFraction ¶ added in v0.8.0
IsFraction reports whether the field is parsed with ParseFloat.
func (Field) IsLongText ¶ added in v0.8.0
IsLongText reports whether the field is rendered as a textarea.
func (Field) IsString ¶
IsString reports whether the field is text-like, and therefore gets length validation.
func (Field) IsTime ¶ added in v0.8.0
IsTime reports whether the field is a date or a timestamp, which are the two that arrive as text and leave as time.Time.
func (Field) IsWholeNumber ¶ added in v0.8.0
IsWholeNumber reports whether the field is parsed with ParseInt.
func (Field) Label ¶ added in v0.8.0
Label is the field as a form label: "supplier_email" becomes "Supplier email".
Sentence case, not Title Case: it is what a form label looks like in an application somebody designed, and Title Case On Every Word is what a generator looks like.
func (Field) MaxLength ¶ added in v0.7.0
MaxLength is the limit the generated validation enforces.
It agrees with the column: a value that passes validation has to fit, or the rejection comes from the database driver instead of from the validator, in a message about a column rather than about a field somebody filled in.
func (Field) Parse ¶ added in v0.8.0
Parse is the expression a controller uses to read the field from the request.
The helpers it names are methods on the controller rather than package functions: every module generates into the same package now, and two modules declaring parseInt would not compile.
func (Field) SQLZero ¶ added in v0.29.0
SQLZero is the value a column of this type gets when it is added to a table that already has rows.
A column added during a rollout has to be readable by the PREVIOUS binary and by the next one. Adding it nullable with no default, while the scan the same generator emits reads every column straight into its Go type, means that the moment `aru migrate` runs the replicas still on the old binary answer "converting NULL to int is unsupported" on every read of that table, and the ones on the new binary do too until something writes each row.
The two halves have to agree, and a default is the half that needs no second pass over the data.
func (Field) TimeLayout ¶ added in v0.8.0
TimeLayout is how a date or a timestamp is written in a form field.
They are the layouts the HTML input types produce: "date" submits 2006-01-02 and "datetime-local" submits 2006-01-02T15:04. Parsing anything else would reject what the browser itself sent.
func (Field) ViewType ¶ added in v0.8.0
ViewType is how the field is declared in the view's row struct.
Dates leave as text, already formatted: a view that formats a time.Time would need the time package imported into a generated file whose imports are fixed, and formatting is a decision about presentation that belongs to the controller anyway.
type File ¶
File is one generated file.
func Generate ¶
Generate produces every file of the module.
It writes nothing: it returns the files, so the caller can show a diff, refuse to overwrite, or write them. A generator that writes as it goes cannot be tested against golden files, and cannot be run twice safely.
func GenerateCommand ¶ added in v0.12.0
GenerateCommand writes app/Console/Commands/<Name>.go.
The difference from the usual shape is where the command becomes reachable from. Discovery scans a directory and instantiates what it finds; here the command is a value that routes/console.go returns, because nothing in this framework finds a type by reflection.
The cost is one line to add by hand, and the command prints it. What it buys is that `aru route:list`, the console listing and the compiler all read the same slice: a command that is not in it does not exist, and a command in it with a broken signature does not build.
func GenerateController ¶ added in v0.12.0
GenerateController produces app/Http/Controllers/<Type>.go.
One file, always: a controller is not a module, and a command that also wrote a view and a migration would be `aru make:module` under another name.
func GenerateListener ¶ added in v0.12.0
GenerateListener writes app/Listeners/<Name>.go.
The shape differs from the usual one where the delivery does. In process, an event object is dispatched and a listener subscribes to its class; here the event was written to the outbox in the same transaction as the row it is about, and the relay hands it over after the commit.
So a listener implements events.Publisher and answers a NAME, not a type. That is what lets the producer and the consumer live in different binaries later without either of them changing.
Delivery is at-least-once by design: the relay can hand the same event twice if a publish succeeded and the acknowledgement did not. The generated handler says so and leaves the idempotency where only the application can put it.
func GenerateMiddleware ¶ added in v0.12.0
GenerateMiddleware produces app/Http/Middleware/<Type>.go.
func GenerateModel ¶ added in v0.12.0
func GenerateModel(m Module, parts ModelParts) ([]File, error)
GenerateModel produces the model, and the parts the flags asked for.
It renders the same templates Generate does: a model written by make:model and a model written by make:module are the same bytes, because they are the same file. A second template would be a second shape of one thing.
What it never writes is a repository. A repository pulls a policy with it -- `aru doctor` reports repository-without-policy as an Error -- and the generated policy denies everything, which pulls a service to issue the Grant. A --repository flag would be `aru make:module` with an arbitrary subset missing, and the mandatory path (validate, Authorize, Grant, Repository) is indivisible by construction.
func GenerateRequest ¶ added in v0.12.0
GenerateRequest produces app/Http/Requests/<Type>.go.
func RenderEnum ¶ added in v0.12.0
RenderEnum produces app/Enums/<Type>.go.
func RenderEvent ¶ added in v0.12.0
RenderEvent produces app/Events/<Type>.go.
func RenderFactory ¶ added in v0.12.0
func RenderFactory(s FactorySpec) (File, error)
RenderFactory produces database/factories/<Entity>Factory.go.
func RenderMail ¶ added in v0.21.0
RenderMail writes the mailable and its two views.
func RenderMigration ¶ added in v0.12.0
func RenderMigration(s MigrationSpec) (File, error)
RenderMigration produces the file. Create picks the template.
func RenderSeeder ¶ added in v0.12.0
func RenderSeeder(s SeederSpec) (File, error)
RenderSeeder produces database/seeders/<Entity>Seeder.go.
It depends on no import from the project, and that is what keeps it compiling before the wiring exists: a seeder generated with the repository call already written would not build until the developer had edited seeders.Deps and main.go, and what comes out of the generator has to compile.
type JobSpec ¶ added in v0.12.0
type JobSpec struct {
// Type is the Go type the payload takes: "SendInvoice".
Type string
// EventName is the routing key stored in Job.Name: "invoice.send". It is
// what ties the push to the handler, which is why it is a constant.
EventName string
// Fields are the payload's columns, from the closed set of types.
Fields []Field
// ModulePath is the project's module path, for the import the command prints.
ModulePath string
}
JobSpec is one background job.
Two types come out of one command, and that is the only conceptual difference worth explaining: the usual shape is one class that is both the payload and the handler, because a container reinstantiates it from the serialized object and injects the dependencies. There is no container here and no object serialization -- the payload is JSON and the handler is a value with its dependencies in the constructor.
type Kind ¶ added in v0.12.0
type Kind string
Kind is which shape of controller was asked for.
Three shapes, and the set is closed for the same reason the type list is: a generator whose shapes grow on demand becomes a language.
type Listener ¶ added in v0.12.0
type Listener struct {
// Name is the type name: NotifyAccounting.
Name string
// Event is the event name it answers: "invoice.paid". It is the string the
// producer stored, not a Go type -- the outbox carries names and payloads,
// so a listener and its event never have to be compiled together.
Event string
// ModulePath is the project's module path.
ModulePath string
}
Listener is one event listener to write.
func (Listener) Answers ¶ added in v0.31.0
Answers is the phrase the generated doc comment reads: the quoted event name, or "every event" when the listener was written without one.
It is a method rather than a conditional in the template because the template is a Go string literal, and the conditional sat in a comment line that a reflow later split in half -- putting a comment marker inside the action and leaving the template unparseable for every run of the command.
func (Listener) EventOrAny ¶ added in v0.12.0
EventOrAny is the event it answers, or the marker for "every event".
type MailSpec ¶ added in v0.21.0
type MailSpec struct {
// Type is the exported Go type: WelcomeEmail.
Type string
// ModulePath is the project's, so the generated imports resolve.
ModulePath string
// Subject is the subject line. Empty derives one from the type.
Subject string
// Fields are what the message carries into its views.
Fields []Field
}
MailSpec is one mailable to write.
func (MailSpec) SubjectLine ¶ added in v0.21.0
SubjectLine is what the envelope carries.
type MigrationSpec ¶ added in v0.12.0
type MigrationSpec struct {
// ID is the immutable identifier: "2026_08_07_000002_add_status_to_invoices".
// It is what GetName returns, and the whole of the ordering rule.
ID string
// Type is the Go type the migration is written as:
// "AddStatusToInvoices". It embeds BaseMigration and registers itself.
Type string
// Table is the table the migration is about.
Table string
// Tenant composes the unique constraints and the index with tenant_id.
Tenant bool
// Fields are the columns.
Fields []Field
// Create picks the template: CREATE TABLE when true, ALTER TABLE ... ADD
// COLUMN when false.
Create bool
}
MigrationSpec is one migration file, independent of what asked for it.
`aru make:module`, `aru make:model --migration` and `aru make:migration` all render through this: three commands, one shape of file. A second template would drift on the first change nobody remembered to make twice.
func (MigrationSpec) Path ¶ added in v0.12.0
func (s MigrationSpec) Path() string
Path is where the file goes, which the id already decides.
func (MigrationSpec) UniqueFields ¶ added in v0.12.0
func (s MigrationSpec) UniqueFields() []Field
UniqueFields returns the columns declared unique.
func (MigrationSpec) Validate ¶ added in v0.12.0
func (s MigrationSpec) Validate() error
Validate reports what is wrong with the specification before a file is written. A specification error must never become broken code.
type ModelParts ¶ added in v0.12.0
type ModelParts struct{ Migration, Factory bool }
ModelParts is what `aru make:model` was asked to write besides the model.
type Module ¶
type Module struct {
// Name is the module name as the user typed it: "purchase_order".
Name string
Fields []Field
// Tenant scopes every query by the Grant's tenant. It is a flag rather than
// the default because a module can legitimately be global -- but the moment
// it is set, there is no way to write a query that ignores it.
Tenant bool
// Module path of the project, for the generated imports.
ModulePath string
// Date is the migration id prefix, e.g. "2026_07_31". It is a field rather
// than time.Now() so the generator stays deterministic and golden files mean
// something.
Date string
// Sequence is the six-digit half of the migration id.
//
// Zero means one, so every existing caller and every golden file keeps the id
// it has. It exists because two migrations written on the same day need two
// numbers, and the number is read off the directory rather than off the
// clock: a timestamp to the second collides when two commands run in the same
// second, and a number read off the files is the same number on every machine.
Sequence int
// Permissions maps an action to the roles allowed to take it, and is what
// opens the generated Policy.
//
// Empty means the policy denies everything, which is what `make:module`
// produces: a generator that guessed at permissions would ship a hole by
// default, in every project that ran it. `aru generate` fills this from the
// specification, where a person or a model said so out loud.
Permissions map[string][]string
}
Module is the whole specification.
func (Module) BoolFields ¶ added in v0.8.0
BoolFields returns the checkbox fields, which are the ones the form renders with a checked attribute.
func (Module) Controller ¶ added in v0.8.0
Controller is the type name of the controller: "PurchaseOrderController".
func (Module) FirstField ¶ added in v0.8.0
FirstField is the column the listing links from. It is the first the specification declared, which is the one a person thinks of as the name of the record.
func (Module) FormStruct ¶ added in v0.8.0
FormStruct is the view struct that carries the form fields.
It is not called FormType, so that reading a template is unambiguous: a field has a FormType -- string or bool -- and the module has a FormStruct.
func (Module) Human ¶ added in v0.8.0
Human is the entity as a person writes it in a sentence: "purchase order".
func (Module) HumanTitle ¶ added in v0.8.0
HumanTitle is Human with a capital initial, for a heading: "Purchase order".
func (Module) HumansTitle ¶ added in v0.8.0
HumansTitle is Humans with a capital initial: "Purchase orders".
func (Module) MigrationID ¶ added in v0.8.0
MigrationID is the immutable identifier of the generated migration.
func (Module) MigrationSpec ¶ added in v0.12.0
func (m Module) MigrationSpec() MigrationSpec
MigrationSpec is how a module describes its own create-table migration.
func (Module) MigrationType ¶ added in v0.31.0
MigrationType is the name of the migration type: CreatePurchaseOrdersTable. It is the name the migration registers itself under in its own init.
func (Module) ModelsImport ¶ added in v0.8.0
ModelsImport is the import path of app/Models.
The directories of the tree are CamelCase, as PSR-4 spells them, and the packages inside them are lowercase, as Go spells them. Every generated import is therefore written with an explicit alias, so nobody has to guess which identifier a path called ".../app/Models" binds.
func (Module) NeedsFractionParse ¶ added in v0.8.0
NeedsFractionParse reports whether the controller parses a decimal.
func (Module) NeedsTimeParse ¶ added in v0.8.0
NeedsTimeParse reports whether the controller parses a date or a timestamp, which is the only reason it imports time.
func (Module) NeedsWholeParse ¶ added in v0.8.0
NeedsWholeParse reports whether the controller parses an integer.
func (Module) Plural ¶ added in v0.8.0
Plural is the exported plural of the entity: "PurchaseOrders". It names the view data types, which are per page and per module.
func (Module) PoliciesImport ¶ added in v0.8.0
PoliciesImport is the import path of app/Policies.
func (Module) PolicyType ¶ added in v0.8.0
PolicyType is the type name of the policy.
func (Module) RepositoriesImport ¶ added in v0.8.0
RepositoriesImport is the import path of app/Repositories.
func (Module) RepositoryType ¶ added in v0.8.0
RepositoryType is the type name of the repository.
func (Module) RequestsImport ¶ added in v0.8.0
RequestsImport is the import path of app/Http/Requests.
func (Module) Resource ¶ added in v0.8.0
Resource is the resource segment: the table with dashes instead of underscores. It names the URL, the route names and the view directory, so all three agree by construction -- "purchase-orders", /purchase-orders, purchase-orders.index.
func (Module) RestFields ¶ added in v0.8.0
RestFields is everything after the first, for the remaining table columns.
func (Module) RowStruct ¶ added in v0.8.0
RowStruct is the view struct that carries one record to the markup.
func (Module) Rules ¶ added in v0.6.0
Rules returns the permissions in a fixed order, for the template.
Sorted, because a map ranges differently on every run and the golden files would never match twice.
func (Module) ServiceType ¶ added in v0.8.0
ServiceType is the type name of the service.
func (Module) ServicesImport ¶ added in v0.8.0
ServicesImport is the import path of app/Services.
func (Module) Sortable ¶
Sortable returns the fields that may be used for ordering. Only text and timestamps: a sort field is a column name, and the allowlist is what keeps a column name from the request out of the SQL.
func (Module) StoreRequest ¶ added in v0.8.0
StoreRequest is the type name of the request that creates: StorePurchaseOrder.
func (Module) Table ¶
Table is the table name, pluralized the simple way. English pluralization has hundreds of exceptions; this handles the common ones and gets out of the way.
func (Module) Unexported ¶ added in v0.8.0
Unexported is the entity with a lowercase initial: "purchaseOrder".
Every module now generates into shared packages -- app/Models, app/Policies, app/Repositories -- so an unexported package-level name has to carry the entity or the second module fails to compile.
func (Module) UniqueFields ¶
UniqueFields returns the fields declared unique.
func (Module) UpdateRequest ¶ added in v0.8.0
UpdateRequest is the type name of the request that updates.
func (Module) Validate ¶
Validate reports what is wrong with the specification, before any file is written. A specification error must never become broken code.
func (Module) ViewData ¶ added in v0.8.0
ViewData is the data type of one page: PurchaseOrdersIndexData.
func (Module) ViewName ¶ added in v0.8.0
ViewName is how a page is rendered: purchase-orders.index. It is the path under resources/views with dots, which is how a view is named.
func (Module) ViewsImport ¶ added in v0.8.0
ViewsImport is the package the compiled views live in.
storage/framework/views and not resources/views, and that is not a detail: a view is WRITTEN in resources/views/<resource>/show.kyse.go and COMPILED to storage/framework/views/<resource>/show.go, which is the only one of the two the Go compiler ever sees -- the source carries `//go:build kyse` precisely so that it does not.
Importing the source directory produces "build constraints exclude all Go files", which names the right directory for the wrong reason and sends the reader looking for a missing build tag.
One directory per resource, because one directory is one Go package.
func (Module) ViewsPackage ¶ added in v0.28.1
ViewsPackage is the Go package clause of the compiled views.
It is Resource with the hyphens removed, and it exists because Resource has them by design: "purchase-orders" is the URL segment, the directory name and the first half of the view name, and all three want the hyphen. A Go package name cannot have one.
Without this, every module whose name is more than one word generated `package purchase-orders` and the project did not compile -- reported by kyse as a bug in the generator, which it was. `aru make:module thing` never showed it: one word has no separator.
type SeederSpec ¶ added in v0.12.0
type SeederSpec struct {
// Entity is the exported entity name, with no Seeder suffix: "Invoice".
Entity string
}
SeederSpec is one seeder.
It carries the entity and nothing else: a seeder has no columns, and what it needs to know -- which repository to call -- is a wiring decision that the command prints rather than a flag it takes.
func (SeederSpec) Human ¶ added in v0.12.0
func (s SeederSpec) Human() string
Human is the entity in a sentence: "purchase order".
func (SeederSpec) Humans ¶ added in v0.12.0
func (s SeederSpec) Humans() string
Humans is the plural of Human, for the doc comment.
func (SeederSpec) Path ¶ added in v0.12.0
func (s SeederSpec) Path() string
Path is where the file goes.
func (SeederSpec) Plural ¶ added in v0.12.0
func (s SeederSpec) Plural() string
Plural is the exported plural, which is what the field in Deps is called.
func (SeederSpec) Receiver ¶ added in v0.12.0
func (s SeederSpec) Receiver() string
Receiver is the short local name the commented example uses.
func (SeederSpec) Type ¶ added in v0.12.0
func (s SeederSpec) Type() string
Type is the generated type name: "InvoiceSeeder".
func (SeederSpec) Validate ¶ added in v0.12.0
func (s SeederSpec) Validate() error
Validate reports what is wrong before a file is written.
type Stub ¶ added in v0.12.0
type Stub struct {
// Type is the Go type the file declares: "InvoiceController".
Type string
// ModulePath is the project's module path, for the generated imports.
ModulePath string
// Resource is the URL segment a controller answers: "invoices". It names
// the route in the wiring the command prints, never the file.
Resource string
// Entity is the name the field on routes.Deps takes: "Invoice". It is the
// type without its suffix, and it appears in the generated example of the
// route -- an example naming a field nobody would write is an example that
// gets copied and then corrected.
Entity string
// Kind picks the shape of controller. It is ignored by the other stubs.
Kind Kind
// Fields are the columns a request carries. Empty is legitimate: it is the
// empty stub.
Fields []Field
}
Stub is one granular file: what `aru make:controller`, `aru make:middleware` and `aru make:request` know, which is deliberately less than a Module.
A Module describes an entity and generates twelve files from it. A Stub describes one file, and the person this is for -- porting an application one class at a time -- asks for one file.
func (Stub) Controller ¶ added in v0.12.0
Controller is the type name, under the name the shared controller template asks for. gen.Module answers the same question, which is what lets one template serve both.
func (Stub) IsInvokable ¶ added in v0.12.0
IsInvokable reports whether the single Handle action is emitted.
func (Stub) IsResource ¶ added in v0.12.0
IsResource reports whether the seven actions are emitted.
func (Stub) NeedsTimeParse ¶ added in v0.12.0
NeedsTimeParse reports whether the stub declares a date or a timestamp, which is the only reason a generated request imports time.