-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreateBuilderForClass.sh
More file actions
executable file
·444 lines (377 loc) · 12.7 KB
/
createBuilderForClass.sh
File metadata and controls
executable file
·444 lines (377 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
#!/bin/bash
# HEADER
# @Author Angelos-Giannis
# @Version v0.0.1
#
#+ Usage and details of this script :
#+ ==================================
#+ Execution
#+ -----------
#+ $(basename $0) [-f] [-u]
#+
#+ Description
#+ -----------
#+ The purpose of this script is to automatically create a builder of a given
#+ class/object under the respective builder path.
#+ Options
#+ -----------
#+ Helping
#+ -h : Displays the usage of the script (this description).
#+ -s : How to setup in Php Storm.
#+ Mandatory
#+ -b : Directory where the builder should live.
#+ -f : Filename of the class upon which we need the builder to be created.
#+ -r : Root path of the project (will be used to properly create the builder class).
#+ Optional
#+ -a : Define whether you need a buildFromArrayFunction to be created or not (default = false).
#+ -c : Constructor extra definition.
#+ -d : Dependecies for the builder class.
#+ -n : Namespace of the builder class.
#+ -p : Private variables that will be used in the builder.
#+
#
#
#- Steps to set up on Php Storm for this script
#- ============================================
#- 1. Open PhpStorm -> Preferences
#- 2. Search for "External Tools"
#- 3. Click on add "+"
#- 4. In the prompt that opens :
#- 4.1 Give a name you want
#- 4.2 Add it to a group of your preference
#- 4.3 Set :
#- Program : <your dir>/createBuilderForClass.sh
#- Arguments :
#- * In case you want a buildFromArrayFunction to be created use this :
#- -f $FilePath$ -r $ContentRoot$ -b "<path to store builder>" -n "<builder namespace>" -a
#- * In case you don't want the buildFromArrayFunction function to be included use this :
#- -f $FilePath$ -r $ContentRoot$ -b "<path to store builder>" -n "<builder namespace>"
#- 4.4 Click "OK" to close the prompt
#- 5. Click "Apply"
#- 6. Click "OK" to close the Preferences
#- 7. On right click on a desired file, on the bottom of the options that show up, you will find your group
#- 8. Simply click on the name of you have given in step 4.1
#- 9. Voila!! Your builder has just been created!!!!
#-
#
# END_OF_HEADER
SCRIPT_HEADSIZE=$(head -200 ${0} |grep -n "^# END_OF_HEADER" | cut -f1 -d:)
SCRIPT_NAME="$(basename ${0})"
#
# __createBuilder performs the required steps to create the builder.
#
function __createBuilder() {
filename=$1
root_path=$2
builder_directory=$3
create_build_from_array_function=$4
builder_namespace=$5
builder_dependencies=$6
private_constructor_variables=$7
builder_constructor=$8
# Retrieve the namespace for the class.
namespace=$(__getNamespaceOfClass $filename)
# Retrieve the class to prepare the builder.
class_name=$(__getClassName $filename)
# Retrieve the name of the variable name of the object to build.
global_var_name=$(__snakeCase $class_name)
# Retrieve the builder class name.
builder_class_name=$(__getBuilderClassName $filename)
# Create the builder file.
builder_file=$(__createBuilderClass $root_path $builder_directory $builder_class_name)
# Open the builder class with the constructor and build functions and write them to the builder class file.
__builderClassOpen "${namespace}" "${class_name}" "${builder_class_name}" "${global_var_name}" "${builder_namespace}" "${builder_dependencies}" "${private_constructor_variables}" "${builder_constructor}" > $builder_file
# Public variables of the base class.
public_vars=($(__getPublicVariablesOfClass $filename))
# If need to create a buildFromArray function, here it is generated and writter to the builder file.
[[ $create_build_from_array_function == true ]] && __createBuildFromArrayFunction $global_var_name ${public_vars[@]} >> $builder_file
# Create the with<Something> functions of the builder class and write them to the builder class file.
for public_var in "${public_vars[@]}"
do
data_type=$(__getDataTypeOfField $filename $public_var)
camel_case=$(__camelCase $public_var)
with_func=$(__getWithValueFunction $builder_class_name $public_var $global_var_name $camel_case $data_type)
echo "$with_func" >> $builder_file
done
# Close the builder class with the create<Class> function and write it to the builder class file.
__builderClassClose $class_name >> $builder_file
}
#
# __builderClassOpen prepares the opening of the builder class.
#
function __builderClassOpen() {
class_path=$1
class_name=$2
builder_class_name=$3
instance_variable_name=$4
builder_namespace=$5
builder_dependencies=$6
private_constructor_variables=$7
builder_constructor=$8
#
# Check if all the provided arguments have value and if not add the respective todos.
#
[[ $builder_namespace == "" ]] && builder_namespace="/** @todo define namespace */"
[[ $builder_dependencies == "" ]] && builder_dependencies="/** @todo Define dependencies for the builder (e.g. DI). */"
[[ $private_constructor_variables == "" ]] && private_constructor_variables="/** @todo Define any required private variables for the builder. */"
[[ $builder_constructor == "" ]] && builder_constructor="/** @todo Define any required steps for constructor. */"
echo -e "<?php
declare(strict_types = 1);
namespace ${builder_namespace};
${builder_dependencies}
use ${class_path}\\${class_name};
class ${builder_class_name}
{
${private_constructor_variables}
/** @var ${class_name} \$${instance_variable_name} */
private \$${instance_variable_name};
public function __construct()
{
${builder_constructor}
\$this->$4 = new ${class_name}();
}
/**
* Creates the ${class_name} in the database and returns it.
*
* @return ${class_name}
*/
public function build() : ${class_name}
{
\$this->create${class_name}();
return \$this->${instance_variable_name};
}"
}
#
# __builderClassClose closes the builder class.
#
function __builderClassClose() {
class_name=$1
echo -e "
/**
* Stores the ${class_name} in the database.
*
* @return void
*/
public function create$1() : void
{
/**
* @todo Implement the object persistence function.
*/
}
}"
}
#
# __snakeCase convert a camel case string to snake case.
#
function __snakeCase() {
echo $1 | sed -e 's/\([A-Z]\)/\_\1/g' -e 's/\_//' | tr '[:upper:]' '[:lower:]'
}
#
# __camelCase convert a snake case string to camel case.
#
function __camelCase() {
echo $1 | perl -pe 's/(^|_)./uc($&)/ge;s/_//g'
}
#
# __getDataTypeOfField retrieve the type for each field in class.
#
function __getDataTypeOfField() {
filename=$1
public_var=$2
data_type=$(grep -B 1 -w $public_var $filename | grep "@var" | awk -F'@var' '{print $NF}' | awk -F' ' '{print $1}')
single_data_type=$(echo ${data_type} | sed 's/null//g' | sed 's/\|//g')
[[ $data_type == *"null"* ]] && echo "?${single_data_type}" || echo $single_data_type
}
#
# __createBuildFromArrayFunction prepares the buildFromArray function for the builder.
#
function __createBuildFromArrayFunction() {
builder_class_variable=$1
public_variables=("${@:2}")
example_array="["
build_sequence="(new self())"
iterator=0
for pb_var in "${public_variables[@]}"
do
example_array="${example_array}\"${pb_var}\", "
camel_case=$(__camelCase $pb_var)
build_sequence="${build_sequence}
->with${camel_case}(\$dt[${iterator}])"
iterator=`expr $iterator + 1`
done
example_array="${example_array}]"
example_array=$(echo $example_array | sed 's/, ]$/]/g')
echo -e "
/**
* Builds a batch of offline reasons based on a provided array of the form :
* [
* ${example_array},
* ${example_array},
* ]
*
* @param array \$details
*
* @return array
*/
public function buildFromArray(array \$details) : array
{
\$${builder_class_variable}_array = [];
foreach (\$details as \$dt) {
\$${builder_class_variable}_array[] = ${build_sequence}
->build();
}
return \$${builder_class_variable}_array;
}"
}
#
# __getWithValueFunction prepares the withSomething function in the builder.
#
function __getWithValueFunction() {
builder_class_name=$1
initial_class_element=$2
instance_variable_name=$3
camel_case_class_element=$4
data_type=$5
param_data_type=$5
fix_data_type_todo=""
if [[ $data_type == "" ]]; then
data_type="string"
param_data_type="string"
fix_data_type_todo=" @todo Fix the datatype (if needed)."
else
if [[ $data_type == *"?"* ]]; then
param_data_type=$(echo $data_type | sed 's/?//g')
param_data_type="${param_data_type}|null"
fi
fi
echo -e "
/**
* Set the value for ${initial_class_element}.
*
* @param ${param_data_type} \$${initial_class_element}
*
* @return ${builder_class_name}
*/
public function with${camel_case_class_element}(${data_type} \$${initial_class_element}) : ${builder_class_name}
{
\$this->${instance_variable_name}->${initial_class_element} = \$${initial_class_element};
return \$this;
}"
}
#
# __getNamespaceOfClass retrieves the namespace in which the class belongs to.
#
function __getNamespaceOfClass() {
echo $(grep "namespace " $1 | awk -F' ' '{print $2}' | sed 's/;//g')
}
#
# __getClassName retrieves the class name of the object.
#
function __getClassName() {
echo $(grep "class " $1 | awk -F' ' '{print $2}')
}
#
# __getBuilderClassName retrieves the class bane that the builder will have.
#
function __getBuilderClassName() {
echo $(grep "class " $1 | awk -F' ' '{print $2"Builder"}')
}
#
# __getPublicVariablesOfClass retrieves the public variables of a class.
#
function __getPublicVariablesOfClass() {
echo $(grep "public " $1 | awk -F' ' '{print $2}' | sed s/';'//g | sed s/'\$'//g)
}
#
# __createBuilderClass is responsible to create the required builder file.
#
function __createBuilderClass() {
root_dir=$1
builder_dir=$2
builder_class_name=$3
builder_file="${root_dir}/${builder_dir}/${builder_class_name}.php"
touch $builder_file
echo $builder_file
}
#
# __getUsage returns the usage of this script.
#
function __getUsage() {
head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "^#+" $0 | sed 's/^#+//g' | sed "s/\$(basename \$0)/${SCRIPT_NAME}/g"
}
#
# __getPhpStormSetup returns the setup required for php storm.
#
function __getPhpStormSetup() {
head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "^#-" $0 | sed 's/^#-//g'
}
#
# createBuilderForObjectClass is the "main" function the performs the required checks
# and executes the required steps.
#
function createBuilderForObjectClass() {
OPTION=$1
create_build_from_array_function=false
filename=""
root_path=""
builder_directory=""
builder_namespace=""
builder_dependencies=""
private_constructor_variables=""
builder_constructor=""
while getopts ab:c:d:f:hn:p:r:s OPTION; do
case "$OPTION" in
a)
create_build_from_array_function=true
;;
b)
builder_directory="${OPTARG}"
;;
c)
builder_constructor="${OPTARG}"
;;
d)
builder_dependencies="${OPTARG}"
;;
f)
filename="${OPTARG}"
;;
n)
builder_namespace="${OPTARG}"
;;
p)
private_constructor_variables="${OPTARG}"
;;
r)
root_path="${OPTARG}"
;;
h)
__getUsage >&2
return
;;
s)
__getPhpStormSetup >&2
return
;;
?)
__getUsage >&2
return
;;
*)
echo "Invalid arguments provided!!" >&2
__getUsage >&2
return
;;
esac
done
if [[ $filename == "" || $root_path == "" || $builder_directory == "" ]]; then
__getUsage >&2
exit 1
fi
__createBuilder "${filename}" "${root_path}" "${builder_directory}" "${create_build_from_array_function}" "${builder_namespace}" "${builder_dependencies}" "${private_constructor_variables}" "${builder_constructor}"
exit 0
}
#
# Run the main function to execute the whole process of creating a builder class.
#
createBuilderForObjectClass "$@"