Skip to content

Commit cdda572

Browse files
committed
Added support for a dependencies.json file
This should make development easier for package developers since they do not need to rely on creating a repository.json file with the dependencies for their Sublime Text install to have the appropriate dependencies.
1 parent e306c12 commit cdda572

File tree

3 files changed

+96
-17
lines changed

3 files changed

+96
-17
lines changed

dependencies.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"windows": {
3+
"<3000": [
4+
"select-windows",
5+
"ssl-windows",
6+
"bz2"
7+
]
8+
},
9+
"linux": {
10+
"*": [
11+
"ssl-linux",
12+
"bz2"
13+
]
14+
},
15+
"*": {
16+
"*": [
17+
"bz2"
18+
]
19+
}
20+
}

package_control/package_cleanup.py

+20-5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def run(self):
3737
found_dependencies = []
3838

3939
installed_packages = list(self.original_installed_packages)
40+
installed_dependencies = list(self.original_installed_dependencies)
4041

4142
for package_name in os.listdir(sublime.packages_path()):
4243
found = True
@@ -161,13 +162,20 @@ def show_still_locked():
161162
invalid_packages = []
162163
invalid_dependencies = []
163164

164-
# Check metadata to verify packages were not improperly installed
165+
# Check metadata to verify packages were not improperly installed, and
166+
# also make sure we have all dependencies we need
165167
for package in found_packages:
166168
if package == 'User':
167169
continue
170+
168171
metadata = self.manager.get_metadata(package)
169-
if metadata and not self.is_compatible(metadata):
170-
invalid_packages.append(package)
172+
if metadata:
173+
if not self.is_compatible(metadata):
174+
invalid_packages.append(package)
175+
176+
for dependency in self.manager.get_dependencies(package):
177+
if dependency not in installed_dependencies:
178+
installed_dependencies.append(dependency)
171179

172180
for dependency in found_dependencies:
173181
metadata = self.manager.get_metadata(dependency, is_dependency=True)
@@ -198,7 +206,7 @@ def show_sync_error():
198206
show_error(message)
199207
sublime.set_timeout(show_sync_error, 100)
200208

201-
sublime.set_timeout(lambda: self.finish(installed_packages, found_packages, found_dependencies), 10)
209+
sublime.set_timeout(lambda: self.finish(installed_packages, installed_dependencies, found_packages, found_dependencies), 10)
202210

203211
def is_compatible(self, metadata):
204212
"""
@@ -237,7 +245,7 @@ def is_compatible(self, metadata):
237245

238246
return True
239247

240-
def finish(self, installed_packages, found_packages, found_dependencies):
248+
def finish(self, installed_packages, installed_dependencies, found_packages, found_dependencies):
241249
"""
242250
A callback that can be run the main UI thread to perform saving of the
243251
Package Control.sublime-settings file. Also fires off the
@@ -247,6 +255,10 @@ def finish(self, installed_packages, found_packages, found_dependencies):
247255
A list of the string package names of all "installed" packages,
248256
even ones that do not appear to be in the filesystem.
249257
258+
:param installed_dependencies:
259+
A list of the string dependency names of all "installed"
260+
dependencies, even ones that do not appear to be in the filesystem.
261+
250262
:param found_packages:
251263
A list of the string package names of all packages that are
252264
currently installed on the filesystem.
@@ -276,6 +288,9 @@ def finish(self, installed_packages, found_packages, found_dependencies):
276288
save_list_setting(settings, filename, 'ignored_packages', new_ignored, ignored)
277289
save_list_setting(pc_settings, pc_filename, 'in_process_packages', [])
278290

291+
save_list_setting(pc_settings, pc_filename, 'installed_dependencies',
292+
installed_dependencies, self.original_installed_dependencies)
293+
279294
save_list_setting(pc_settings, pc_filename, 'installed_packages',
280295
installed_packages, self.original_installed_packages)
281296
AutomaticUpgrader(found_packages, found_dependencies).start()

package_control/package_manager.py

+56-12
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@
3939
from .clients.client_exception import ClientException
4040
from .download_manager import downloader
4141
from .providers.channel_provider import ChannelProvider
42-
from .providers.release_selector import filter_releases
42+
from .providers.release_selector import filter_releases, is_compatible_version
4343
from .upgraders.git_upgrader import GitUpgrader
4444
from .upgraders.hg_upgrader import HgUpgrader
45-
from .package_io import read_package_file
45+
from .package_io import read_package_file, package_file_exists
4646
from .providers import CHANNEL_PROVIDERS, REPOSITORY_PROVIDERS
4747
from .settings import pc_settings_filename, load_list_setting, save_list_setting
4848
from .versions import version_comparable
@@ -165,6 +165,58 @@ def get_metadata(self, package, is_dependency=False):
165165

166166
return {}
167167

168+
def get_dependencies(self, package):
169+
"""
170+
Returns a list of dependencies for the specified package on the
171+
current machine
172+
173+
:param package:
174+
The name of the package
175+
176+
:return:
177+
A list of dependency names
178+
"""
179+
180+
try:
181+
debug = self.settings.get('debug')
182+
if not package_file_exists(package, 'dependencies.json'):
183+
raise ValueError()
184+
185+
dep_info_json = read_package_file(package, 'dependencies.json', debug=debug)
186+
if not dep_info_json:
187+
raise ValueError()
188+
189+
dep_info = json.loads(dep_info_json)
190+
platform_selectors = [sublime.platform() + '-' + sublime.arch(),
191+
sublime.platform(), '*']
192+
193+
for platform_selector in platform_selectors:
194+
if platform_selector not in dep_info:
195+
continue
196+
197+
platform_dep_info = dep_info[platform_selector]
198+
versions = platform_dep_info.keys()
199+
200+
# Sorting reverse will give us >, < then *
201+
for version_selector in sorted(versions, reverse=True):
202+
if not is_compatible_version(version_selector):
203+
continue
204+
return platform_dep_info[version_selector]
205+
206+
# If there were no matches in dependencies.json, but there also
207+
# weren't any errors, then it just means there are not dependencies
208+
# for this machine
209+
return []
210+
211+
except (IOError, ValueError) as e:
212+
pass
213+
214+
metadata = self.get_metadata(package)
215+
if metadata:
216+
return metadata.get('dependencies', [])
217+
218+
return []
219+
168220
def list_repositories(self):
169221
"""
170222
Returns a master list of all repositories pulled from all sources
@@ -477,20 +529,12 @@ def find_required_dependencies(self, ignore_package):
477529
A list of the dependencies required by the installed packages
478530
"""
479531

480-
output = ['0_package_control_loader', 'bz2']
481-
482-
# Hard-code Package Control deps by os/plat
483-
if os.name == 'nt' and sys.version_info < (3,):
484-
output.extend(['ssl-windows', 'select-windows'])
485-
486-
if sublime.platform() == 'linux':
487-
output.append('ssl-linux')
532+
output = ['0_package_control_loader']
488533

489534
for package in self.list_packages():
490535
if package == ignore_package:
491536
continue
492-
metadata = self.get_metadata(package)
493-
output.extend(metadata.get('dependencies', []))
537+
output.extend(self.get_dependencies(package))
494538

495539
output = list(set(output))
496540
return sorted(output, key=lambda s: s.lower())

0 commit comments

Comments
 (0)