@@ -32,6 +32,7 @@ const headlampPluginPkg = require('../package.json');
3232const PluginManager = require ( '../plugin-management/plugin-management' ) . PluginManager ;
3333const { table } = require ( 'table' ) ;
3434const tar = require ( 'tar' ) ;
35+ const MultiPluginManager = require ( '../plugin-management/multi-plugin-management' ) ;
3536
3637// ES imports
3738const viteCopyPluginPromise = import ( 'vite-plugin-static-copy' ) ;
@@ -1420,14 +1421,19 @@ yargs(process.argv.slice(2))
14201421 }
14211422 )
14221423 . command (
1423- 'install < URL> ' ,
1424- 'Install a plugin from the Artiface Hub URL' ,
1424+ 'install [ URL] ' ,
1425+ 'Install plugin(s) from a configuration file or a plugin artifact Hub URL' ,
14251426 yargs => {
1426- yargs
1427+ return yargs
14271428 . positional ( 'URL' , {
14281429 describe : 'URL of the plugin to install' ,
14291430 type : 'string' ,
14301431 } )
1432+ . option ( 'config' , {
1433+ alias : 'c' ,
1434+ describe : 'Path to plugin configuration file' ,
1435+ type : 'string' ,
1436+ } )
14311437 . option ( 'folderName' , {
14321438 describe : 'Name of the folder to install the plugin into' ,
14331439 type : 'string' ,
@@ -1440,22 +1446,66 @@ yargs(process.argv.slice(2))
14401446 alias : 'q' ,
14411447 describe : 'Do not print logs' ,
14421448 type : 'boolean' ,
1449+ } )
1450+ . check ( argv => {
1451+ if ( ! argv . URL && ! argv . config ) {
1452+ throw new Error ( 'Either URL or --config must be specified' ) ;
1453+ }
1454+ if ( argv . URL && argv . config ) {
1455+ throw new Error ( 'Cannot specify both URL and --config' ) ;
1456+ }
1457+ return true ;
14431458 } ) ;
14441459 } ,
14451460 async argv => {
1446- const { URL , folderName, headlampVersion, quiet } = argv ;
1447- const progressCallback = quiet
1448- ? null
1449- : data => {
1450- if ( data . type === 'error' || data . type === 'success' ) {
1451- console . error ( data . type , ':' , data . message ) ;
1452- }
1453- } ; // Use console.log for logs if not in quiet mode
14541461 try {
1455- await PluginManager . install ( URL , folderName , headlampVersion , progressCallback ) ;
1456- } catch ( e ) {
1457- console . error ( e . message ) ;
1458- process . exit ( 1 ) ; // Exit with error status
1462+ const { URL , config, folderName, headlampVersion, quiet } = argv ;
1463+ const progressCallback = quiet
1464+ ? ( ) => { }
1465+ : data => {
1466+ const { type = 'info' , message, raise = true } = data ;
1467+ if ( config && ! URL ) {
1468+ // bulk installation
1469+ let prefix = '' ;
1470+ if ( data . current || data . total || data . plugin ) {
1471+ prefix = `${ data . current } of ${ data . total } (${ data . plugin } ): ` ;
1472+ }
1473+ if ( type === 'info' || type === 'success' ) {
1474+ console . log ( `${ prefix } ${ type } : ${ message } ` ) ;
1475+ } else if ( type === 'error' && raise ) {
1476+ throw new Error ( message ) ;
1477+ } else {
1478+ console . error ( `${ prefix } ${ type } : ${ message } ` ) ;
1479+ }
1480+ } else {
1481+ if ( type === 'error' || type === 'success' ) {
1482+ console . error ( `${ type } : ${ message } ` ) ;
1483+ }
1484+ }
1485+ } ;
1486+ if ( URL ) {
1487+ // Single plugin installation
1488+ try {
1489+ await PluginManager . install ( URL , folderName , headlampVersion , progressCallback ) ;
1490+ } catch ( e ) {
1491+ console . error ( e . message ) ;
1492+ process . exit ( 1 ) ; // Exit with error status
1493+ }
1494+ } else if ( config ) {
1495+ const installer = new MultiPluginManager ( folderName , headlampVersion , progressCallback ) ;
1496+ // Bulk installation from config
1497+ const result = await installer . installFromConfig ( config ) ;
1498+ // Exit with error if any plugins failed to install
1499+ if ( result . failed > 0 ) {
1500+ process . exit ( 1 ) ;
1501+ }
1502+ }
1503+ } catch ( error ) {
1504+ console . error ( 'Installation failed' , {
1505+ error : error . message ,
1506+ stack : error . stack ,
1507+ } ) ;
1508+ process . exit ( 1 ) ;
14591509 }
14601510 }
14611511 )
0 commit comments