Skip to content

Commit a111b76

Browse files
committed
Provide the ability to have platform specific paths in settings
Resolves #183
1 parent 8564059 commit a111b76

4 files changed

Lines changed: 176 additions & 3 deletions

File tree

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,30 @@ Your .project file should look something like this:
152152

153153
Of course this is a example to apply Drupal code sniffer. This could be anything. Whatever you can have on this package settings it can be overwritten under the settings -> phpcs
154154

155+
### Multi-Platform Settings
156+
157+
If you use this plugin across multiple operating systems (e.g. syncing settings between Windows and Linux), you can specify platform-specific values for any path setting by using a dictionary instead of a string. The supported platform keys are `"windows"`, `"linux"`, and `"osx"`. You can also specify a `"default"` key as a fallback for platforms not explicitly listed.
158+
159+
```json
160+
{
161+
"phpcs_executable_path": {
162+
"windows": "c:\\xampp\\php\\bin\\phpcs",
163+
"linux": "/usr/bin/phpcs",
164+
"osx": "/usr/local/bin/phpcs"
165+
},
166+
"php_cs_fixer_executable_path": {
167+
"windows": "c:\\xampp\\php\\bin\\php-cs-fixer",
168+
"default": "/usr/local/bin/php-cs-fixer"
169+
},
170+
"phpcs_php_prefix_path": {
171+
"windows": "c:\\xampp\\php\\bin\\php",
172+
"default": ""
173+
}
174+
}
175+
```
176+
177+
This works for all path settings: `phpcs_executable_path`, `phpcs_php_prefix_path`, `phpcs_php_path`, `php_cs_fixer_executable_path`, `phpcbf_executable_path`, and `phpmd_executable_path`. Plain string values continue to work as before.
178+
155179
## FAQ
156180

157181
### What do I do when I get "OSError: [Errno 8] Exec format error"?

phpcs.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,28 @@ def load(self):
7575

7676
def get(self, key):
7777
if key in self.project_settings:
78-
return self.project_settings.get(key)
78+
raw = self.project_settings.get(key)
7979
else:
80-
return self.settings.get(key)
80+
raw = self.settings.get(key)
81+
return self._resolve_platform_value(raw)
82+
83+
def _resolve_platform_value(self, value):
84+
"""
85+
If value is a dict, resolve it to the value for the current platform.
86+
Supports keys: "osx", "linux", "windows", and "default" as a fallback.
87+
If value is not a dict, return it as-is for backward compatibility.
88+
"""
89+
if isinstance(value, dict) and any(
90+
k in value for k in ("osx", "linux", "windows", "default")
91+
):
92+
platform = sublime.platform()
93+
if platform in value:
94+
return value[platform]
95+
elif "default" in value:
96+
return value["default"]
97+
else:
98+
return ""
99+
return value
81100

82101
def set(self, key, value):
83102
if key in self.project_settings:

phpcs.sublime-settings

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@
3333
// The path to the php executable.
3434
// Needed for windows, or anyone who doesn't/can't make phars
3535
// executable. Avoid setting this if at all possible
36+
//
37+
// You can use a dictionary to specify different paths per platform:
38+
// "phpcs_php_prefix_path": {
39+
// "windows": "c:\\xampp\\php\\bin\\php",
40+
// "linux": "/usr/bin/php",
41+
// "osx": "/usr/local/bin/php"
42+
// }
3643
"phpcs_php_prefix_path": "",
3744

3845
// Options include:
@@ -61,6 +68,13 @@
6168

6269
// It seems python/sublime cannot always find the phpcs application
6370
// If empty, then use PATH version of phpcs, else use the set value
71+
//
72+
// You can use a dictionary to specify different paths per platform:
73+
// "phpcs_executable_path": {
74+
// "windows": "c:\\xampp\\php\\bin\\phpcs",
75+
// "linux": "/usr/bin/phpcs",
76+
// "osx": "/usr/local/bin/phpcs"
77+
// }
6478
"phpcs_executable_path": "",
6579

6680
// Additional arguments you can specify into the application
@@ -84,6 +98,13 @@
8498
"php_cs_fixer_show_quick_panel": false,
8599

86100
// Path to where you have the php-cs-fixer installed
101+
//
102+
// You can use a dictionary to specify different paths per platform:
103+
// "php_cs_fixer_executable_path": {
104+
// "windows": "c:\\xampp\\php\\bin\\php-cs-fixer",
105+
// "linux": "/usr/local/bin/php-cs-fixer",
106+
// "osx": "/usr/local/bin/php-cs-fixer"
107+
// }
87108
"php_cs_fixer_executable_path": "",
88109

89110
// Additional arguments you can specify into the application
@@ -98,6 +119,13 @@
98119
"phpcbf_show_quick_panel": false,
99120

100121
// Path to where you have the phpcbf installed
122+
//
123+
// You can use a dictionary to specify different paths per platform:
124+
// "phpcbf_executable_path": {
125+
// "windows": "c:\\xampp\\php\\bin\\phpcbf",
126+
// "linux": "/usr/local/bin/phpcbf",
127+
// "osx": "/usr/local/bin/phpcbf"
128+
// }
101129
"phpcbf_executable_path": "",
102130

103131
// Additional arguments you can specify into the application
@@ -121,6 +149,13 @@
121149

