Skip to content

Commit 8d76e15

Browse files
reckless: accept a full local path as source+name
This allows installing a local plugin directly without having to modify reckless sources. Changelog-changed: Reckless can be passed a local file or directory for installation.
1 parent fc69a0a commit 8d76e15

File tree

1 file changed

+65
-24
lines changed

1 file changed

+65
-24
lines changed

tools/reckless

Lines changed: 65 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,30 @@ def _install_plugin(src: InstInfo) -> Union[InstInfo, None]:
13001300
return staged_src
13011301

13021302

1303+
def location_from_name(plugin_name: str) -> (str, str):
1304+
"""Maybe the location was passed in place of the plugin name. Check
1305+
if this looks like a filepath or URL and return that as well as the
1306+
plugin name."""
1307+
if not Path(plugin_name).exists():
1308+
# No path included, return the name only.
1309+
return (None, plugin_name)
1310+
1311+
# Directory containing the plugin? The plugin name should match the dir.
1312+
if os.path.isdir(plugin_name):
1313+
return (Path(plugin_name).parent, Path(plugin_name).name)
1314+
1315+
# Possibly the entrypoint itself was passed?
1316+
elif os.path.isfile(plugin_name):
1317+
if Path(plugin_name).with_suffix('').name != Path(plugin_name).parent.name or \
1318+
not Path(plugin_name).parent.parent.exists():
1319+
# If the directory is not named for the plugin, we can't infer what
1320+
# should be done.
1321+
# FIXME: return InstInfo with entrypoint rather than source str.
1322+
return (None, plugin_name)
1323+
# We have to make inferences as to the naming here.
1324+
return (Path(plugin_name).parent.parent, Path(plugin_name).with_suffix('').name)
1325+
1326+
13031327
def install(plugin_name: str) -> Union[str, None]:
13041328
"""Downloads plugin from source repos, installs and activates plugin.
13051329
Returns the location of the installed plugin or "None" in the case of
@@ -1312,33 +1336,48 @@ def install(plugin_name: str) -> Union[str, None]:
13121336
else:
13131337
name = plugin_name
13141338
commit = None
1315-
log.debug(f"Searching for {name}")
1316-
if search(name):
1317-
global LAST_FOUND
1318-
src = LAST_FOUND
1319-
src.commit = commit
1320-
log.debug(f'Retrieving {src.name} from {src.source_loc}')
1321-
try:
1322-
installed = _install_plugin(src)
1323-
except FileExistsError as err:
1324-
log.error(f'File exists: {err.filename}')
1325-
return None
1326-
LAST_FOUND = None
1327-
if not installed:
1328-
log.warning(f'{plugin_name}: installation aborted')
1339+
# Is the install request specifying a path to the plugin?
1340+
direct_location, name = location_from_name(name)
1341+
if direct_location:
1342+
logging.debug(f"install of {name} requested from {direct_location}")
1343+
src = InstInfo(name, direct_location, None)
1344+
if not src.get_inst_details():
1345+
src = None
1346+
# Treating a local git repo as a directory allows testing
1347+
# uncommitted changes.
1348+
if src and src.srctype == Source.LOCAL_REPO:
1349+
src.srctype = Source.DIRECTORY
1350+
if not direct_location or not src:
1351+
log.debug(f"direct_location {direct_location}, src: {src}")
1352+
log.debug(f"Searching for {name}")
1353+
if search(name):
1354+
global LAST_FOUND
1355+
src = LAST_FOUND
1356+
src.commit = commit
1357+
log.debug(f'Retrieving {src.name} from {src.source_loc}')
1358+
else:
13291359
return None
13301360

1331-
# Match case of the containing directory
1332-
for dirname in os.listdir(RECKLESS_CONFIG.reckless_dir):
1333-
if dirname.lower() == installed.name.lower():
1334-
inst_path = Path(RECKLESS_CONFIG.reckless_dir)
1335-
inst_path = inst_path / dirname / installed.entry
1336-
RECKLESS_CONFIG.enable_plugin(inst_path)
1337-
enable(installed.name)
1338-
return f"{installed.source_loc}"
1339-
log.error(('dynamic activation failed: '
1340-
f'{installed.name} not found in reckless directory'))
1361+
try:
1362+
installed = _install_plugin(src)
1363+
except FileExistsError as err:
1364+
log.error(f'File exists: {err.filename}')
13411365
return None
1366+
LAST_FOUND = None
1367+
if not installed:
1368+
log.warning(f'{plugin_name}: installation aborted')
1369+
return None
1370+
1371+
# Match case of the containing directory
1372+
for dirname in os.listdir(RECKLESS_CONFIG.reckless_dir):
1373+
if dirname.lower() == installed.name.lower():
1374+
inst_path = Path(RECKLESS_CONFIG.reckless_dir)
1375+
inst_path = inst_path / dirname / installed.entry
1376+
RECKLESS_CONFIG.enable_plugin(inst_path)
1377+
enable(installed.name)
1378+
return f"{installed.source_loc}"
1379+
log.error(('dynamic activation failed: '
1380+
f'{installed.name} not found in reckless directory'))
13421381
return None
13431382

13441383

@@ -1388,6 +1427,8 @@ def search(plugin_name: str) -> Union[InstInfo, None]:
13881427
if srctype in [Source.DIRECTORY, Source.LOCAL_REPO,
13891428
Source.GITHUB_REPO, Source.OTHER_URL]:
13901429
found = _source_search(plugin_name, source)
1430+
if found:
1431+
log.debug(f"{found}, {found.srctype}")
13911432
if not found:
13921433
continue
13931434
log.info(f"found {found.name} in source: {found.source_loc}")

0 commit comments

Comments
 (0)