Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: recipe_engine/doc.py

Issue 1344583003: Recipe package system. (Closed) Base URL: git@github.com:luci/recipes-py.git@master
Patch Set: Recompiled proto Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « recipe_engine/config_types.py ('k') | recipe_engine/lint_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 from __future__ import print_function
7
8 import collections
9 import inspect
10 import os
11 import sys
12
13 from . import loader
14 from . import run as recipe_run
15 from . import package
16 from . import recipe_api
17
18 def trim_doc(docstring):
19 """From PEP 257"""
20 if not docstring:
21 return ''
22 # Convert tabs to spaces (following the normal Python rules)
23 # and split into a list of lines:
24 lines = docstring.expandtabs().splitlines()
25 # Determine minimum indentation (first line doesn't count):
26 indent = sys.maxint
27 for line in lines[1:]:
28 stripped = line.lstrip()
29 if stripped:
30 indent = min(indent, len(line) - len(stripped))
31 # Remove indentation (first line is special):
32 trimmed = [lines[0].strip()]
33 if indent < sys.maxint:
34 for line in lines[1:]:
35 trimmed.append(line[indent:].rstrip())
36 # Strip off trailing and leading blank lines:
37 while trimmed and not trimmed[-1]:
38 trimmed.pop()
39 while trimmed and not trimmed[0]:
40 trimmed.pop(0)
41 return trimmed
42
43 def member_iter(obj):
44 for name in sorted(dir(obj)):
45 if name[0] == '_' and name != '__call__':
46 continue
47 # Check class first to avoid calling property functions.
48 if hasattr(obj.__class__, name):
49 val = getattr(obj.__class__, name)
50 if callable(val) or isinstance(val, property):
51 yield name, val
52 else:
53 val = getattr(obj, name)
54 if callable(val) or inspect.ismodule(val):
55 yield name, val
56
57 def map_to_cool_name(typ):
58 if typ is collections.Mapping:
59 return 'Mapping'
60 return typ
61
62 def p(indent_lvl, *args, **kwargs):
63 sys.stdout.write(' '*indent_lvl)
64 print(*args, **kwargs)
65
66 def pmethod(indent_lvl, name, obj):
67 if isinstance(obj, property):
68 name = '@'+name
69 if obj.fset:
70 name += '(r/w)'
71 p(indent_lvl, name, '', end='')
72 if obj.__doc__:
73 lines = trim_doc(obj.__doc__)
74 p(0, '--', lines[0])
75 else:
76 p(0)
77
78 def main(package_deps):
79 common_methods = set(k for k, v in member_iter(recipe_api.RecipeApi))
80 p(0, 'Common Methods -- %s' % os.path.splitext(recipe_api.__file__)[0])
81 for method in sorted(common_methods):
82 pmethod(1, method, getattr(recipe_api.RecipeApi, method))
83
84 universe = loader.RecipeUniverse(package_deps)
85 deps = universe.deps_from_spec(
86 # TODO(luqui): This doesn't handle name scoping correctly (e.g. same-named
87 # modules in different packages).
88 { modpath: modpath.split('/')[-1]
89 for modpath in universe.loop_over_recipe_modules() })
90
91 inst = loader.create_recipe_api(
92 deps, recipe_run.RecipeEngine(None, {}, None))
93
94 for mod_name, mod in deps.iteritems():
95 p(0)
96 p(0, "(%s) -- %s" % (mod_name, mod.__path__[0]))
97 if mod.LOADED_DEPS:
98 p(1, 'DEPS:', list(mod.LOADED_DEPS))
99
100 subinst = getattr(inst, mod_name)
101 bases = set(subinst.__class__.__bases__)
102 base_fns = set()
103 for base in bases:
104 for name, _ in inspect.getmembers(base):
105 base_fns.add(name)
106 for cool_base in bases - set((recipe_api.RecipeApi,)):
107 p(1, 'behaves like %s' % map_to_cool_name(cool_base))
108
109 if mod.API.__doc__:
110 for line in trim_doc(mod.API.__doc__):
111 p(2, '"', line)
112
113 for fn_name, obj in member_iter(subinst):
114 if fn_name in base_fns:
115 continue
116 pmethod(1, fn_name, obj)
OLDNEW
« no previous file with comments | « recipe_engine/config_types.py ('k') | recipe_engine/lint_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698