122150
// It seems python/sublime cannot always find the php application
123151
// If empty, then use PATH version of php, else use the set value
152+
//
153+
// You can use a dictionary to specify different paths per platform:
154+
// "phpcs_php_path": {
155+
// "windows": "c:\\xampp\\php\\bin\\php",
156+
// "linux": "/usr/bin/php",
157+
// "osx": "/usr/local/bin/php"
158+
// }
124159
"phpcs_php_path": "",
125160

126161
// What is the regex for the linter? Has to provide a named match for 'message' and 'line'
@@ -136,6 +171,13 @@
136171

137172
// It seems python/sublime cannot always find the phpmd application
138173
// If empty, then use PATH version of phpmd, else use the set value
174+
//
175+
// You can use a dictionary to specify different paths per platform:
176+
// "phpmd_executable_path": {
177+
// "windows": "c:\\xampp\\php\\bin\\phpmd",
178+
// "linux": "/usr/local/bin/phpmd",
179+
// "osx": "/usr/local/bin/phpmd"
180+
// }
139181
"phpmd_executable_path": "",
140182

141183
// Additional arguments you can specify into the application

tests/test_phpcs.py

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import sublime
55

6-
from Phpcs.phpcs import Sniffer
6+
from Phpcs.phpcs import Pref, Sniffer
77

88

99
class TestSniffer(TestCase):
@@ -37,3 +37,91 @@ def test_we_can_parse_phpcs_standards_output(self, shell_mock):
3737
expected = ["One", "NeutronStandard", "Two", "Three"]
3838

3939
self.assertEqual(expected, standards)
40+
41+
42+
class TestPrefPlatformResolution(TestCase):
43+
def setUp(self):
44+
self.pref = Pref()
45+
46+
def test_string_value_passes_through_unchanged(self):
47+
result = self.pref._resolve_platform_value("/usr/bin/phpcs")
48+
self.assertEqual("/usr/bin/phpcs", result)
49+
50+
def test_empty_string_passes_through_unchanged(self):
51+
result = self.pref._resolve_platform_value("")
52+
self.assertEqual("", result)
53+
54+
def test_non_platform_dict_passes_through_unchanged(self):
55+
value = {"--standard": "PSR2", "-n": ""}
56+
result = self.pref._resolve_platform_value(value)
57+
self.assertEqual(value, result)
58+
59+
@patch("Phpcs.phpcs.sublime.platform", return_value="osx")
60+
def test_dict_resolves_to_osx_value(self, _):
61+
value = {
62+
"windows": "c:\\xampp\\php\\bin\\phpcs",
63+
"linux": "/usr/bin/phpcs",
64+
"osx": "/usr/local/bin/phpcs",
65+
}
66+
result = self.pref._resolve_platform_value(value)
67+
self.assertEqual("/usr/local/bin/phpcs", result)
68+
69+
@patch("Phpcs.phpcs.sublime.platform", return_value="linux")
70+
def test_dict_resolves_to_linux_value(self, _):
71+
value = {
72+
"windows": "c:\\xampp\\php\\bin\\phpcs",
73+
"linux": "/usr/bin/phpcs",
74+
"osx": "/usr/local/bin/phpcs",
75+
}
76+
result = self.pref._resolve_platform_value(value)
77+
self.assertEqual("/usr/bin/phpcs", result)
78+
79+
@patch("Phpcs.phpcs.sublime.platform", return_value="windows")
80+
def test_dict_resolves_to_windows_value(self, _):
81+
value = {
82+
"windows": "c:\\xampp\\php\\bin\\phpcs",
83+
"linux": "/usr/bin/phpcs",
84+
"osx": "/usr/local/bin/phpcs",
85+
}
86+
result = self.pref._resolve_platform_value(value)
87+
self.assertEqual("c:\\xampp\\php\\bin\\phpcs", result)
88+
89+
@patch("Phpcs.phpcs.sublime.platform", return_value="osx")
90+
def test_dict_falls_back_to_default_when_platform_missing(self, _):
91+
value = {
92+
"windows": "c:\\xampp\\php\\bin\\phpcs",
93+
"default": "/usr/bin/phpcs",
94+
}
95+
result = self.pref._resolve_platform_value(value)
96+
self.assertEqual("/usr/bin/phpcs", result)
97+
98+
@patch("Phpcs.phpcs.sublime.platform", return_value="osx")
99+
def test_dict_returns_empty_string_when_platform_and_default_missing(self, _):
100+
value = {
101+
"windows": "c:\\xampp\\php\\bin\\phpcs",
102+
"linux": "/usr/bin/phpcs",
103+
}
104+
result = self.pref._resolve_platform_value(value)
105+
self.assertEqual("", result)
106+
107+
@patch("Phpcs.phpcs.sublime.platform", return_value="linux")
108+
def test_dict_prefers_platform_over_default(self, _):
109+
value = {
110+
"linux": "/usr/bin/phpcs",
111+
"default": "/opt/phpcs",
112+
}
113+
result = self.pref._resolve_platform_value(value)
114+
self.assertEqual("/usr/bin/phpcs", result)
115+
116+
def test_none_value_passes_through(self):
117+
result = self.pref._resolve_platform_value(None)
118+
self.assertIsNone(result)
119+
120+
def test_list_value_passes_through(self):
121+
value = ["Sniffer", "Fixer"]
122+
result = self.pref._resolve_platform_value(value)
123+
self.assertEqual(["Sniffer", "Fixer"], result)
124+
125+
def test_boolean_value_passes_through(self):
126+
result = self.pref._resolve_platform_value(True)
127+
self.assertTrue(result)

0 commit comments

Comments
 (0)