Skip to content

Commit 577a07d

Browse files
authored
Create VueFileFormatCommand.php
This command is used to format Vue files in the specified order. The order is specified by the user in the format argument. The format argument is a string of 3 characters, each character can be s,t,l s: scripts, t: template, l: style The command will search for all Vue files in the specified folder and format them in the specified order. The command will ask for confirmation before updating the file. The command will also run test function if --test option is passed. we can use this command after install vue-starter-ket to ask user which sequence wants, for example : if want Template,Script,Style we tell him write tsl
1 parent a994387 commit 577a07d

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
<?php
2+
3+
namespace App\Console\Commands;
4+
5+
use Illuminate\Console\Command;
6+
7+
/*
8+
* This command is used to format Vue files in the specified order.
9+
* The order is specified by the user in the format argument.
10+
* The format argument is a string of 3 characters, each character can be s,t,l
11+
* s: scripts, t: template, l: style
12+
* The command will search for all Vue files in the specified folder and format them in the specified order.
13+
* The command will ask for confirmation before updating the file.
14+
* The command will also run test function if --test option is passed.
15+
*/
16+
class VueFileFormatCommand extends Command
17+
{
18+
/**
19+
* The name and signature of the console command.
20+
*
21+
* @var string
22+
*/
23+
protected $signature = 'vuejs:format {format : has 3 char(s,t,l) order of the file format s:scripts, t:template, l:style} {--test : for run test function} {folder? : the folder to search for vue files ,empty means start in root folder,resources/js/ is root folder} {--ask : ask before updating the file}';
24+
25+
26+
/**
27+
* The console command description.
28+
*
29+
* @var string
30+
*/
31+
32+
protected $description = "Format Vue files in the specified order";
33+
34+
35+
/**
36+
* Execute the console command.
37+
*/
38+
public function handle()
39+
{
40+
// get the format argument
41+
$format = $this->argument('format');
42+
$folderInput = $this->argument('folder');
43+
$folderInput = trim($folderInput);
44+
if(empty($folderInput)){
45+
$folderInput = '';
46+
}else{
47+
// add / to the end of the folder name if not exist
48+
if(substr($folderInput, -1) != '/'){
49+
$folderInput .= '/';
50+
}
51+
// remove / from the start of the folder name if exist
52+
if(substr($folderInput, 0, 1) == '/'){
53+
$folderInput = substr($folderInput, 1);
54+
}
55+
}
56+
$ask = $this->option('ask');
57+
$test = $this->option('test');
58+
$this->info('Format: ' . $format);
59+
$this->info('Ask: ' . $ask);
60+
if($test){
61+
$this->test($format);
62+
return;
63+
}
64+
// check if the format is valid
65+
// check if the format is 3 characters long
66+
// check if the format is s,t,l
67+
// check if the format is s,t,l in any order
68+
if (strlen($format) != 3) {
69+
$this->error('Invalid format');
70+
return;
71+
}
72+
if (!preg_match('/^[stl]{3}$/', $format)) {
73+
$this->error('Invalid format');
74+
return;
75+
}
76+
$folder = base_path('resources/js/'.$folderInput); // specify the folder to search for vue files
77+
// get all files in the folder and subfolders
78+
79+
$dir = new \RecursiveDirectoryIterator($folder);
80+
$iterator = new \RecursiveIteratorIterator($dir);
81+
$skippedAll = false;
82+
foreach ($iterator as $file) {
83+
if ($file->isFile() && $file->getExtension() == 'vue') {
84+
$file = $file->getPathname();
85+
86+
if( $ask == 'true'){
87+
$this->info('Processing file: ' . $file);
88+
// yes or no or skip all
89+
$response = $this->choice('Do you want to format this file?', ['y'=>'yes', 'n'=>'no','s'=> 'skip all'], 0);
90+
//$response = $this->confirm('Do you want to format this file?');
91+
if($response == 's'){
92+
break;
93+
$skippedAll = true;
94+
$response = 'n';
95+
}
96+
}else{
97+
$response = 'y';
98+
}
99+
if($response == 'n'){
100+
$this->info('Skipping file: ' . $file);
101+
continue;
102+
}
103+
104+
$this->formattingFile($format,$file);
105+
}
106+
}
107+
108+
$this->info('Files formatted successfully');
109+
110+
}
111+
protected function test($format){
112+
$file = base_path('resources/js/Components/ui/sidebar/SidebarMenuButton.vue');
113+
$this->formattingFile($format,$file);
114+
$this->info('File formatted successfully');
115+
}
116+
function extractRootTemplate($content) {
117+
$templateStart = strpos($content, '<template');
118+
if ($templateStart === false) return '';
119+
120+
$templateEnd = null;
121+
$depth = 0;
122+
$length = strlen($content);
123+
$i = $templateStart;
124+
125+
while ($i < $length) {
126+
if (substr($content, $i, 9) === '<template') {
127+
$depth++;
128+
$i += 9;
129+
} elseif (substr($content, $i, 10) === '</template') {
130+
$depth--;
131+
$i += 10;
132+
if ($depth === 0) {
133+
$templateEnd = strpos($content, '>', $i) + 1;
134+
break;
135+
}
136+
} else {
137+
$i++;
138+
}
139+
}
140+
141+
if ($templateEnd === null) return null;
142+
143+
$templateTag = substr($content, $templateStart, $templateEnd - $templateStart);
144+
$templateContent = substr($templateTag, strpos($templateTag, '>') + 1);
145+
$templateContent = substr($templateContent, 0, strrpos($templateContent, '<'));
146+
147+
return trim($templateContent);
148+
}
149+
150+
151+
protected function formattingFile($format,$file){
152+
153+
$this->info('Processing file: ' . $file);
154+
$content = file_get_contents($file);
155+
$script = '';
156+
$template = '';
157+
$style = '';
158+
// I found issue when <template> tag has template tag inside it
159+
// so I need to use regex to get the content of the root template tag
160+
161+
// get the content of the template tag
162+
163+
/*preg_match('/<template>(.*?)<\/template>/s', $content, $matches);
164+
if (isset($matches[1])) {
165+
$template = $matches[1];
166+
}*/
167+
$template = $this->extractRootTemplate($content);
168+
preg_match_all('/<script(.*?)>(.*?)<\/script>/s', $content, $matches);
169+
if (isset($matches[0])) {
170+
foreach ($matches[0] as $match) {
171+
if($script == '') {
172+
$script = $match;
173+
}
174+
else {
175+
$script .= "\n".$match;
176+
}
177+
178+
}
179+
}
180+
preg_match_all('/<style(.*?)>(.*?)<\/style>/s', $content, $matches);
181+
if (isset($matches[0])) {
182+
foreach ($matches[0] as $match) {
183+
if($style == '') {
184+
$style = $match;
185+
}
186+
else {
187+
$style .= "\n\r".$match;
188+
}
189+
190+
}
191+
}
192+
// now update the file with the new format
193+
$content = '';
194+
for ($index = 0; $index < strlen($format); $index++) {
195+
$char = $format[$index];
196+
if ($char == 's') {
197+
$content .= $script;
198+
} elseif ($char == 't') {
199+
$content .= "<template>\n$template\n</template>";
200+
} elseif ($char == 'l') {
201+
$content .= $style;
202+
}
203+
if($index!== (strlen($format)-1)) $content .= "\n\n";
204+
}
205+
206+
file_put_contents($file, $content);
207+
208+
209+
}
210+
}

0 commit comments

Comments
 (0)