99use PHPCensor \Plugin ;
1010use PHPCensor \ZeroConfigPluginInterface ;
1111
12- use hollodotme \CrontabValidator \CrontabValidator ;
13-
1412/**
1513 * Crontab Linter.
1614 *
@@ -49,8 +47,6 @@ public function __construct(Builder $builder, Build $build, array $options = [])
4947 if (isset ($ options ['files ' ]) && is_array ($ options ['files ' ])) {
5048 $ this ->files = $ options ['files ' ];
5149 }
52-
53- $ this ->validator = new CrontabValidator ();
5450 }
5551
5652 /**
@@ -69,30 +65,46 @@ public function execute()
6965 // $this->builder->logExecOutput(false);
7066 //
7167
72- $ this ->validator = $ validator = new CrontabValidator ();
73-
7468 if (empty ($ this ->files )) {
7569 return true ;
7670 }
7771
72+ $ success = true ;
73+
7874 foreach ($ this ->files as $ fileName ) {
7975 $ cronFile = sprintf ('%s%s ' , $ this ->buildDir , $ fileName );
80- printf ("%s \n" , $ cronFile );
81-
8276 if (!$ this ->validateFile ($ cronFile )) {
77+ $ this ->build ->reportError (
78+ $ this ->builder ,
79+ self ::pluginName (),
80+ sprintf ('Missing Cron File: %s ' , $ fileName ),
81+ BuildError::SEVERITY_NORMAL ,
82+ $ fileName
83+ );
8384 continue ;
8485 }
8586
86- $ cronTab = file_get_contents ($ cronFile );
87+ $ lineNo = 1 ;
88+ $ cronTab = file_get_contents ($ cronFile );
8789 $ cronLines = explode ("\n" , $ cronTab );
8890 foreach ($ cronLines as $ line ) {
89- if (!$ this ->validateLine ($ line )) {
90- continue ;
91+ $ errors = $ this ->validateLine ($ line );
92+ foreach ($ errors as $ err ) {
93+ $ this ->build ->reportError (
94+ $ this ->builder ,
95+ self ::pluginName (),
96+ $ err ,
97+ BuildError::SEVERITY_HIGH ,
98+ $ fileName ,
99+ $ lineNo
100+ );
101+ $ success = false ;
91102 }
103+ ++$ lineNo ;
92104 }
93105 }
94106
95- return true ;
107+ return $ success ;
96108 }
97109
98110 // ------------------------------------------------------------------------
@@ -106,40 +118,74 @@ public function execute()
106118 */
107119 protected function validateFile (string $ file ) : bool
108120 {
109- if (!file_exists ($ file )) {
110- $ this ->build ->reportError (
111- $ this ->builder ,
112- self ::pluginName (),
113- 'Missing Cron File ' ,
114- BuildError::SEVERITY_NORMAL ,
115- $ fileName
116- );
117-
118- return false ;
119- }
120-
121- return true ;
121+ return file_exists ($ file );
122122 }
123123
124124 /**
125125 * Validate Cron Line.
126126 *
127127 * @param string $line
128- * @return bool
128+ * @return array
129129 */
130- protected function validateLine (string $ line ) : bool
130+ protected function validateLine (string $ line ) : array
131131 {
132- if (!$ this ->validator ->isIntervalValid ($ line )) {
133- $ this ->build ->reportError (
134- $ this ->builder ,
135- self ::pluginName (),
136- sprintf ('Invalid expression - %s ' , $ line ),
137- BuildError::SEVERITY_HIGH ,
138- $ fileName
139- );
140- return false ;
132+ $ errors = [];
133+
134+ // Skip comment lines or empty lines
135+ if (empty ($ line ) || substr ($ line , 0 , 1 ) == '# ' ) {
136+ echo "empty/comment line \n" ;
137+ return $ errors ;
138+ }
139+
140+ $ line = str_replace ("\t" , " " , $ line );
141+ $ args = array_values (
142+ array_filter (
143+ explode (" " , $ line ),
144+ function ($ v ) {
145+ return (bool ) strlen ($ v );
146+ }
147+ )
148+ );
149+ $ cmd = implode (' ' , array_slice ($ args , 5 ));
150+ list ($ mins , $ hours , $ dayofmonth , $ month , $ dayofweek ) = array_slice ($ args , 0 , 5 );
151+
152+ $ regEx = [
153+ 'minhour ' => '/^([\*|\d]+)$|^([\*]\/\d+)$|^([\d+]\/\d+?(\-\d+))$|^(\d+-\d+\/[\d]+)$/i ' ,
154+ 'daymonth ' => '/^(\d|\*)$/i ' ,
155+ 'month ' => '/^(\d|\*)$/i ' ,
156+ 'dayweek ' => '/^(\*|\d|[a-z]{3})$/i ' ,
157+ 'cmdoverflow ' => '/^(\d|\*)$/i '
158+ ];
159+
160+ if (!preg_match ($ regEx ['minhour ' ], $ mins )) {
161+ $ errors [] = sprintf ("Minutes invalid value: %s " , $ mins );
162+ }
163+ if (!preg_match ($ regEx ['minhour ' ], $ hours )) {
164+ $ errors [] = sprintf ("Hours invalid value: %s " , $ hours );
165+ }
166+
167+ $ offset = 0 ;
168+ $ dayofmonth = explode (', ' , $ dayofmonth );
169+ foreach ($ dayofmonth as $ dom ) {
170+ if (!preg_match ($ regEx ['daymonth ' ], $ dom )) {
171+ $ errors [] = sprintf ("Day of month[%d] invalid value: %s " , $ offset , $ dom );
172+ }
173+ ++$ offset ;
174+ }
175+
176+ $ offset = 0 ;
177+ $ dayofweek = explode (', ' , $ dayofweek );
178+ foreach ($ dayofweek as $ dow ) {
179+ if (!preg_match ($ regEx ['dayweek ' ], $ dow )) {
180+ $ errors [] = sprintf ("Day of week[%d] invalid value: %s " , $ offset , $ dow );
181+ }
182+ ++$ offset ;
183+ }
184+
185+ if (preg_match ($ regEx ['cmdoverflow ' ], substr ($ cmd , 0 , 1 ) == '* ' )) {
186+ $ errors [] = sprintf ("Cmd starts with invalid character: %s " , $ cmd );
141187 }
142188
143- return true ;
189+ return $ errors ;
144190 }
145191}
0 commit comments