@@ -19,9 +19,9 @@ class Application
1919 /**
2020 * Application version.
2121 *
22- * @var string
22+ * @var string|null
2323 */
24- protected string $ version = ' 1.0.0 ' ;
24+ protected ? string $ version = null ;
2525
2626 /**
2727 * Registered commands.
@@ -35,6 +35,7 @@ class Application
3535 */
3636 public function __construct ()
3737 {
38+ $ this ->version = $ this ->detectVersion ();
3839 $ this ->registerDefaultCommands ();
3940 }
4041
@@ -171,12 +172,89 @@ public function run(array $argv): int
171172 return $ command ->execute ();
172173 }
173174
175+ /**
176+ * Detect application version.
177+ *
178+ * @return string
179+ */
180+ protected function detectVersion (): string
181+ {
182+ // Try to get version from Composer\InstalledVersions
183+ if (class_exists (\Composer \InstalledVersions::class)) {
184+ try {
185+ $ version = \Composer \InstalledVersions::getVersion ('tommyknocker/pdo-database-class ' );
186+ if (is_string ($ version ) && $ version !== '' ) {
187+ // Remove 'dev-' prefix and commit hash for dev versions
188+ $ version = preg_replace ('/^dev-[^-]+-/ ' , '' , $ version );
189+ $ version = is_string ($ version ) ? preg_replace ('/^dev-/ ' , '' , $ version ) : '' ;
190+ // If it's a valid version (not just 'master'), return it
191+ if (is_string ($ version ) && preg_match ('/^\d+\.\d+\.\d+/ ' , $ version ) === 1 ) {
192+ return $ version ;
193+ }
194+ }
195+ } catch (\Throwable ) {
196+ // Ignore
197+ }
198+ }
199+
200+ // Try to get version from git
201+ $ gitDir = __DIR__ . '/../../.git ' ;
202+ if (is_dir ($ gitDir )) {
203+ // First try to get exact tag
204+ $ gitDescribe = @shell_exec ('git describe --tags --exact-match 2>/dev/null ' );
205+ if (is_string ($ gitDescribe ) && $ gitDescribe !== '' ) {
206+ $ version = trim ($ gitDescribe );
207+ $ version = ltrim ($ version , 'v ' );
208+ if (preg_match ('/^\d+\.\d+\.\d+/ ' , $ version ) === 1 ) {
209+ return $ version ;
210+ }
211+ }
212+
213+ // If not on exact tag, get the latest tag
214+ $ gitDescribe = @shell_exec ('git describe --tags --always 2>/dev/null ' );
215+ if (is_string ($ gitDescribe ) && $ gitDescribe !== '' ) {
216+ $ version = trim ($ gitDescribe );
217+ $ version = ltrim ($ version , 'v ' );
218+ // Extract just the version number from "2.10.2-12-gabc123" -> "2.10.2"
219+ $ matches = [];
220+ if (preg_match ('/^(\d+\.\d+\.\d+)/ ' , $ version , $ matches ) === 1 && count ($ matches ) > 1 ) {
221+ return (string )$ matches [1 ];
222+ }
223+ }
224+ }
225+
226+ // Fallback: try to read from composer.json in parent directory
227+ $ composerPath = __DIR__ . '/../../composer.json ' ;
228+ if (file_exists ($ composerPath )) {
229+ $ composerContent = @file_get_contents ($ composerPath );
230+ if (is_string ($ composerContent )) {
231+ $ composer = @json_decode ($ composerContent , true );
232+ if (is_array ($ composer ) && isset ($ composer ['version ' ]) && is_string ($ composer ['version ' ])) {
233+ return $ composer ['version ' ];
234+ }
235+ }
236+ }
237+
238+ // Ultimate fallback
239+ return '2.10.2 ' ;
240+ }
241+
242+ /**
243+ * Get application version.
244+ *
245+ * @return string
246+ */
247+ public function getVersion (): string
248+ {
249+ return $ this ->version ?? '2.10.2 ' ;
250+ }
251+
174252 /**
175253 * Show help message.
176254 */
177255 protected function showHelp (): void
178256 {
179- echo "{$ this ->name } v {$ this ->version }\n\n" ;
257+ echo "{$ this ->name } v {$ this ->getVersion () }\n\n" ;
180258 echo "Usage: pdodb <command> [arguments] [options] \n\n" ;
181259 echo "Available commands: \n\n" ;
182260
0 commit comments