|
1 |
|
2 # Developing GCLI |
|
3 |
|
4 ## About the code |
|
5 |
|
6 The majority of the GCLI source is stored in the ``lib`` directory. |
|
7 |
|
8 The ``docs`` directory contains documentation. |
|
9 The ``scripts`` directory contains RequireJS that GCLI uses. |
|
10 The ``build`` directory contains files used when creating builds. |
|
11 The ``mozilla`` directory contains the mercurial patch queue of patches to apply |
|
12 to mozilla-central. |
|
13 The ``selenium-tests`` directory contains selenium web-page integration tests. |
|
14 |
|
15 The source in the ``lib`` directory is split into 4 sections: |
|
16 |
|
17 - ``lib/demo`` contains commands used in the demo page. It is not needed except |
|
18 for demo purposes. |
|
19 - ``lib/test`` contains a small test harness for testing GCLI. |
|
20 - ``lib/gclitest`` contains tests that run in the test harness |
|
21 - ``lib/gcli`` contains the actual meat |
|
22 |
|
23 GCLI is split into a UI portion and a Model/Controller portion. |
|
24 |
|
25 |
|
26 ## The GCLI Model |
|
27 |
|
28 The heart of GCLI is a ``Requisition``, which is an AST for the input. A |
|
29 ``Requisition`` is a command that we'd like to execute, and we're filling out |
|
30 all the inputs required to execute the command. |
|
31 |
|
32 A ``Requisition`` has a ``Command`` that is to be executed. Each Command has a |
|
33 number of ``Parameter``s, each of which has a name and a type as detailed |
|
34 above. |
|
35 |
|
36 As you type, your input is split into ``Argument``s, which are then assigned to |
|
37 ``Parameter``s using ``Assignment``s. Each ``Assignment`` has a ``Conversion`` |
|
38 which stores the input argument along with the value that is was converted into |
|
39 according to the type of the parameter. |
|
40 |
|
41 There are special assignments called ``CommandAssignment`` which the |
|
42 ``Requisition`` uses to link to the command to execute, and |
|
43 ``UnassignedAssignment``used to store arguments that do not have a parameter |
|
44 to be assigned to. |
|
45 |
|
46 |
|
47 ## The GCLI UI |
|
48 |
|
49 There are several components of the GCLI UI. Each can have a script portion, |
|
50 some template HTML and a CSS file. The template HTML is processed by |
|
51 ``domtemplate`` before use. |
|
52 |
|
53 DomTemplate is fully documented in [it's own repository] |
|
54 (https://github.com/joewalker/domtemplate). |
|
55 |
|
56 The components are: |
|
57 |
|
58 - ``Inputter`` controls the input field, processing special keyboard events and |
|
59 making sure that it stays in sync with the Requisition. |
|
60 - ``Completer`` updates a div that is located behind the input field and used |
|
61 to display completion advice and hint highlights. It is stored in |
|
62 completer.js. |
|
63 - ``Display`` is responsible for containing the popup hints that are displayed |
|
64 above the command line. Typically Display contains a Hinter and a RequestsView |
|
65 although these are not both required. Display itself is optional, and isn't |
|
66 planned for use in the first release of GCLI in Firefox. |
|
67 - ``Hinter`` Is used to display input hints. It shows either a Menu or an |
|
68 ArgFetch component depending on the state of the Requisition |
|
69 - ``Menu`` is used initially to select the command to be executed. It can act |
|
70 somewhat like the Start menu on windows. |
|
71 - ``ArgFetch`` Once the command to be executed has been selected, ArgFetch |
|
72 shows a 'dialog' allowing the user to enter the parameters to the selected |
|
73 command. |
|
74 - ``RequestsView`` Contains a set of ``RequestView`` components, each of which |
|
75 displays a command that has been invoked. RequestsView is a poor name, and |
|
76 should better be called ReportView |
|
77 |
|
78 ArgFetch displays a number of Fields. There are fields for most of the Types |
|
79 discussed earlier. See 'Writing Fields' above for more information. |
|
80 |
|
81 |
|
82 ## Testing |
|
83 |
|
84 GCLI contains 2 test suites: |
|
85 |
|
86 - JS level testing is run with the ``test`` command. The tests are located in |
|
87 ``lib/gclitest`` and they use the test runner in ``lib/test``. This is fairly |
|
88 comprehensive, however it does not do UI level testing. |
|
89 If writing a new test it needs to be registered in ``lib/gclitest/index``. |
|
90 For an example of how to write tests, see ``lib/gclitest/testSplit.js``. |
|
91 The test functions are implemented in ``lib/test/assert``. |
|
92 - Browser integration tests are included in ``browser_webconsole_gcli_*.js``, |
|
93 in ``toolkit/components/console/hudservice/tests/browser``. These are |
|
94 run with the rest of the Mozilla test suite. |
|
95 |
|
96 |
|
97 ## Coding Conventions |
|
98 |
|
99 The coding conventions for the GCLI project come from the Bespin/Skywriter and |
|
100 Ace projects. They are roughly [Crockford] |
|
101 (http://javascript.crockford.com/code.html) with a few exceptions and |
|
102 additions: |
|
103 |
|
104 * ``var`` does not need to be at the top of each function, we'd like to move |
|
105 to ``let`` when it's generally available, and ``let`` doesn't have the same |
|
106 semantic twists as ``var``. |
|
107 |
|
108 * Strings are generally enclosed in single quotes. |
|
109 |
|
110 * ``eval`` is to be avoided, but we don't declare it evil. |
|
111 |
|
112 The [Google JavaScript conventions] |
|
113 (https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml) are |
|
114 more detailed, we tend to deviate in: |
|
115 |
|
116 * Custom exceptions: We generally just use ``throw new Error('message');`` |
|
117 |
|
118 * Multi-level prototype hierarchies: Allowed; we don't have ``goog.inherits()`` |
|
119 |
|
120 * ``else`` begins on a line by itself: |
|
121 |
|
122 if (thing) { |
|
123 doThis(); |
|
124 } |
|
125 else { |
|
126 doThat(); |
|
127 } |
|
128 |
|
129 |
|
130 ## Startup |
|
131 |
|
132 Internally GCLI modules have ``startup()``/``shutdown()`` functions which are |
|
133 called on module init from the top level ``index.js`` of that 'package'. |
|
134 |
|
135 In order to initialize a package all that is needed is to require the package |
|
136 index (e.g. ``require('package/index')``). |
|
137 |
|
138 The ``shutdown()`` function was useful when GCLI was used in Bespin as part of |
|
139 dynamic registration/de-registration. It is not known if this feature will be |
|
140 useful in the future. So it has not been entirely removed, it may be at some |
|
141 future date. |
|
142 |
|
143 |
|
144 ## Running the Unit Tests |
|
145 |
|
146 Start the GCLI static server: |
|
147 |
|
148 cd path/to/gcli |
|
149 node gcli.js |
|
150 |
|
151 Now point your browser to http://localhost:9999/localtest.html. When the page |
|
152 loads the tests will be automatically run outputting to the console, or you can |
|
153 enter the ``test`` command to run the unit tests. |
|
154 |
|
155 |
|
156 ## Contributing Code |
|
157 |
|
158 Please could you do the following to help minimize the amount of rework that we |
|
159 do: |
|
160 |
|
161 1. Check the unit tests run correctly (see **Running the Unit Tests** above) |
|
162 2. Check the code follows the style guide. At a minimum it should look like the |
|
163 code around it. For more detailed notes, see **Coding Conventions** above |
|
164 3. Help me review your work by using good commit comments. Which means 2 things |
|
165 * Well formatted messages, i.e. 50 char summary including bug tag, followed |
|
166 by a blank line followed by a more in-depth message wrapped to 72 chars |
|
167 per line. This is basically the format used by the Linux Kernel. See the |
|
168 [commit log](https://github.com/joewalker/gcli/commits/master) for |
|
169 examples. The be extra helpful, please use the "shortdesc-BUGNUM: " if |
|
170 possible which also helps in reviews. |
|
171 * Commit your changes as a story. Make it easy for me to understand the |
|
172 changes that you've made. |
|
173 4. Sign your work. To improve tracking of who did what, we follow the sign-off |
|
174 procedure used in the Linux Kernel. |
|
175 The sign-off is a simple line at the end of the explanation for the |
|
176 patch, which certifies that you wrote it or otherwise have the right to |
|
177 pass it on as an open-source patch. The rules are pretty simple: if you |
|
178 can certify the below: |
|
179 |
|
180 Developer's Certificate of Origin 1.1 |
|
181 |
|
182 By making a contribution to this project, I certify that: |
|
183 |
|
184 (a) The contribution was created in whole or in part by me and I |
|
185 have the right to submit it under the open source license |
|
186 indicated in the file; or |
|
187 |
|
188 (b) The contribution is based upon previous work that, to the best |
|
189 of my knowledge, is covered under an appropriate open source |
|
190 license and I have the right under that license to submit that |
|
191 work with modifications, whether created in whole or in part |
|
192 by me, under the same open source license (unless I am |
|
193 permitted to submit under a different license), as indicated |
|
194 in the file; or |
|
195 |
|
196 (c) The contribution was provided directly to me by some other |
|
197 person who certified (a), (b) or (c) and I have not modified |
|
198 it. |
|
199 |
|
200 (d) I understand and agree that this project and the contribution |
|
201 are public and that a record of the contribution (including all |
|
202 personal information I submit with it, including my sign-off) is |
|
203 maintained indefinitely and may be redistributed consistent with |
|
204 this project or the open source license(s) involved. |
|
205 |
|
206 then you just add a line saying |
|
207 |
|
208 Signed-off-by: Random J Developer <random@developer.example.org> |
|
209 |
|
210 using your real name (sorry, no pseudonyms or anonymous contributions.) |
|
211 |
|
212 Thanks for wanting to contribute code. |
|
213 |