Skip to content

Commit

Permalink
Rename COMMAND to FUNCTION (#3533)
Browse files Browse the repository at this point in the history
This PR adds another Earthly command called `FUNCTION` which will
replace the command `COMMAND`.
For now `COMMAND` can still be used, but it will show a deprecation
message explaining to use a feature flag (`--use-function-keyword`) and
rename `COMMAND` TO `FUNCTION`.
When the flag is off => `FUNCTION` can't be used.
When the flag is on => `COMMAND` can't be used.

I'd appreciate a review, specifically on the lexer and parser files
where I simply copied the existing configuration for `COMMAND` as
`FUNCTION`
  • Loading branch information
idodod committed Nov 27, 2023
1 parent 19b3ead commit e7e02b4
Show file tree
Hide file tree
Showing 53 changed files with 2,968 additions and 1,922 deletions.
1 change: 1 addition & 0 deletions ast/command/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func init() {
UserCmd: User,
VolumeCmd: Volume,
WorkdirCmd: Workdir,
FunctionCmd: Function,
}
}

Expand Down
1 change: 1 addition & 0 deletions ast/command/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const (
Cache = "CACHE"
Cmd = "CMD"
Command = "COMMAND"
Function = "FUNCTION"
Copy = "COPY"
Do = "DO"
Docker = "DOCKER"
Expand Down
1 change: 1 addition & 0 deletions ast/command/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ const (
UserCmd // "USER"
VolumeCmd // "VOLUME"
WorkdirCmd // "WORKDIR"
FunctionCmd // "FUNCTION"
)
54 changes: 42 additions & 12 deletions ast/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ type block struct {
type listener struct {
*parser.BaseEarthParserListener

tokStream *antlr.CommonTokenStream
ef *spec.Earthfile
target *spec.Target
userCommand *spec.UserCommand
blocks []*block
command *spec.Command
tokStream *antlr.CommonTokenStream
ef *spec.Earthfile
target *spec.Target
function *spec.Function
blocks []*block
command *spec.Command

stmtWords []string
execMode bool
Expand Down Expand Up @@ -154,9 +154,9 @@ func (l *listener) ExitTarget(c *parser.TargetContext) {
// User command ---------------------------------------------------------------

func (l *listener) EnterUserCommand(c *parser.UserCommandContext) {
l.userCommand = new(spec.UserCommand)
l.function = new(spec.Function)
if l.enableSourceMap {
l.userCommand.SourceLocation = &spec.SourceLocation{
l.function.SourceLocation = &spec.SourceLocation{
File: l.filePath,
StartLine: c.GetStart().GetLine(),
StartColumn: c.GetStart().GetColumn(),
Expand All @@ -168,13 +168,39 @@ func (l *listener) EnterUserCommand(c *parser.UserCommandContext) {
}

func (l *listener) EnterUserCommandHeader(c *parser.UserCommandHeaderContext) {
l.userCommand.Name = strings.TrimSuffix(c.GetText(), ":")
l.function.Name = strings.TrimSuffix(c.GetText(), ":")
}

func (l *listener) ExitUserCommand(c *parser.UserCommandContext) {
l.userCommand.Recipe = l.popBlock()
l.ef.UserCommands = append(l.ef.UserCommands, *l.userCommand)
l.userCommand = nil
l.function.Recipe = l.popBlock()
l.ef.Functions = append(l.ef.Functions, *l.function)
l.function = nil
}

// Function ---------------------------------------------------------------

func (l *listener) EnterFunction(c *parser.FunctionContext) {
l.function = new(spec.Function)
if l.enableSourceMap {
l.function.SourceLocation = &spec.SourceLocation{
File: l.filePath,
StartLine: c.GetStart().GetLine(),
StartColumn: c.GetStart().GetColumn(),
EndLine: c.GetStop().GetLine(),
EndColumn: c.GetStop().GetColumn(),
}
}
l.pushNewBlock()
}

func (l *listener) EnterFunctionHeader(c *parser.FunctionHeaderContext) {
l.function.Name = strings.TrimSuffix(c.GetText(), ":")
}

func (l *listener) ExitFunction(c *parser.FunctionContext) {
l.function.Recipe = l.popBlock()
l.ef.Functions = append(l.ef.Functions, *l.function)
l.function = nil
}

// Statement ------------------------------------------------------------------
Expand Down Expand Up @@ -329,6 +355,10 @@ func (l *listener) EnterUserCommandStmt(c *parser.UserCommandStmtContext) {
l.command.Name = "COMMAND"
}

func (l *listener) EnterFunctionStmt(c *parser.FunctionStmtContext) {
l.command.Name = "FUNCTION"
}

func (l *listener) EnterDoStmt(c *parser.DoStmtContext) {
l.command.Name = "DO"
}
Expand Down
5 changes: 5 additions & 0 deletions ast/parser/EarthLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ channels {

Target: [a-z] ([a-zA-Z0-9.] | '-')* ':' -> pushMode(RECIPE);
UserCommand: [A-Z] ([A-Z0-9._])* ':' -> pushMode(RECIPE);
Function: [A-Z] ([A-Z0-9._])* ':' -> pushMode(RECIPE);

FROM: 'FROM' -> pushMode(COMMAND_ARGS);
FROM_DOCKERFILE: 'FROM DOCKERFILE' -> pushMode(COMMAND_ARGS);
Expand Down Expand Up @@ -40,6 +41,7 @@ HEALTHCHECK: 'HEALTHCHECK' -> pushMode(COMMAND_ARGS);
SHELL: 'SHELL' -> pushMode(COMMAND_ARGS);
DO: 'DO' -> pushMode(COMMAND_ARGS);
COMMAND: 'COMMAND' -> pushMode(COMMAND_ARGS);
FUNCTION: 'FUNCTION' -> pushMode(COMMAND_ARGS);
IMPORT: 'IMPORT' -> pushMode(COMMAND_ARGS);
VERSION: 'VERSION' -> pushMode(COMMAND_ARGS);
CACHE: 'CACHE' -> pushMode(COMMAND_ARGS);
Expand Down Expand Up @@ -72,6 +74,7 @@ mode RECIPE;

Target_R: Target -> type(Target);
UserCommand_R: UserCommand -> type(UserCommand);
Function_R: Function -> type(Function);

FROM_R: FROM -> type(FROM), pushMode(COMMAND_ARGS);
FROM_DOCKERFILE_R: FROM_DOCKERFILE -> type(FROM_DOCKERFILE), pushMode(COMMAND_ARGS);
Expand Down Expand Up @@ -100,6 +103,7 @@ HEALTHCHECK_R: HEALTHCHECK -> type(HEALTHCHECK), pushMode(COMMAND_ARGS);
SHELL_R: SHELL -> type(SHELL), pushMode(COMMAND_ARGS);
DO_R: DO -> type(DO), pushMode(COMMAND_ARGS);
COMMAND_R: COMMAND -> type(COMMAND), pushMode(COMMAND_ARGS);
FUNCTION_R: FUNCTION -> type(FUNCTION), pushMode(COMMAND_ARGS);
IMPORT_R: IMPORT -> type(IMPORT), pushMode(COMMAND_ARGS);
CACHE_R: CACHE -> type(CACHE), pushMode(COMMAND_ARGS);
HOST_R: HOST -> type(HOST), pushMode(COMMAND_ARGS);
Expand Down Expand Up @@ -148,6 +152,7 @@ HEALTHCHECK_B: HEALTHCHECK -> type(HEALTHCHECK), pushMode(COMMAND_ARGS);
SHELL_B: SHELL -> type(SHELL), pushMode(COMMAND_ARGS);
DO_B: DO -> type(DO), pushMode(COMMAND_ARGS);
COMMAND_B: COMMAND -> type(COMMAND), pushMode(COMMAND_ARGS);
FUNCTION_B: FUNCTION -> type(FUNCTION), pushMode(COMMAND_ARGS);
IMPORT_B: IMPORT -> type(IMPORT), pushMode(COMMAND_ARGS);
CACHE_B: CACHE -> type(CACHE), pushMode(COMMAND_ARGS);
HOST_B: HOST -> type(HOST), pushMode(COMMAND_ARGS);
Expand Down
4 changes: 4 additions & 0 deletions ast/parser/EarthParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ target: targetHeader NL+ (INDENT NL* stmts? NL+ DEDENT)?;
targetHeader: Target;
userCommand: userCommandHeader NL+ (INDENT NL* stmts NL+ DEDENT)?;
userCommandHeader: UserCommand;
function: functionHeader NL+ (INDENT NL* stmts NL+ DEDENT)?;
functionHeader: Function;

stmts: stmt (NL+ stmt)*;

Expand Down Expand Up @@ -49,6 +51,7 @@ commandStmt:
| healthcheckStmt
| shellStmt
| userCommandStmt
| functionStmt
| doStmt
| importStmt
| cacheStmt
Expand Down Expand Up @@ -163,6 +166,7 @@ onbuildStmt: ONBUILD stmtWords?;
healthcheckStmt: HEALTHCHECK stmtWords?;
shellStmt: SHELL stmtWords?;
userCommandStmt: COMMAND stmtWords?;
functionStmt: FUNCTION stmtWords?;
doStmt: DO stmtWords?;
importStmt: IMPORT stmtWords?;
cacheStmt: CACHE stmtWords?;
Expand Down

0 comments on commit e7e02b4

Please sign in to comment.