@@ -1298,6 +1298,31 @@ def _install_plugin(src: InstInfo) -> Union[InstInfo, None]:
1298
1298
return staged_src
1299
1299
1300
1300
1301
+ def location_from_name (plugin_name : str ) -> (str , str ):
1302
+ """Maybe the location was passed in place of the plugin name. Check
1303
+ if this looks like a filepath or URL and return that as well as the
1304
+ plugin name."""
1305
+ if not Path (plugin_name ).exists ():
1306
+ # No path included, return the name only.
1307
+ return (None , plugin_name )
1308
+
1309
+ if os .path .isdir (plugin_name ):
1310
+ # Could be entrypoint or directory
1311
+ return (Path (plugin_name ).parent , Path (plugin_name ).name )
1312
+
1313
+ elif os .path .isfile (plugin_name ):
1314
+ # Maybe the plugin entrypoint was passed?
1315
+ if Path (plugin_name ).with_suffix ('' ).name != Path (plugin_name ).parent .name or \
1316
+ not Path (plugin_name ).parent .parent .exists ():
1317
+ # The directory should be named for the plugin. If it's not, we
1318
+ # can't infer what should be done.
1319
+ # FIXME: return InstInfo with entrypoint rather than source str.
1320
+ return (None , plugin_name )
1321
+ # Asked for the entrypoint, but we're inferring how it should be
1322
+ # named, i.e. the directory (named for the plugin, probably w/ matching entrypoint)
1323
+ return (Path (plugin_name ).parent .parent , Path (plugin_name ).with_suffix ('' ).name )
1324
+
1325
+
1301
1326
def install (plugin_name : str ) -> Union [str , None ]:
1302
1327
"""Downloads plugin from source repos, installs and activates plugin.
1303
1328
Returns the location of the installed plugin or "None" in the case of
@@ -1310,33 +1335,56 @@ def install(plugin_name: str) -> Union[str, None]:
1310
1335
else :
1311
1336
name = plugin_name
1312
1337
commit = None
1313
- log .debug (f"Searching for { name } " )
1314
- if search (name ):
1315
- global LAST_FOUND
1316
- src = LAST_FOUND
1317
- src .commit = commit
1318
- log .debug (f'Retrieving { src .name } from { src .source_loc } ' )
1319
- try :
1320
- installed = _install_plugin (src )
1321
- except FileExistsError as err :
1322
- log .error (f'File exists: { err .filename } ' )
1323
- return None
1324
- LAST_FOUND = None
1325
- if not installed :
1326
- log .warning (f'{ plugin_name } : installation aborted' )
1338
+ # Is the install request specifying a path to the plugin?
1339
+ direct_location , name = location_from_name (name )
1340
+ if direct_location :
1341
+ logging .debug (f"install of { name } requested from { direct_location } " )
1342
+ # We don't need to search here, but this populates install info and
1343
+ # validates that it seems installable.
1344
+ # src = _source_search(name, direct_location) # didn't work because it infers source type
1345
+ src = InstInfo (name , direct_location , None )
1346
+ src .srctype = Source .DIRECTORY
1347
+ if src .get_inst_details ():
1348
+ log .debug (f"{ src } , { src .srctype } " )
1349
+ else :
1350
+ log .debug (f"could not get install details for { src } ." )
1351
+ src = None
1352
+ # We can potentially treat a local directory as that, or as a local git
1353
+ # repo. Treating it as simply a directory allows testing changes
1354
+ # without commiting or pushing.
1355
+ if src and src .srctype == Source .LOCAL_REPO :
1356
+ src .srctype = Source .DIRECTORY
1357
+ if not direct_location or not src :
1358
+ log .debug (f"direct_location { direct_location } , src: { src } " )
1359
+ log .debug (f"Searching for { name } " )
1360
+ if search (name ):
1361
+ global LAST_FOUND
1362
+ src = LAST_FOUND
1363
+ src .commit = commit
1364
+ log .debug (f'Retrieving { src .name } from { src .source_loc } ' )
1365
+ else :
1327
1366
return None
1328
1367
1329
- # Match case of the containing directory
1330
- for dirname in os .listdir (RECKLESS_CONFIG .reckless_dir ):
1331
- if dirname .lower () == installed .name .lower ():
1332
- inst_path = Path (RECKLESS_CONFIG .reckless_dir )
1333
- inst_path = inst_path / dirname / installed .entry
1334
- RECKLESS_CONFIG .enable_plugin (inst_path )
1335
- enable (installed .name )
1336
- return f"{ installed .source_loc } "
1337
- log .error (('dynamic activation failed: '
1338
- f'{ installed .name } not found in reckless directory' ))
1368
+ try :
1369
+ installed = _install_plugin (src )
1370
+ except FileExistsError as err :
1371
+ log .error (f'File exists: { err .filename } ' )
1339
1372
return None
1373
+ LAST_FOUND = None
1374
+ if not installed :
1375
+ log .warning (f'{ plugin_name } : installation aborted' )
1376
+ return None
1377
+
1378
+ # Match case of the containing directory
1379
+ for dirname in os .listdir (RECKLESS_CONFIG .reckless_dir ):
1380
+ if dirname .lower () == installed .name .lower ():
1381
+ inst_path = Path (RECKLESS_CONFIG .reckless_dir )
1382
+ inst_path = inst_path / dirname / installed .entry
1383
+ RECKLESS_CONFIG .enable_plugin (inst_path )
1384
+ enable (installed .name )
1385
+ return f"{ installed .source_loc } "
1386
+ log .error (('dynamic activation failed: '
1387
+ f'{ installed .name } not found in reckless directory' ))
1340
1388
return None
1341
1389
1342
1390
0 commit comments