Skip to content

Commit

Permalink
add capability to scaffold controller route with multiple methods
Browse files Browse the repository at this point in the history
  • Loading branch information
zamronypj committed Sep 17, 2020
1 parent 76f257b commit 319f042
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 1 deletion.
136 changes: 136 additions & 0 deletions src/Tasks/Implementations/Controller/CreateMultiRouteTaskImpl.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
(*!------------------------------------------------------------
* Fano CLI Application (https://fanoframework.github.io)
*
* @link https://github.com/fanoframework/fano-cli
* @copyright Copyright (c) 2018 - 2020 Zamrony P. Juhara
* @license https://github.com/fanoframework/fano-cli/blob/master/LICENSE (MIT)
*------------------------------------------------------------- *)
unit CreateMultiRouteTaskImpl;

interface

{$MODE OBJFPC}
{$H+}

uses

TaskOptionsIntf,
TaskIntf,
FileContentReaderIntf,
FileContentWriterIntf,
DirectoryCreatorIntf;

type

(*!--------------------------------------
* Task that add controller to multiple routes
*
* @author Zamrony P. Juhara <[email protected]>
*---------------------------------------*)
TCreateMultiRouteTask = class(TInterfacedObject, ITask)
private
fileReader : IFileContentReader;
fileWriter : IFileContentWriter;
directoryCreator : IDirectoryCreator;
public
constructor create(
fReader : IFileContentReader;
fWriter : IFileContentWriter;
dirCreator : IDirectoryCreator
);

destructor destroy(); override;

function run(
const opt : ITaskOptions;
const longOpt : shortstring
) : ITask;
end;

implementation

uses

SysUtils,
Classes,
strformats;

const

BASE_ROUTE_DIR = 'src' + DirectorySeparator + 'Routes' + DirectorySeparator;

constructor TCreateMultiRouteTask.create(
fReader : IFileContentReader;
fWriter : IFileContentWriter;
dirCreator : IDirectoryCreator
);
begin
fileReader := fReader;
fileWriter := fWriter;
directoryCreator := dirCreator;
end;

destructor TCreateMultiRouteTask.destroy();
begin
fileReader := nil;
fileWriter := nil;
directoryCreator := nil;
inherited destroy();
end;

function TCreateMultiRouteTask.run(
const opt : ITaskOptions;
const longOpt : shortstring
) : ITask;
var controllerName, lowerCtrlName : string;
routeContent : string;
routePattern : string;
routeMethod : string;
routeMethods : TStringArray;
i, lenMethod : integer;
{$INCLUDE src/Tasks/Implementations/Controller/Includes/routes.inc.inc}
begin
controllerName := opt.getOptionValue(longOpt);

//create main entry to main routes file
routeContent := fileReader.read(BASE_ROUTE_DIR + 'routes.inc');
routeContent := routeContent +
'{$INCLUDE ' + controllerName + '/routes.inc}' + LineEnding;
fileWriter.write(BASE_ROUTE_DIR + 'routes.inc', routeContent);

lowerCtrlName := lowerCase(controllerName);
routePattern := opt.getOptionValueDef('route', '/' + lowerCtrlName);
if (routePattern[1] <> '/') then
begin
routePattern := '/' + routePattern;
end;

routeMethods := lowerCase(opt.getOptionValueDef('method', 'get')).split(',');
lenMethod := length(routeMethods);
routeMethod := '';
if lenMethod > 0 then
begin
for i:= 0 to lenMethod - 2 do
begin
routeMethod := routeMethod + '''' + upperCase(routeMethods[i]) + ''',';
end;
routeMethod := routeMethod + '''' + upperCase(routeMethods[lenMethod-1]) + '''';
end;

//create controller route file
directoryCreator.createDirIfNotExists(BASE_ROUTE_DIR + controllerName);
strCtrlRoutesInc := strCtrlRoutesInc + LineEnding +
format(
'router.map([%s], ''%s'', container.get(''%sController'') as IRequestHandler);',
[routeMethod, routePattern, lowerCtrlName]
) + LineEnding;
fileWriter.write(BASE_ROUTE_DIR + controllerName + '/routes.inc', strCtrlRoutesInc);

writeln(
'Create route ',
formatColor(routePattern, TXT_GREEN),
' (', formatColor(uppercase(routeMethod), TXT_YELLOW), ')'
);
result := self;
end;
end.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ implementation
CreateDependencyRegistrationTaskImpl,
CreateRouteTaskImpl,
WithNoRouteTaskImpl,
CreateMultiRouteTaskImpl,
WithMultiRouteTaskImpl,
CreateDependencyTaskImpl,
CreateControllerTaskImpl,
DuplicateCtrlCheckTaskImpl;
Expand Down Expand Up @@ -78,7 +80,11 @@ implementation
),
//wrap to handle --no-route argument
TWithNoRouteTask.create(
TCreateRouteTask.create(fileReader, fileWriter, directoryCreator)
//wrap to handle multiple methods route creation
TWithMultiRouteTask.create(
TCreateMultiRouteTask.create(fileReader, fileWriter, directoryCreator),
TCreateRouteTask.create(fileReader, fileWriter, directoryCreator)
)
)
);
//protect to avoid accidentally creating controller in non Fano-CLI
Expand Down
57 changes: 57 additions & 0 deletions src/Tasks/Implementations/Controller/WithMultiRouteTaskImpl.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
(*!------------------------------------------------------------
* Fano CLI Application (https://fanoframework.github.io)
*
* @link https://github.com/fanoframework/fano-cli
* @copyright Copyright (c) 2018 - 2020 Zamrony P. Juhara
* @license https://github.com/fanoframework/fano-cli/blob/master/LICENSE (MIT)
*------------------------------------------------------------- *)
unit WithMultiRouteTaskImpl;

interface

{$MODE OBJFPC}
{$H+}

uses

TaskOptionsIntf,
TaskIntf,
ConditionalCompositeTaskImpl;

type

(*!--------------------------------------
* Task that run first task if multiple methods
* creation or second task if single method
*----------------------------------------
* Single method
* --method=GET
* Multiple methods
* --method=GET,POST
*----------------------------------------
* @author Zamrony P. Juhara <[email protected]>
*---------------------------------------*)
TWithMultiRouteTask = class(TConditionalCompositeTask)
protected
function condition(
const opt : ITaskOptions;
const longOpt : shortstring
) : boolean; override;
end;

implementation

uses

sysutils;

function TWithMultiRouteTask.condition(
const opt : ITaskOptions;
const longOpt : shortstring
) : boolean;
var routeMethods : TStringArray;
begin
routeMethods := lowerCase(opt.getOptionValueDef('method', 'get')).split(',');
result := (length(routeMethods) > 1);
end;
end.

0 comments on commit 319f042

Please sign in to comment.