Merge lp:~sergiusens/snapcraft/1500902 into lp:~snappy-dev/snapcraft/core
- 1500902
- Merge into core
Proposed by
Sergio Schvezov
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Sergio Schvezov | ||||||||
Approved revision: | 249 | ||||||||
Merged at revision: | 236 | ||||||||
Proposed branch: | lp:~sergiusens/snapcraft/1500902 | ||||||||
Merge into: | lp:~snappy-dev/snapcraft/core | ||||||||
Diff against target: |
1329 lines (+398/-381) 33 files modified
plugins/ant.yaml (+0/-13) plugins/autotools.yaml (+0/-12) plugins/cmake.yaml (+0/-12) plugins/copy.yaml (+0/-6) plugins/go.yaml (+0/-10) plugins/jdk.yaml (+0/-2) plugins/make.yaml (+0/-10) plugins/maven.yaml (+0/-13) plugins/python2.yaml (+0/-11) plugins/python3.yaml (+0/-11) plugins/readline.yaml (+0/-3) plugins/scons.yaml (+0/-9) plugins/tar-content.yaml (+0/-6) setup.py (+0/-2) snapcraft/__init__.py (+47/-7) snapcraft/cmds.py (+7/-8) snapcraft/plugin.py (+106/-110) snapcraft/plugins/ant.py (+15/-5) snapcraft/plugins/autotools.py (+21/-2) snapcraft/plugins/cmake.py (+21/-6) snapcraft/plugins/copy.py (+13/-0) snapcraft/plugins/go.py (+15/-0) snapcraft/plugins/jdk.py (+3/-3) snapcraft/plugins/make.py (+4/-0) snapcraft/plugins/maven.py (+9/-1) snapcraft/plugins/python2.py (+19/-12) snapcraft/plugins/python3.py (+19/-12) snapcraft/plugins/qml.py (+41/-35) snapcraft/plugins/scons.py (+19/-5) snapcraft/plugins/tar_content.py (+13/-0) snapcraft/tests/test_cmds.py (+3/-3) snapcraft/tests/test_plugin.py (+18/-29) snapcraft/yaml.py (+5/-23) |
||||||||
To merge this branch: | bzr merge lp:~sergiusens/snapcraft/1500902 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Leo Arias (community) | Approve | ||
John Lenton (community) | Approve | ||
Review via email: mp+273444@code.launchpad.net |
Commit message
Plugin yaml's are obsolete
Description of the change
To post a comment you must log in.
lp:~sergiusens/snapcraft/1500902
updated
- 235. By Sergio Schvezov
-
Making stage-packages and build-packages regular attributes while polishing the phase in the lifecycle where it is handled
- 236. By Sergio Schvezov
-
Merging trunk
- 237. By Sergio Schvezov
-
Fix issues when using global dictionaries and plugin code polish
- 238. By Sergio Schvezov
-
The name belongs to the part, the other thing is just the plugin to use to handle it
- 239. By Sergio Schvezov
-
getattr--
- 240. By Sergio Schvezov
-
contextlib++
- 241. By Sergio Schvezov
-
More name changes
- 242. By Sergio Schvezov
-
Remove more PLUGIN_
BUILD_PACKAGES refs
Revision history for this message
Sergio Schvezov (sergiusens) wrote : | # |
OK, except for the docs, most of this the comments have been addressed.
lp:~sergiusens/snapcraft/1500902
updated
- 243. By Sergio Schvezov
-
options is here
- 244. By Sergio Schvezov
-
import jdk for maven plugin
- 245. By Sergio Schvezov
-
missing options for scons_options
- 246. By Sergio Schvezov
-
Remove _PLUGIN_
BUILD_PACKAGES from CMakePlugin - 247. By Sergio Schvezov
-
jsonschema support
Revision history for this message
John Lenton (chipaca) : | # |
review:
Approve
lp:~sergiusens/snapcraft/1500902
updated
- 248. By Sergio Schvezov
-
Removing plugins install logic from setup.py
Revision history for this message
Leo Arias (elopio) wrote : | # |
This cleans up almost everything I didn't like. Let's merge!
review:
Approve
lp:~sergiusens/snapcraft/1500902
updated
- 249. By Sergio Schvezov
-
Build packages for plugins
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed directory 'plugins' |
2 | === removed file 'plugins/ant.yaml' |
3 | --- plugins/ant.yaml 2015-10-01 08:54:15 +0000 |
4 | +++ plugins/ant.yaml 1970-01-01 00:00:00 +0000 |
5 | @@ -1,13 +0,0 @@ |
6 | -requires: |
7 | - - jdk |
8 | -options: |
9 | - source: |
10 | - required: true |
11 | - source-type: |
12 | - source-tag: |
13 | - source-branch: |
14 | - stage-packages: |
15 | - snap: |
16 | - stage: |
17 | -build-packages: |
18 | - - ant |
19 | |
20 | === removed file 'plugins/autotools.yaml' |
21 | --- plugins/autotools.yaml 2015-10-01 08:54:15 +0000 |
22 | +++ plugins/autotools.yaml 1970-01-01 00:00:00 +0000 |
23 | @@ -1,12 +0,0 @@ |
24 | -build-packages: [autoconf, automake, autopoint] |
25 | -options: |
26 | - source: |
27 | - required: true |
28 | - source-type: |
29 | - source-tag: |
30 | - source-branch: |
31 | - configflags: |
32 | - required: false |
33 | - stage-packages: |
34 | - snap: |
35 | - stage: |
36 | |
37 | === removed file 'plugins/cmake.yaml' |
38 | --- plugins/cmake.yaml 2015-10-01 08:54:15 +0000 |
39 | +++ plugins/cmake.yaml 1970-01-01 00:00:00 +0000 |
40 | @@ -1,12 +0,0 @@ |
41 | -build-packages: [cmake] |
42 | -options: |
43 | - source: |
44 | - required: true |
45 | - source-type: |
46 | - source-tag: |
47 | - source-branch: |
48 | - configflags: |
49 | - required: false |
50 | - stage-packages: |
51 | - snap: |
52 | - stage: |
53 | |
54 | === removed file 'plugins/copy.yaml' |
55 | --- plugins/copy.yaml 2015-09-08 18:06:03 +0000 |
56 | +++ plugins/copy.yaml 1970-01-01 00:00:00 +0000 |
57 | @@ -1,6 +0,0 @@ |
58 | -options: |
59 | - files: |
60 | - required: true |
61 | - stage-packages: |
62 | - snap: |
63 | - stage: |
64 | |
65 | === removed file 'plugins/go.yaml' |
66 | --- plugins/go.yaml 2015-10-01 08:54:15 +0000 |
67 | +++ plugins/go.yaml 1970-01-01 00:00:00 +0000 |
68 | @@ -1,10 +0,0 @@ |
69 | -build-packages: |
70 | - - golang-go |
71 | -options: |
72 | - source: |
73 | - required: true |
74 | - configflags: |
75 | - required: false |
76 | - stage-packages: |
77 | - snap: |
78 | - stage: |
79 | |
80 | === removed file 'plugins/jdk.yaml' |
81 | --- plugins/jdk.yaml 2015-10-08 18:08:29 +0000 |
82 | +++ plugins/jdk.yaml 1970-01-01 00:00:00 +0000 |
83 | @@ -1,2 +0,0 @@ |
84 | -build-packages: |
85 | - - ca-certificates-java |
86 | |
87 | === removed file 'plugins/make.yaml' |
88 | --- plugins/make.yaml 2015-10-01 08:54:15 +0000 |
89 | +++ plugins/make.yaml 1970-01-01 00:00:00 +0000 |
90 | @@ -1,10 +0,0 @@ |
91 | -build-packages: [make] |
92 | -options: |
93 | - source: |
94 | - required: true |
95 | - source-type: |
96 | - source-tag: |
97 | - source-branch: |
98 | - stage-packages: |
99 | - snap: |
100 | - stage: |
101 | |
102 | === removed file 'plugins/maven.yaml' |
103 | --- plugins/maven.yaml 2015-10-01 08:54:15 +0000 |
104 | +++ plugins/maven.yaml 1970-01-01 00:00:00 +0000 |
105 | @@ -1,13 +0,0 @@ |
106 | -build-packages: |
107 | - - maven |
108 | -requires: |
109 | - - jdk |
110 | -options: |
111 | - source: |
112 | - required: true |
113 | - source-type: |
114 | - source-tag: |
115 | - source-branch: |
116 | - stage-packages: |
117 | - snap: |
118 | - stage: |
119 | |
120 | === removed file 'plugins/python2.yaml' |
121 | --- plugins/python2.yaml 2015-10-01 08:54:15 +0000 |
122 | +++ plugins/python2.yaml 1970-01-01 00:00:00 +0000 |
123 | @@ -1,11 +0,0 @@ |
124 | -options: |
125 | - requirements: |
126 | - required: false |
127 | - source: |
128 | - required: false |
129 | - source-type: |
130 | - source-tag: |
131 | - source-branch: |
132 | - stage-packages: |
133 | - snap: |
134 | - stage: |
135 | |
136 | === removed file 'plugins/python3.yaml' |
137 | --- plugins/python3.yaml 2015-10-01 08:54:15 +0000 |
138 | +++ plugins/python3.yaml 1970-01-01 00:00:00 +0000 |
139 | @@ -1,11 +0,0 @@ |
140 | -options: |
141 | - requirements: |
142 | - required: false |
143 | - source: |
144 | - required: false |
145 | - source-type: |
146 | - source-tag: |
147 | - source-branch: |
148 | - stage-packages: |
149 | - snap: |
150 | - stage: |
151 | |
152 | === removed file 'plugins/qml.yaml' |
153 | === removed file 'plugins/readline.yaml' |
154 | --- plugins/readline.yaml 2015-10-01 08:54:15 +0000 |
155 | +++ plugins/readline.yaml 1970-01-01 00:00:00 +0000 |
156 | @@ -1,3 +0,0 @@ |
157 | -source: git://git.sv.gnu.org/readline.git |
158 | -requires: |
159 | - - autotools |
160 | |
161 | === removed file 'plugins/scons.yaml' |
162 | --- plugins/scons.yaml 2015-10-01 08:54:15 +0000 |
163 | +++ plugins/scons.yaml 1970-01-01 00:00:00 +0000 |
164 | @@ -1,9 +0,0 @@ |
165 | -build-packages: |
166 | - - scons |
167 | -options: |
168 | - source: |
169 | - required: true |
170 | - scons-options: |
171 | - source-type: |
172 | - source-tag: |
173 | - source-branch: |
174 | |
175 | === removed file 'plugins/tar-content.yaml' |
176 | --- plugins/tar-content.yaml 2015-09-22 03:08:07 +0000 |
177 | +++ plugins/tar-content.yaml 1970-01-01 00:00:00 +0000 |
178 | @@ -1,6 +0,0 @@ |
179 | -options: |
180 | - source: |
181 | - required: true |
182 | - stage-packages: |
183 | - snap: |
184 | - stage: |
185 | |
186 | === modified file 'setup.py' |
187 | --- setup.py 2015-10-02 09:13:00 +0000 |
188 | +++ setup.py 2015-10-13 15:27:09 +0000 |
189 | @@ -37,8 +37,6 @@ |
190 | package_data={'snapcraft': ['manifest.txt']}, |
191 | scripts=['bin/snapcraft'], |
192 | data_files=[ |
193 | - ('share/snapcraft/plugins', |
194 | - ['plugins/' + x for x in os.listdir('plugins')]), |
195 | ('share/snapcraft/schema', |
196 | ['schema/' + x for x in os.listdir('schema')]), |
197 | ], |
198 | |
199 | === modified file 'snapcraft/__init__.py' |
200 | --- snapcraft/__init__.py 2015-10-02 09:13:00 +0000 |
201 | +++ snapcraft/__init__.py 2015-10-13 15:27:09 +0000 |
202 | @@ -14,6 +14,7 @@ |
203 | # You should have received a copy of the GNU General Public License |
204 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
205 | |
206 | +import contextlib |
207 | import logging |
208 | import os |
209 | import re |
210 | @@ -28,9 +29,41 @@ |
211 | |
212 | class BasePlugin: |
213 | |
214 | - @property |
215 | - def PLUGIN_STAGE_PACKAGES(self): |
216 | - return getattr(self, '_PLUGIN_STAGE_PACKAGES', []) |
217 | + @classmethod |
218 | + def schema(cls): |
219 | + ''' |
220 | + Returns a json-schema for the plugin's properties as a dictionary. |
221 | + Of importance to plugin authors is the 'properties' keyword and |
222 | + optionally the 'requires' keyword with a list of required |
223 | + 'properties'. |
224 | + |
225 | + By default the the properties will be that of a standard VCS, override |
226 | + in custom implementations if required. |
227 | + ''' |
228 | + return { |
229 | + '$schema': 'http://json-schema.org/draft-04/schema#', |
230 | + 'type': 'object', |
231 | + 'properties': { |
232 | + 'source': { |
233 | + 'type': 'string', |
234 | + }, |
235 | + 'source-type': { |
236 | + 'type': 'string', |
237 | + 'default': '', |
238 | + }, |
239 | + 'source-branch': { |
240 | + 'type': 'string', |
241 | + 'default': '', |
242 | + }, |
243 | + 'source-tag': { |
244 | + 'type:': 'string', |
245 | + 'default': '', |
246 | + }, |
247 | + }, |
248 | + 'required': [ |
249 | + 'source', |
250 | + ] |
251 | + } |
252 | |
253 | @property |
254 | def PLUGIN_STAGE_SOURCES(self): |
255 | @@ -38,6 +71,14 @@ |
256 | |
257 | def __init__(self, name, options): |
258 | self.name = name |
259 | + self.build_packages = [] |
260 | + self.stage_packages = [] |
261 | + |
262 | + with contextlib.suppress(AttributeError): |
263 | + self.stage_packages = options.stage_packages |
264 | + with contextlib.suppress(AttributeError): |
265 | + self.build_packages = options.build_packages |
266 | + |
267 | self.options = options |
268 | self.partdir = os.path.join(os.getcwd(), "parts", self.name) |
269 | self.sourcedir = os.path.join(os.getcwd(), "parts", self.name, "src") |
270 | @@ -121,11 +162,10 @@ |
271 | os.makedirs(d, exist_ok=True) |
272 | |
273 | def setup_stage_packages(self): |
274 | - part_stage_packages = getattr(self.options, 'stage_packages', []) or [] |
275 | - if self.PLUGIN_STAGE_PACKAGES or part_stage_packages: |
276 | + if self.stage_packages: |
277 | ubuntu = snapcraft.repo.Ubuntu(self.ubuntudir, |
278 | sources=self.PLUGIN_STAGE_SOURCES) |
279 | - ubuntu.get(self.PLUGIN_STAGE_PACKAGES + part_stage_packages) |
280 | + ubuntu.get(self.stage_packages) |
281 | ubuntu.unpack(self.installdir) |
282 | self._fixup(self.installdir) |
283 | |
284 | @@ -143,7 +183,7 @@ |
285 | |
286 | |
287 | def _get_source_handler(source_type, source): |
288 | - if source_type is None: |
289 | + if not source_type: |
290 | source_type = _get_source_type_from_uri(source) |
291 | |
292 | if source_type == 'bzr': |
293 | |
294 | === modified file 'snapcraft/cmds.py' |
295 | --- snapcraft/cmds.py 2015-10-05 16:16:23 +0000 |
296 | +++ snapcraft/cmds.py 2015-10-13 15:27:09 +0000 |
297 | @@ -54,9 +54,8 @@ |
298 | if args.part: |
299 | yaml += 'parts:\n' |
300 | for part_name in args.part: |
301 | - part = snapcraft.plugin.load_plugin(part_name, part_name, |
302 | - load_code=False) |
303 | - yaml += ' ' + part.names()[0] + ':\n' |
304 | + part = snapcraft.plugin.load_plugin(part_name, part_name) |
305 | + yaml += ' ' + part.name + ':\n' |
306 | for opt in part.config.get('options', []): |
307 | if part.config['options'][opt].get('required', False): |
308 | yaml += ' ' + opt + ':\n' |
309 | @@ -241,7 +240,7 @@ |
310 | config = _load_config() |
311 | |
312 | for part in config.all_parts: |
313 | - logger.info('Cleaning up for part %r', part.names()[0]) |
314 | + logger.info('Cleaning up for part %r', part.name) |
315 | if os.path.exists(part.partdir): |
316 | shutil.rmtree(part.partdir) |
317 | |
318 | @@ -287,14 +286,14 @@ |
319 | 'paths in common which have different ' |
320 | 'contents:\n %s', |
321 | other_part_name, |
322 | - part.names()[0], |
323 | + part.name, |
324 | '\n '.join(sorted(conflict_files))) |
325 | |
326 | return False |
327 | |
328 | # And add our files to the list |
329 | - parts_files[part.names()[0]] = {'files': part_files, |
330 | - 'installdir': part.installdir} |
331 | + parts_files[part.name] = {'files': part_files, |
332 | + 'installdir': part.installdir} |
333 | |
334 | return True |
335 | |
336 | @@ -336,7 +335,7 @@ |
337 | force = forceAll or cmd == forceCommand |
338 | |
339 | if not getattr(part, cmd)(force=force): |
340 | - logger.error('Failed doing %s for %s!', cmd, part.names()[0]) |
341 | + logger.error('Failed doing %s for %s!', cmd, part.name) |
342 | sys.exit(1) |
343 | |
344 | |
345 | |
346 | === modified file 'snapcraft/plugin.py' |
347 | --- snapcraft/plugin.py 2015-10-05 16:56:10 +0000 |
348 | +++ snapcraft/plugin.py 2015-10-13 15:27:09 +0000 |
349 | @@ -14,13 +14,14 @@ |
350 | # You should have received a copy of the GNU General Public License |
351 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
352 | |
353 | +import contextlib |
354 | import glob |
355 | import importlib |
356 | +import jsonschema |
357 | import logging |
358 | import os |
359 | import sys |
360 | import shutil |
361 | -import yaml |
362 | |
363 | import snapcraft |
364 | from snapcraft import common |
365 | @@ -30,15 +31,6 @@ |
366 | logger = logging.getLogger(__name__) |
367 | |
368 | |
369 | -_BUILTIN_OPTIONS = { |
370 | - 'filesets': {}, |
371 | - 'snap': [], |
372 | - 'stage': [], |
373 | - 'stage-packages': [], |
374 | - 'organize': {} |
375 | -} |
376 | - |
377 | - |
378 | def _local_plugindir(): |
379 | return os.path.abspath(os.path.join('parts', 'plugins')) |
380 | |
381 | @@ -49,14 +41,16 @@ |
382 | |
383 | class PluginHandler: |
384 | |
385 | - def __init__(self, name, part_name, properties, load_code=True, |
386 | - load_config=True): |
387 | + @property |
388 | + def name(self): |
389 | + return self._name |
390 | + |
391 | + def __init__(self, plugin_name, part_name, properties): |
392 | self.valid = False |
393 | self.code = None |
394 | self.config = {} |
395 | - self.part_names = [] |
396 | + self._name = part_name |
397 | self.deps = [] |
398 | - self.plugin_name = name |
399 | |
400 | parts_dir = common.get_partsdir() |
401 | self.partdir = os.path.join(parts_dir, part_name) |
402 | @@ -69,78 +63,46 @@ |
403 | self.statefile = os.path.join(parts_dir, part_name, 'state') |
404 | |
405 | try: |
406 | - if load_config: |
407 | - self._load_config(name) |
408 | - if load_code: |
409 | - self._load_code(name, part_name, properties) |
410 | + self._load_code(plugin_name, properties) |
411 | # only set to valid if it loads without PluginError |
412 | - self.part_names.append(part_name) |
413 | self.valid = True |
414 | except PluginError as e: |
415 | logger.error(str(e)) |
416 | return |
417 | - |
418 | - def _load_config(self, name): |
419 | - config_path = os.path.join(common.get_plugindir(), name + ".yaml") |
420 | - if not os.path.exists(config_path): |
421 | - config_path = os.path.join(_local_plugindir(), name + ".yaml") |
422 | - if not os.path.exists(config_path): |
423 | - raise PluginError('Unknown plugin: {}'.format(name)) |
424 | - with open(config_path, 'r') as fp: |
425 | - self.config = yaml.load(fp) or {} |
426 | - |
427 | - def _make_options(self, name, properties): |
428 | - class Options(): |
429 | - pass |
430 | - options = Options() |
431 | - |
432 | - plugin_options = self.config.get('options', {}) |
433 | - # Let's append some mandatory options, but not .update() to not lose |
434 | - # original content |
435 | - for key in _BUILTIN_OPTIONS: |
436 | - if key not in plugin_options: |
437 | - plugin_options[key] = _BUILTIN_OPTIONS[key] |
438 | - |
439 | - for opt in plugin_options: |
440 | - attrname = opt.replace('-', '_') |
441 | - opt_parameters = plugin_options[opt] or {} |
442 | - if opt in properties: |
443 | - setattr(options, attrname, properties[opt]) |
444 | - else: |
445 | - if opt_parameters.get('required', False): |
446 | - raise PluginError('Required field {} missing on part {}'. |
447 | - format(opt, name)) |
448 | - setattr(options, attrname, None) |
449 | - |
450 | - return options |
451 | - |
452 | - def _load_code(self, name, part_name, properties): |
453 | - options = self._make_options(name, properties) |
454 | - module_name = name.replace('-', '_') |
455 | - |
456 | - try: |
457 | - module = importlib.import_module('snapcraft.plugins.' + |
458 | - module_name) |
459 | - except ImportError: |
460 | - module = None |
461 | - |
462 | - if not module: |
463 | - logger.info('Searching for local plugin for %s', name) |
464 | - sys.path = [_local_plugindir()] + sys.path |
465 | - module = importlib.import_module(module_name) |
466 | - sys.path.pop(0) |
467 | - |
468 | - for prop_name in dir(module): |
469 | - prop = getattr(module, prop_name) |
470 | - if issubclass(prop, snapcraft.BasePlugin): |
471 | - self.code = prop(part_name, options) |
472 | - break |
473 | + except jsonschema.ValidationError as e: |
474 | + logger.error('Issues while loading properties for ' |
475 | + '{}: {}'.format(part_name, e.message)) |
476 | + return |
477 | + |
478 | + def _load_code(self, plugin_name, properties): |
479 | + module_name = plugin_name.replace('-', '_') |
480 | + module = None |
481 | + |
482 | + with contextlib.suppress(ImportError): |
483 | + module = _load_local('x-{}'.format(plugin_name)) |
484 | + logger.info('Loaded local plugin for %s', plugin_name) |
485 | + |
486 | + if not module: |
487 | + with contextlib.suppress(ImportError): |
488 | + module = importlib.import_module( |
489 | + 'snapcraft.plugins.{}'.format(module_name)) |
490 | + |
491 | + if not module: |
492 | + logger.info('Searching for local plugin for %s', plugin_name) |
493 | + with contextlib.suppress(ImportError): |
494 | + module = _load_local(module_name) |
495 | + if not module: |
496 | + raise PluginError('Unknown plugin: {}'.format(plugin_name)) |
497 | + |
498 | + plugin = _get_plugin(module) |
499 | + options = _make_options(properties, plugin.schema()) |
500 | + self.code = plugin(self.name, options) |
501 | |
502 | def __str__(self): |
503 | - return self.part_names[0] |
504 | + return self.name |
505 | |
506 | def __repr__(self): |
507 | - return self.part_names[0] |
508 | + return self.name |
509 | |
510 | def makedirs(self): |
511 | dirs = [ |
512 | @@ -153,11 +115,8 @@ |
513 | def is_valid(self): |
514 | return self.valid |
515 | |
516 | - def names(self): |
517 | - return self.part_names |
518 | - |
519 | def notify_stage(self, stage, hint=''): |
520 | - logger.info(stage + " " + self.part_names[0] + hint) |
521 | + logger.info('%s %s %s', stage, self.name, hint) |
522 | |
523 | def is_dirty(self, stage): |
524 | try: |
525 | @@ -183,23 +142,16 @@ |
526 | return True |
527 | self.makedirs() |
528 | |
529 | - run_setup_stage_packages = self.code and \ |
530 | - hasattr(self.code, 'setup_stage_packages') |
531 | - run_pull = self.code and hasattr(self.code, 'pull') |
532 | - |
533 | - if run_setup_stage_packages or run_pull: |
534 | - self.notify_stage("Pulling") |
535 | - |
536 | - if run_setup_stage_packages: |
537 | - try: |
538 | - self.code.setup_stage_packages() |
539 | - except repo.PackageNotFoundError as e: |
540 | - logger.error(e.message) |
541 | - return False |
542 | - |
543 | - if run_pull: |
544 | - if not getattr(self.code, 'pull')(): |
545 | - return False |
546 | + self.notify_stage("Pulling") |
547 | + |
548 | + try: |
549 | + self.code.setup_stage_packages() |
550 | + except repo.PackageNotFoundError as e: |
551 | + logger.error(e.message) |
552 | + return False |
553 | + |
554 | + if not self.code.pull(): |
555 | + return False |
556 | |
557 | self.mark_done('pull') |
558 | return True |
559 | @@ -208,10 +160,9 @@ |
560 | if not self.should_stage_run('build', force): |
561 | return True |
562 | self.makedirs() |
563 | - if self.code and hasattr(self.code, 'build'): |
564 | - self.notify_stage("Building") |
565 | - if not getattr(self.code, 'build')(): |
566 | - return False |
567 | + self.notify_stage("Building") |
568 | + if not self.code.build(): |
569 | + return False |
570 | |
571 | self.mark_done('build') |
572 | return True |
573 | @@ -284,14 +235,59 @@ |
574 | return True |
575 | |
576 | def env(self, root): |
577 | - if self.code and hasattr(self.code, 'env'): |
578 | - return getattr(self.code, 'env')(root) |
579 | - return [] |
580 | - |
581 | - |
582 | -def load_plugin(part_name, plugin_name, properties={}, load_code=True): |
583 | - part = PluginHandler(plugin_name, part_name, properties, |
584 | - load_code=load_code) |
585 | + return self.code.env(root) |
586 | + |
587 | + |
588 | +def _builtin_options(): |
589 | + return { |
590 | + 'filesets': {}, |
591 | + 'snap': [], |
592 | + 'stage': [], |
593 | + 'stage-packages': [], |
594 | + 'build-packages': [], |
595 | + 'organize': {} |
596 | + } |
597 | + |
598 | + |
599 | +def _make_options(properties, schema): |
600 | + class Options(): |
601 | + pass |
602 | + options = Options() |
603 | + |
604 | + # Built in options are already validated |
605 | + builtin_options = _builtin_options() |
606 | + for key in builtin_options: |
607 | + value = properties.pop(key, builtin_options[key]) |
608 | + setattr(options, key.replace('-', '_'), value) |
609 | + |
610 | + jsonschema.validate(properties, schema) |
611 | + |
612 | + schema_properties = schema.get('properties', {}) |
613 | + for key in schema_properties: |
614 | + attr_name = key.replace('-', '_') |
615 | + default_value = schema_properties[key].get('default') |
616 | + attr_value = properties.get(key, default_value) |
617 | + setattr(options, attr_name, attr_value) |
618 | + |
619 | + return options |
620 | + |
621 | + |
622 | +def _get_plugin(module): |
623 | + for attr in vars(module).values(): |
624 | + if isinstance(attr, type) and issubclass(attr, snapcraft.BasePlugin): |
625 | + return attr |
626 | + |
627 | + |
628 | +def _load_local(module_name): |
629 | + sys.path = [_local_plugindir()] + sys.path |
630 | + module = importlib.import_module(module_name) |
631 | + sys.path.pop(0) |
632 | + |
633 | + return module |
634 | + |
635 | + |
636 | +def load_plugin(part_name, plugin_name, properties={}): |
637 | + part = PluginHandler(plugin_name, part_name, properties) |
638 | if not part.is_valid(): |
639 | logger.error('Could not load part %s', plugin_name) |
640 | sys.exit(1) |
641 | |
642 | === modified file 'snapcraft/plugins/ant.py' |
643 | --- snapcraft/plugins/ant.py 2015-10-02 09:13:00 +0000 |
644 | +++ snapcraft/plugins/ant.py 2015-10-13 15:27:09 +0000 |
645 | @@ -21,17 +21,24 @@ |
646 | |
647 | import snapcraft |
648 | import snapcraft.common |
649 | +import snapcraft.plugins.jdk |
650 | |
651 | |
652 | logger = logging.getLogger(__name__) |
653 | |
654 | |
655 | -class AntPlugin(snapcraft.BasePlugin): |
656 | +class AntPlugin(snapcraft.plugins.jdk.JdkPlugin): |
657 | + |
658 | + def __init__(self, name, options): |
659 | + super().__init__(name, options) |
660 | + self.build_packages.append('ant') |
661 | |
662 | def pull(self): |
663 | + super().pull() |
664 | return self.handle_source_options() |
665 | |
666 | def build(self): |
667 | + super().build() |
668 | if not self.run(['ant']): |
669 | return False |
670 | files = glob.glob(os.path.join(self.builddir, 'target', '*.jar')) |
671 | @@ -44,8 +51,11 @@ |
672 | self.run(['cp', '-a'] + files + [jardir]) |
673 | |
674 | def env(self, root): |
675 | + env = super().env(root) |
676 | jars = glob.glob(os.path.join(self.installdir, 'jar', '*.jar')) |
677 | - if not jars: |
678 | - return [] |
679 | - jars = [os.path.join(root, 'jar', os.path.basename(x)) for x in jars] |
680 | - return ['CLASSPATH=%s:$CLASSPATH' % ':'.join(jars)] |
681 | + if jars: |
682 | + jars = [os.path.join(root, 'jar', |
683 | + os.path.basename(x)) for x in jars] |
684 | + env.extend( |
685 | + ['CLASSPATH=%s:$CLASSPATH' % ':'.join(jars)]) |
686 | + return env |
687 | |
688 | === modified file 'snapcraft/plugins/autotools.py' |
689 | --- snapcraft/plugins/autotools.py 2015-10-02 09:13:00 +0000 |
690 | +++ snapcraft/plugins/autotools.py 2015-10-13 15:27:09 +0000 |
691 | @@ -19,10 +19,29 @@ |
692 | |
693 | |
694 | class AutotoolsPlugin(MakePlugin): |
695 | + |
696 | + @classmethod |
697 | + def schema(cls): |
698 | + schema = super().schema() |
699 | + schema['properties']['configflags'] = { |
700 | + 'type': 'array', |
701 | + 'minitems': 1, |
702 | + 'uniqueItems': True, |
703 | + 'items': { |
704 | + 'type': 'string', |
705 | + }, |
706 | + 'default': [], |
707 | + } |
708 | + |
709 | + return schema |
710 | + |
711 | def __init__(self, name, options): |
712 | super().__init__(name, options) |
713 | - if self.options.configflags is None: |
714 | - self.options.configflags = [] |
715 | + self.build_packages.extend([ |
716 | + 'autoconf', |
717 | + 'automake', |
718 | + 'autopoint', |
719 | + ]) |
720 | |
721 | def build(self): |
722 | if not os.path.exists(os.path.join(self.builddir, "configure")): |
723 | |
724 | === modified file 'snapcraft/plugins/cmake.py' |
725 | --- snapcraft/plugins/cmake.py 2015-10-02 09:13:00 +0000 |
726 | +++ snapcraft/plugins/cmake.py 2015-10-13 15:27:09 +0000 |
727 | @@ -14,14 +14,29 @@ |
728 | # You should have received a copy of the GNU General Public License |
729 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
730 | |
731 | -from snapcraft.plugins.make import MakePlugin |
732 | - |
733 | - |
734 | -class CMakePlugin(MakePlugin): |
735 | +import snapcraft.plugins.make |
736 | + |
737 | + |
738 | +class CMakePlugin(snapcraft.plugins.make.MakePlugin): |
739 | + |
740 | + @classmethod |
741 | + def schema(cls): |
742 | + schema = super().schema() |
743 | + schema['properties']['configflags'] = { |
744 | + 'type': 'array', |
745 | + 'minitems': 1, |
746 | + 'uniqueItems': True, |
747 | + 'items': { |
748 | + 'type': 'string', |
749 | + }, |
750 | + 'default': [], |
751 | + } |
752 | + |
753 | + return schema |
754 | + |
755 | def __init__(self, name, options): |
756 | super().__init__(name, options) |
757 | - if self.options.configflags is None: |
758 | - self.options.configflags = [] |
759 | + self.build_packages.append('cmake') |
760 | |
761 | def build(self): |
762 | return self.run(['cmake', '.', '-DCMAKE_INSTALL_PREFIX='] + |
763 | |
764 | === modified file 'snapcraft/plugins/copy.py' |
765 | --- snapcraft/plugins/copy.py 2015-10-02 09:13:00 +0000 |
766 | +++ snapcraft/plugins/copy.py 2015-10-13 15:27:09 +0000 |
767 | @@ -25,6 +25,19 @@ |
768 | |
769 | class CopyPlugin(snapcraft.BasePlugin): |
770 | |
771 | + @classmethod |
772 | + def schema(cls): |
773 | + return { |
774 | + 'properties': { |
775 | + 'files': { |
776 | + 'type': 'object', |
777 | + }, |
778 | + }, |
779 | + 'required': [ |
780 | + 'files', |
781 | + ] |
782 | + } |
783 | + |
784 | def build(self): |
785 | res = True |
786 | for src in sorted(self.options.files): |
787 | |
788 | === modified file 'snapcraft/plugins/go.py' |
789 | --- snapcraft/plugins/go.py 2015-10-02 09:13:00 +0000 |
790 | +++ snapcraft/plugins/go.py 2015-10-13 15:27:09 +0000 |
791 | @@ -20,8 +20,23 @@ |
792 | |
793 | class GoPlugin(snapcraft.BasePlugin): |
794 | |
795 | + @classmethod |
796 | + def schema(cls): |
797 | + return { |
798 | + 'properties': { |
799 | + 'source': { |
800 | + 'type': 'string', |
801 | + }, |
802 | + }, |
803 | + 'required': [ |
804 | + 'source', |
805 | + ] |
806 | + } |
807 | + |
808 | def __init__(self, name, options): |
809 | super().__init__(name, options) |
810 | + self.build_packages.append('golang-go') |
811 | + |
812 | if self.options.source.startswith("lp:"): |
813 | self.fullname = self.options.source.split(":~")[1] |
814 | else: |
815 | |
816 | === modified file 'snapcraft/plugins/jdk.py' |
817 | --- snapcraft/plugins/jdk.py 2015-09-09 19:41:36 +0000 |
818 | +++ snapcraft/plugins/jdk.py 2015-10-13 15:27:09 +0000 |
819 | @@ -19,9 +19,9 @@ |
820 | |
821 | class JdkPlugin(snapcraft.BasePlugin): |
822 | |
823 | - _PLUGIN_STAGE_PACKAGES = [ |
824 | - 'default-jdk', |
825 | - ] |
826 | + def __init__(self, name, options): |
827 | + super().__init__(name, options) |
828 | + self.stage_packages.append('default-jdk') |
829 | |
830 | def env(self, root): |
831 | return ['JAVA_HOME=%s/usr/lib/jvm/default-java' % root, |
832 | |
833 | === modified file 'snapcraft/plugins/make.py' |
834 | --- snapcraft/plugins/make.py 2015-10-01 08:54:15 +0000 |
835 | +++ snapcraft/plugins/make.py 2015-10-13 15:27:09 +0000 |
836 | @@ -19,6 +19,10 @@ |
837 | |
838 | class MakePlugin(snapcraft.BasePlugin): |
839 | |
840 | + def __init__(self, name, options): |
841 | + super().__init__(name, options) |
842 | + self.build_packages.append('make') |
843 | + |
844 | def pull(self): |
845 | return self.handle_source_options() |
846 | |
847 | |
848 | === modified file 'snapcraft/plugins/maven.py' |
849 | --- snapcraft/plugins/maven.py 2015-10-02 09:13:00 +0000 |
850 | +++ snapcraft/plugins/maven.py 2015-10-13 15:27:09 +0000 |
851 | @@ -20,17 +20,25 @@ |
852 | |
853 | import snapcraft |
854 | import snapcraft.common |
855 | +import snapcraft.plugins.jdk |
856 | |
857 | |
858 | logger = logging.getLogger(__name__) |
859 | |
860 | |
861 | -class MavenPlugin(snapcraft.BasePlugin): |
862 | +class MavenPlugin(snapcraft.plugins.jdk.JdkPlugin): |
863 | + |
864 | + def __init__(self, name, options): |
865 | + super().__init__(name, options) |
866 | + self.build_packages.append('maven') |
867 | |
868 | def pull(self): |
869 | + super().pull() |
870 | return self.handle_source_options() |
871 | |
872 | def build(self): |
873 | + super().build() |
874 | + |
875 | if not self.run(['mvn', 'package']): |
876 | return False |
877 | jarfiles = glob.glob(os.path.join(self.builddir, 'target', '*.jar')) |
878 | |
879 | === modified file 'snapcraft/plugins/python2.py' |
880 | --- snapcraft/plugins/python2.py 2015-10-02 09:13:00 +0000 |
881 | +++ snapcraft/plugins/python2.py 2015-10-13 15:27:09 +0000 |
882 | @@ -22,23 +22,30 @@ |
883 | |
884 | class Python2Plugin(snapcraft.BasePlugin): |
885 | |
886 | - _PLUGIN_STAGE_PACKAGES = [ |
887 | - 'python-dev', |
888 | - 'python-pkg-resources', |
889 | - 'python-setuptools', |
890 | - ] |
891 | + @classmethod |
892 | + def schema(cls): |
893 | + schema = super().schema() |
894 | + schema['properties']['requirements'] = { |
895 | + 'type': 'string', |
896 | + } |
897 | + schema.pop('required') |
898 | + |
899 | + return schema |
900 | |
901 | def __init__(self, name, options): |
902 | super().__init__(name, options) |
903 | - self.requirements = options.requirements |
904 | - self.source = options.source |
905 | + self.stage_packages.extend([ |
906 | + 'python-dev', |
907 | + 'python-pkg-resources', |
908 | + 'python-setuptools', |
909 | + ]) |
910 | |
911 | def env(self, root): |
912 | return ["PYTHONPATH=%s" % os.path.join( |
913 | root, 'usr', 'lib', self.python_version, 'dist-packages')] |
914 | |
915 | def pull(self): |
916 | - if self.source and not self.handle_source_options(): |
917 | + if self.options.source and not self.handle_source_options(): |
918 | return False |
919 | |
920 | return self._pip() |
921 | @@ -48,10 +55,10 @@ |
922 | if os.listdir(self.sourcedir): |
923 | setup = os.path.join(self.sourcedir, 'setup.py') |
924 | |
925 | - if self.requirements: |
926 | - requirements = os.path.join(os.getcwd(), self.requirements) |
927 | + if self.options.requirements: |
928 | + requirements = os.path.join(os.getcwd(), self.options.requirements) |
929 | |
930 | - if not os.path.exists(setup) and not self.requirements: |
931 | + if not os.path.exists(setup) and not self.options.requirements: |
932 | return True |
933 | |
934 | easy_install = os.path.join( |
935 | @@ -73,7 +80,7 @@ |
936 | pip_install = ['python2', pip2, 'install', '--target', |
937 | site_packages_dir] |
938 | |
939 | - if self.requirements and not self.run( |
940 | + if self.options.requirements and not self.run( |
941 | pip_install + ['--requirement', requirements]): |
942 | return False |
943 | |
944 | |
945 | === modified file 'snapcraft/plugins/python3.py' |
946 | --- snapcraft/plugins/python3.py 2015-10-05 16:16:23 +0000 |
947 | +++ snapcraft/plugins/python3.py 2015-10-13 15:27:09 +0000 |
948 | @@ -22,23 +22,30 @@ |
949 | |
950 | class Python3Plugin(snapcraft.BasePlugin): |
951 | |
952 | - _PLUGIN_STAGE_PACKAGES = [ |
953 | - 'python3-dev', |
954 | - 'python3-pkg-resources', |
955 | - 'python3-setuptools', |
956 | - ] |
957 | + @classmethod |
958 | + def schema(cls): |
959 | + schema = super().schema() |
960 | + schema['properties']['requirements'] = { |
961 | + 'type': 'string', |
962 | + } |
963 | + schema.pop('required') |
964 | + |
965 | + return schema |
966 | |
967 | def __init__(self, name, options): |
968 | super().__init__(name, options) |
969 | - self.requirements = options.requirements |
970 | - self.source = options.source |
971 | + self.stage_packages.extend([ |
972 | + 'python3-dev', |
973 | + 'python3-pkg-resources', |
974 | + 'python3-setuptools', |
975 | + ]) |
976 | |
977 | def env(self, root): |
978 | return ["PYTHONPATH=%s" % os.path.join( |
979 | root, 'usr', 'lib', self.python_version, 'dist-packages')] |
980 | |
981 | def pull(self): |
982 | - if self.source and not self.handle_source_options(): |
983 | + if self.options.source and not self.handle_source_options(): |
984 | return False |
985 | |
986 | return self._pip() |
987 | @@ -48,10 +55,10 @@ |
988 | if os.listdir(self.sourcedir): |
989 | setup = os.path.join(self.sourcedir, 'setup.py') |
990 | |
991 | - if self.requirements: |
992 | - requirements = os.path.join(os.getcwd(), self.requirements) |
993 | + if self.options.requirements: |
994 | + requirements = os.path.join(os.getcwd(), self.options.requirements) |
995 | |
996 | - if not os.path.exists(setup) and not self.requirements: |
997 | + if not os.path.exists(setup) and not self.options.requirements: |
998 | return True |
999 | |
1000 | easy_install = os.path.join( |
1001 | @@ -72,7 +79,7 @@ |
1002 | pip_install = ['python3', pip3, 'install', '--target', |
1003 | site_packages_dir] |
1004 | |
1005 | - if self.requirements and not self.run( |
1006 | + if self.options.requirements and not self.run( |
1007 | pip_install + ['--requirement', requirements]): |
1008 | return False |
1009 | |
1010 | |
1011 | === modified file 'snapcraft/plugins/qml.py' |
1012 | --- snapcraft/plugins/qml.py 2015-10-02 09:13:00 +0000 |
1013 | +++ snapcraft/plugins/qml.py 2015-10-13 15:27:09 +0000 |
1014 | @@ -21,41 +21,47 @@ |
1015 | |
1016 | class QmlPlugin(snapcraft.BasePlugin): |
1017 | |
1018 | - _PLUGIN_STAGE_PACKAGES = [ |
1019 | - "qmlscene", |
1020 | - "qtdeclarative5-qtmir-plugin", |
1021 | - "mir-graphics-drivers-desktop", |
1022 | - "qtubuntu-desktop", |
1023 | - "ttf-ubuntu-font-family", |
1024 | - # if there's a metapackage for these, please swap it in here: |
1025 | - "qml-module-qt-labs-folderlistmodel", |
1026 | - "qml-module-qt-labs-settings", |
1027 | - "qml-module-qt-websockets", |
1028 | - "qml-module-qtfeedback", |
1029 | - "qml-module-qtgraphicaleffects", |
1030 | - "qml-module-qtlocation", |
1031 | - "qml-module-qtmultimedia", |
1032 | - "qml-module-qtorganizer", |
1033 | - "qml-module-qtpositioning", |
1034 | - "qml-module-qtqml-models2", |
1035 | - "qml-module-qtqml-statemachine", |
1036 | - "qml-module-qtquick-controls", |
1037 | - "qml-module-qtquick-dialogs", |
1038 | - "qml-module-qtquick-layouts", |
1039 | - "qml-module-qtquick-localstorage", |
1040 | - "qml-module-qtquick-particles2", |
1041 | - "qml-module-qtquick-privatewidgets", |
1042 | - "qml-module-qtquick-window2", |
1043 | - "qml-module-qtquick-xmllistmodel", |
1044 | - "qml-module-qtquick2", |
1045 | - "qml-module-qtsensors", |
1046 | - "qml-module-qtsysteminfo", |
1047 | - "qml-module-qttest", |
1048 | - "qml-module-qtwebkit", |
1049 | - "qml-module-ubuntu-connectivity", |
1050 | - "qml-module-ubuntu-onlineaccounts", |
1051 | - "qml-module-ubuntu-onlineaccounts-client", |
1052 | - ] |
1053 | + @classmethod |
1054 | + def schema(cls): |
1055 | + return {} |
1056 | + |
1057 | + def __init__(self, name, options): |
1058 | + super().__init__(name, options) |
1059 | + self.stage_packages.extend([ |
1060 | + "qmlscene", |
1061 | + "qtdeclarative5-qtmir-plugin", |
1062 | + "mir-graphics-drivers-desktop", |
1063 | + "qtubuntu-desktop", |
1064 | + "ttf-ubuntu-font-family", |
1065 | + # if there's a metapackage for these, please swap it in here: |
1066 | + "qml-module-qt-labs-folderlistmodel", |
1067 | + "qml-module-qt-labs-settings", |
1068 | + "qml-module-qt-websockets", |
1069 | + "qml-module-qtfeedback", |
1070 | + "qml-module-qtgraphicaleffects", |
1071 | + "qml-module-qtlocation", |
1072 | + "qml-module-qtmultimedia", |
1073 | + "qml-module-qtorganizer", |
1074 | + "qml-module-qtpositioning", |
1075 | + "qml-module-qtqml-models2", |
1076 | + "qml-module-qtqml-statemachine", |
1077 | + "qml-module-qtquick-controls", |
1078 | + "qml-module-qtquick-dialogs", |
1079 | + "qml-module-qtquick-layouts", |
1080 | + "qml-module-qtquick-localstorage", |
1081 | + "qml-module-qtquick-particles2", |
1082 | + "qml-module-qtquick-privatewidgets", |
1083 | + "qml-module-qtquick-window2", |
1084 | + "qml-module-qtquick-xmllistmodel", |
1085 | + "qml-module-qtquick2", |
1086 | + "qml-module-qtsensors", |
1087 | + "qml-module-qtsysteminfo", |
1088 | + "qml-module-qttest", |
1089 | + "qml-module-qtwebkit", |
1090 | + "qml-module-ubuntu-connectivity", |
1091 | + "qml-module-ubuntu-onlineaccounts", |
1092 | + "qml-module-ubuntu-onlineaccounts-client", |
1093 | + ]) |
1094 | |
1095 | def snap_fileset(self): |
1096 | return ['*', |
1097 | |
1098 | === modified file 'snapcraft/plugins/scons.py' |
1099 | --- snapcraft/plugins/scons.py 2015-10-01 08:54:15 +0000 |
1100 | +++ snapcraft/plugins/scons.py 2015-10-13 15:27:09 +0000 |
1101 | @@ -21,11 +21,24 @@ |
1102 | |
1103 | class SconsPlugin(snapcraft.BasePlugin): |
1104 | |
1105 | + @classmethod |
1106 | + def schema(cls): |
1107 | + schema = super().schema() |
1108 | + schema['properties']['scons-options'] = { |
1109 | + 'type': 'array', |
1110 | + 'minitems': 1, |
1111 | + 'uniqueItems': True, |
1112 | + 'items': { |
1113 | + 'type': 'string', |
1114 | + }, |
1115 | + 'default': [] |
1116 | + } |
1117 | + |
1118 | + return schema |
1119 | + |
1120 | def __init__(self, name, options): |
1121 | super().__init__(name, options) |
1122 | - self.scons_options = [] |
1123 | - if options.scons_options: |
1124 | - self.scons_options = options.scons_options |
1125 | + self.build_packages.append('scons') |
1126 | |
1127 | def pull(self): |
1128 | return self.handle_source_options() |
1129 | @@ -33,5 +46,6 @@ |
1130 | def build(self): |
1131 | env = os.environ.copy() |
1132 | env['DESTDIR'] = self.installdir |
1133 | - return (self.run(['scons', ] + self.scons_options) and |
1134 | - self.run(['scons', 'install'] + self.scons_options, env=env)) |
1135 | + return (self.run(['scons', ] + self.options.scons_options) and |
1136 | + self.run(['scons', 'install'] + |
1137 | + self.options.scons_options, env=env)) |
1138 | |
1139 | === modified file 'snapcraft/plugins/tar_content.py' |
1140 | --- snapcraft/plugins/tar_content.py 2015-08-31 13:49:40 +0000 |
1141 | +++ snapcraft/plugins/tar_content.py 2015-10-13 15:27:09 +0000 |
1142 | @@ -20,6 +20,19 @@ |
1143 | |
1144 | class TarContentPlugin(snapcraft.BasePlugin): |
1145 | |
1146 | + @classmethod |
1147 | + def schema(cls): |
1148 | + return { |
1149 | + 'properties': { |
1150 | + 'source': { |
1151 | + 'type': 'string', |
1152 | + }, |
1153 | + }, |
1154 | + 'required': [ |
1155 | + 'source', |
1156 | + ] |
1157 | + } |
1158 | + |
1159 | def __init__(self, name, options): |
1160 | super().__init__(name, options) |
1161 | self.tar = snapcraft.sources.Tar(self.options.source, self.builddir) |
1162 | |
1163 | === modified file 'snapcraft/tests/test_cmds.py' |
1164 | --- snapcraft/tests/test_cmds.py 2015-10-02 09:13:00 +0000 |
1165 | +++ snapcraft/tests/test_cmds.py 2015-10-13 15:27:09 +0000 |
1166 | @@ -39,14 +39,14 @@ |
1167 | tmpdir = tmpdirObject.name |
1168 | |
1169 | part1 = mock.Mock() |
1170 | - part1.names.return_value = ['part1'] |
1171 | + part1.name = 'part1' |
1172 | part1.code.options.stage = ['*'] |
1173 | part1.installdir = tmpdir + '/install1' |
1174 | os.makedirs(part1.installdir + '/a') |
1175 | open(part1.installdir + '/a/1', mode='w').close() |
1176 | |
1177 | part2 = mock.Mock() |
1178 | - part2.names.return_value = ['part2'] |
1179 | + part2.name = 'part2' |
1180 | part2.code.options.stage = ['*'] |
1181 | part2.installdir = tmpdir + '/install2' |
1182 | os.makedirs(part2.installdir + '/a') |
1183 | @@ -57,7 +57,7 @@ |
1184 | f.write('a/2') |
1185 | |
1186 | part3 = mock.Mock() |
1187 | - part3.names.return_value = ['part3'] |
1188 | + part3.name = 'part3' |
1189 | part3.code.options.stage = ['*'] |
1190 | part3.installdir = tmpdir + '/install3' |
1191 | os.makedirs(part3.installdir + '/a') |
1192 | |
1193 | === modified file 'snapcraft/tests/test_plugin.py' |
1194 | --- snapcraft/tests/test_plugin.py 2015-10-02 09:13:00 +0000 |
1195 | +++ snapcraft/tests/test_plugin.py 2015-10-13 15:27:09 +0000 |
1196 | @@ -28,16 +28,12 @@ |
1197 | plugin, |
1198 | tests |
1199 | ) |
1200 | -from snapcraft.tests import mock_plugin |
1201 | - |
1202 | - |
1203 | -def get_test_plugin(name='mock', part_name='mock-part', |
1204 | - properties=None, load_code=False, load_config=False): |
1205 | + |
1206 | + |
1207 | +def get_test_plugin(name='mock', part_name='mock-part', properties=None): |
1208 | if properties is None: |
1209 | properties = {} |
1210 | - return plugin.PluginHandler( |
1211 | - name, part_name, properties, load_code=load_code, |
1212 | - load_config=load_config) |
1213 | + return plugin.PluginHandler(name, part_name, properties) |
1214 | |
1215 | |
1216 | class PluginTestCase(tests.TestCase): |
1217 | @@ -46,7 +42,7 @@ |
1218 | fake_logger = fixtures.FakeLogger(level=logging.ERROR) |
1219 | self.useFixture(fake_logger) |
1220 | |
1221 | - get_test_plugin('test_unexisting_name', load_config=True) |
1222 | + get_test_plugin('test_unexisting_name') |
1223 | |
1224 | self.assertEqual( |
1225 | 'Unknown plugin: test_unexisting_name\n', fake_logger.output) |
1226 | @@ -202,24 +198,18 @@ |
1227 | |
1228 | self.assertEqual(expected, result) |
1229 | |
1230 | - def test_notify_stage_must_log_information(self): |
1231 | - fake_logger = fixtures.FakeLogger(level=logging.INFO) |
1232 | - self.useFixture(fake_logger) |
1233 | - |
1234 | - p = get_test_plugin() |
1235 | - p.notify_stage('test stage') |
1236 | - |
1237 | - self.assertEqual('test stage mock-part\n', fake_logger.output) |
1238 | - |
1239 | - def test_non_local_plugins(self): |
1240 | - """Ensure regular plugins are loaded from snapcraft only""" |
1241 | - def mock_import_modules(module_name): |
1242 | - # called with the full snapcraft path |
1243 | - self.assertEqual(module_name, "snapcraft.plugins.mock") |
1244 | - return mock_plugin |
1245 | - with patch("importlib.import_module", side_effect=mock_import_modules): |
1246 | - plugin.PluginHandler( |
1247 | - "mock", "mock-part", {}, load_config=False, load_code=True) |
1248 | + @patch('importlib.import_module') |
1249 | + @patch('snapcraft.plugin._load_local') |
1250 | + @patch('snapcraft.plugin._get_plugin') |
1251 | + def test_non_local_plugins(self, plugin_mock, |
1252 | + local_load_mock, import_mock): |
1253 | + mock_plugin = Mock() |
1254 | + mock_plugin.schema.return_value = {} |
1255 | + plugin_mock.return_value = mock_plugin |
1256 | + local_load_mock.side_effect = ImportError() |
1257 | + plugin.PluginHandler('mock', 'mock-part', {}) |
1258 | + import_mock.assert_called_with('snapcraft.plugins.mock') |
1259 | + local_load_mock.assert_called_with('x-mock') |
1260 | |
1261 | def test_filesets_includes_without_relative_paths(self): |
1262 | with self.assertRaises(plugin.PluginError) as raised: |
1263 | @@ -240,8 +230,7 @@ |
1264 | self.useFixture(fake_logger) |
1265 | |
1266 | with self.assertRaises(SystemExit) as raised: |
1267 | - plugin.load_plugin( |
1268 | - 'dummy-part', 'test_unexisting_name', load_code=False) |
1269 | + plugin.load_plugin('dummy-part', 'test_unexisting_name') |
1270 | |
1271 | self.assertEqual(raised.exception.code, 1, 'Wrong exit code returned.') |
1272 | self.assertEqual( |
1273 | |
1274 | === modified file 'snapcraft/yaml.py' |
1275 | --- snapcraft/yaml.py 2015-10-05 16:56:10 +0000 |
1276 | +++ snapcraft/yaml.py 2015-10-13 15:27:09 +0000 |
1277 | @@ -129,36 +129,19 @@ |
1278 | |
1279 | self.load_plugin(part_name, plugin_name, properties) |
1280 | |
1281 | - self._load_missing_part_plugins() |
1282 | self._compute_part_dependencies(after_requests) |
1283 | self.all_parts = self._sort_parts() |
1284 | |
1285 | - def _load_missing_part_plugins(self): |
1286 | - new_parts = self.all_parts.copy() |
1287 | - while new_parts: |
1288 | - part = new_parts.pop(0) |
1289 | - requires = part.config.get('requires', []) |
1290 | - for required_part in requires: |
1291 | - present = False |
1292 | - for p in self.all_parts: |
1293 | - if required_part in p.names(): |
1294 | - present = True |
1295 | - break |
1296 | - if not present: |
1297 | - new_parts.append(self.load_plugin(required_part, |
1298 | - required_part, {})) |
1299 | - |
1300 | def _compute_part_dependencies(self, after_requests): |
1301 | '''Gather the lists of dependencies and adds to all_parts.''' |
1302 | w = snapcraft.wiki.Wiki() |
1303 | |
1304 | for part in self.all_parts: |
1305 | - dep_names = part.config.get('requires', []) + \ |
1306 | - after_requests.get(part.names()[0], []) |
1307 | + dep_names = after_requests.get(part.name, []) |
1308 | for dep in dep_names: |
1309 | found = False |
1310 | for i in range(len(self.all_parts)): |
1311 | - if dep in self.all_parts[i].names(): |
1312 | + if dep in self.all_parts[i].name: |
1313 | part.deps.append(self.all_parts[i]) |
1314 | found = True |
1315 | break |
1316 | @@ -195,11 +178,10 @@ |
1317 | |
1318 | return sorted_parts |
1319 | |
1320 | - def load_plugin(self, part_name, plugin_name, properties, load_code=True): |
1321 | - part = snapcraft.plugin.load_plugin(part_name, plugin_name, |
1322 | - properties, load_code=load_code) |
1323 | + def load_plugin(self, part_name, plugin_name, properties): |
1324 | + part = snapcraft.plugin.load_plugin(part_name, plugin_name, properties) |
1325 | |
1326 | - self.build_tools += part.config.get('build-packages', []) |
1327 | + self.build_tools += part.code.build_packages |
1328 | self.all_parts.append(part) |
1329 | return part |
1330 |
A couple of style comments inline.
This change makes sense, because now we don't split the plugins into a python and a yaml file. But I think we need to spend some time cleaning and documenting the api of the parent base plugin. Clearly mark things that are internals, constants and things that are to be extended by children. And write nice sphinxed docs.