Skip to content

Commit ea87631

Browse files
authored
Merge #92: Make from_file_path work with installed resources
2 parents 2d4d432 + 93fb959 commit ea87631

File tree

2 files changed

+80
-2
lines changed

2 files changed

+80
-2
lines changed

st3/sublime_lib/resource_path.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ def get_resource_roots():
1717
}
1818

1919

20+
def get_installed_resource_roots():
21+
return (
22+
sublime.installed_packages_path(),
23+
Path(sublime.executable_path()).parent / 'Packages',
24+
)
25+
26+
2027
class ResourcePath():
2128
"""
2229
A pathlib-inspired representation of a Sublime Text resource path.
@@ -65,8 +72,27 @@ def from_file_path(cls, file_path):
6572
"""
6673
Return a :class:`ResourcePath` corresponding to the given file path.
6774
75+
If the file path corresponds to a resource inside an installed package,
76+
then return the path to that resource.
77+
6878
:raise ValueError: if the given file path does not correspond to any resource path.
6979
:raise ValueError: if the given file path is relative.
80+
81+
.. code-block:: python
82+
83+
>>> ResourcePath.from_file_path(
84+
os.path.join(sublime.packages_path(), 'My Package', 'foo.py')
85+
)
86+
ResourcePath("Packages/My Package/foo.py")
87+
88+
>>> ResourcePath.from_file_path(
89+
os.path.join(
90+
sublime.installed_packages_path(),
91+
'My Package.sublime-package',
92+
'foo.py'
93+
)
94+
)
95+
ResourcePath("Packages/My Package/foo.py")
7096
"""
7197
file_path = Path(file_path)
7298
if not file_path.is_absolute():
@@ -75,11 +101,25 @@ def from_file_path(cls, file_path):
75101
for root, base in get_resource_roots().items():
76102
try:
77103
rel = file_path.relative_to(base)
78-
return cls(root, *rel.parts)
79104
except ValueError:
80105
pass
106+
else:
107+
return cls(root, *rel.parts)
81108

82-
raise ValueError("Path {!r} is not beneath any resource path root.".format(file_path))
109+
for base in get_installed_resource_roots():
110+
try:
111+
rel = file_path.relative_to(base).parts
112+
except ValueError:
113+
pass
114+
else:
115+
if rel == ():
116+
return cls('Packages')
117+
package, *rest = rel
118+
package_path = cls('Packages', package)
119+
if package_path.suffix == '.sublime-package':
120+
return package_path.with_suffix('').joinpath(*rest)
121+
122+
raise ValueError("Path {!r} does not correspond to any resource path.".format(file_path))
83123

84124
def __init__(self, *pathsegments):
85125
"""

tests/test_resource_path.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,44 @@ def test_from_file_path_cache(self):
4444
ResourcePath("Cache/test_package")
4545
)
4646

47+
def test_from_file_path_installed_packages(self):
48+
self.assertEqual(
49+
ResourcePath.from_file_path(
50+
Path(sublime.installed_packages_path(), 'test_package.sublime-package', 'foo.py')
51+
),
52+
ResourcePath("Packages/test_package/foo.py")
53+
)
54+
55+
def test_from_file_path_installed_packages_not_installed(self):
56+
with self.assertRaises(ValueError):
57+
ResourcePath.from_file_path(
58+
Path(sublime.installed_packages_path(), 'test_package', 'foo.py')
59+
),
60+
61+
def test_from_file_path_installed_packages_root(self):
62+
self.assertEqual(
63+
ResourcePath.from_file_path(Path(sublime.installed_packages_path())),
64+
ResourcePath("Packages")
65+
)
66+
67+
def test_from_file_path_default_packages(self):
68+
self.assertEqual(
69+
ResourcePath.from_file_path(
70+
Path(sublime.executable_path()).parent.joinpath(
71+
'Packages', 'test_package.sublime-package', 'foo.py'
72+
)
73+
),
74+
ResourcePath("Packages/test_package/foo.py")
75+
)
76+
77+
def test_from_file_path_default_packages_root(self):
78+
self.assertEqual(
79+
ResourcePath.from_file_path(
80+
Path(sublime.executable_path()).parent / 'Packages'
81+
),
82+
ResourcePath("Packages")
83+
)
84+
4785
def test_from_file_path_error(self):
4886
with self.assertRaises(ValueError):
4987
ResourcePath.from_file_path(Path('/test_package')),

0 commit comments

Comments
 (0)