Change monospace text formatting
Summary: Using `##` can cause some formatting issues, see D13071. Test Plan: See D13071. Reviewers: epriestley, #blessed_reviewers, chad Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin, epriestley Differential Revision: https://secure.phabricator.com/D13072
This commit is contained in:
		| @@ -18,8 +18,7 @@ To add a new CSS or JS file, create it in an appropriate location in | ||||
| `webroot/rsrc/css/` or `webroot/rsrc/js/` inside your `phabricator/` | ||||
| directory. | ||||
|  | ||||
| Each file must ##@provides## itself as a component, declared in a header | ||||
| comment: | ||||
| Each file must `@provides` itself as a component, declared in a header comment: | ||||
|  | ||||
|   LANG=css | ||||
|   /** | ||||
|   | ||||
| @@ -37,7 +37,7 @@ can use them to access different debugging and performance features. | ||||
| = Plugin: Error Log = | ||||
|  | ||||
| The "Error Log" plugin shows errors that occurred while generating the page, | ||||
| similar to the httpd ##error.log##. You can send information to the error log | ||||
| similar to the httpd `error.log`. You can send information to the error log | ||||
| explicitly with the @{function@libphutil:phlog} function. | ||||
|  | ||||
| If errors occurred, a red dot will appear on the plugin tab. | ||||
|   | ||||
| @@ -18,9 +18,9 @@ guidelines, you can probably get away with skimming this document. | ||||
|  | ||||
|   - Use two spaces for indentation. Don't use literal tab characters. | ||||
|   - Use Unix linebreaks ("\n"), not MSDOS ("\r\n") or OS9 ("\r"). | ||||
|   - Put a space after control keywords like ##if## and ##for##. | ||||
|   - Put a space after control keywords like `if` and `for`. | ||||
|   - Put a space after commas in argument lists. | ||||
|   - Put space around operators like ##=##, ##<##, etc. | ||||
|   - Put space around operators like `=`, `<`, etc. | ||||
|   - Don't put spaces after function names. | ||||
|   - Parentheses should hug their contents. | ||||
|   - Generally, prefer to wrap code at 80 columns. | ||||
| @@ -30,26 +30,26 @@ guidelines, you can probably get away with skimming this document. | ||||
| The Javascript language unambiguously dictates casing/naming rules; follow those | ||||
| rules. | ||||
|  | ||||
|   - Name variables using ##lowercase_with_underscores##. | ||||
|   - Name classes using ##UpperCamelCase##. | ||||
|   - Name methods and properties using ##lowerCamelCase##. | ||||
|   - Name global functions using ##lowerCamelCase##. Avoid defining global | ||||
|   - Name variables using `lowercase_with_underscores`. | ||||
|   - Name classes using `UpperCamelCase`. | ||||
|   - Name methods and properties using `lowerCamelCase`. | ||||
|   - Name global functions using `lowerCamelCase`. Avoid defining global | ||||
|     functions. | ||||
|   - Name constants using ##UPPERCASE##. | ||||
|   - Write ##true##, ##false##, and ##null## in lowercase. | ||||
|   - Name constants using `UPPERCASE`. | ||||
|   - Write `true`, `false`, and `null` in lowercase. | ||||
|   - "Internal" methods and properties should be prefixed with an underscore. | ||||
|     For more information about what "internal" means, see | ||||
|     **Leading Underscores**, below. | ||||
|  | ||||
| = Comments = | ||||
|  | ||||
|   - Strongly prefer ##//## comments for making comments inside the bodies of | ||||
|   - Strongly prefer `//` comments for making comments inside the bodies of | ||||
|     functions and methods (this lets someone easily comment out a block of code | ||||
|     while debugging later). | ||||
|  | ||||
| = Javascript Language = | ||||
|  | ||||
|   - Use ##[]## and ##{}##, not ##new Array## and ##new Object##. | ||||
|   - Use `[]` and `{}`, not `new Array` and `new Object`. | ||||
|   - When creating an object literal, do not quote keys unless required. | ||||
|  | ||||
| = Examples = | ||||
| @@ -66,7 +66,7 @@ rules. | ||||
|   } | ||||
|  | ||||
| You should always put braces around the body of an if clause, even if it is only | ||||
| one line. Note that operators like ##>## and ##===## are also surrounded by | ||||
| one line. Note that operators like `>` and `===` are also surrounded by | ||||
| spaces. | ||||
|  | ||||
| **for (iteration):** | ||||
| @@ -107,10 +107,10 @@ see @{article:Javascript Object and Array}. | ||||
|   } | ||||
|  | ||||
| `break` statements should be indented to block level. If you don't push them | ||||
| in, you end up with an inconsistent rule for conditional ##break## statements, | ||||
| as in the ##2## case. | ||||
| in, you end up with an inconsistent rule for conditional `break` statements, | ||||
| as in the `2` case. | ||||
|  | ||||
| If you insist on having a "fall through" case that does not end with ##break##, | ||||
| If you insist on having a "fall through" case that does not end with `break`, | ||||
| make it clear in a comment that you wrote this intentionally. For instance: | ||||
|  | ||||
|   lang=js | ||||
|   | ||||
| @@ -14,11 +14,11 @@ The N+1 query problem is a common performance antipattern. It looks like this: | ||||
|     // ... | ||||
|   } | ||||
|  | ||||
| Assuming ##load_cats()## has an implementation that boils down to: | ||||
| Assuming `load_cats()` has an implementation that boils down to: | ||||
|  | ||||
|   SELECT * FROM cat WHERE ... | ||||
|  | ||||
| ..and ##load_hats_for_cat($cat)## has an implementation something like this: | ||||
| ..and `load_hats_for_cat($cat)` has an implementation something like this: | ||||
|  | ||||
|   SELECT * FROM hat WHERE catID = ... | ||||
|  | ||||
|   | ||||
| @@ -20,21 +20,21 @@ most of its code in standardized subdirectories and classes. | ||||
|  | ||||
| = Best Practice Class and Subdirectory Organization = | ||||
|  | ||||
| Suppose you were working on the application ##Derp##. | ||||
| Suppose you were working on the application `Derp`. | ||||
|  | ||||
|   phabricator/src/applications/derp/ | ||||
|  | ||||
| If ##Derp## were as simple as possible, it would have one subdirectory: | ||||
| If `Derp` were as simple as possible, it would have one subdirectory: | ||||
|  | ||||
|   phabricator/src/applications/derp/controller/ | ||||
|  | ||||
| containing the file ##DerpController.php## with the class | ||||
| containing the file `DerpController.php` with the class | ||||
|  | ||||
|  - ##DerpController##: minimally implements a ##processRequest()## method | ||||
|  - `DerpController`: minimally implements a `processRequest()` method | ||||
|    which returns some @{class:AphrontResponse} object. The class would probably | ||||
|    extend @{class:PhabricatorController}. | ||||
|  | ||||
| If ##Derp## were (relatively) complex, one could reasonably expect to see | ||||
| If `Derp` were (relatively) complex, one could reasonably expect to see | ||||
| the following directory layout: | ||||
|  | ||||
|   phabricator/src/applications/derp/conduit/ | ||||
| @@ -54,54 +54,54 @@ this document. See @{article:Adding New CSS and JS}.) | ||||
|   phabricator/webroot/rsrc/js/application/derp/ | ||||
|   phabricator/webroot/rsrc/css/application/derp/ | ||||
|  | ||||
| These directories under ##phabricator/src/applications/derp/## represent | ||||
| These directories under `phabricator/src/applications/derp/` represent | ||||
| the basic set of class types from which most Phabrictor applications are | ||||
| assembled. Each would contain a class file. For ##Derp##, these classes could be | ||||
| assembled. Each would contain a class file. For `Derp`, these classes could be | ||||
| something like: | ||||
|  | ||||
|  - **DerpConstants**: constants used in the ##Derp## application. | ||||
|  - **DerpConstants**: constants used in the `Derp` application. | ||||
|  - **DerpController**: business logic providing functionality for a given | ||||
|    URI. Typically, controllers load data via Storage or Query classes, then | ||||
|    present the data to the user via one or more View classes. | ||||
|  - **DerpEditor**:  business logic for workflows that change one or more | ||||
|    Storage objects. Editor classes are only necessary for particularly | ||||
|    complicated edits and should be used pragmatically versus Storage objects. | ||||
|  - **DerpException**: exceptions used in the ##Derp## application. | ||||
|  - **DerpQuery**: query one or more storage objects for pertinent ##Derp## | ||||
|  - **DerpException**: exceptions used in the `Derp` application. | ||||
|  - **DerpQuery**: query one or more storage objects for pertinent `Derp` | ||||
|    application data. @{class:PhabricatorOffsetPagedQuery} is particularly | ||||
|    handy for pagination and works well with @{class:AphrontPagerView}. | ||||
|  - **DerpReplyHandler**: business logic from any configured email interactions | ||||
|    users can have with the ##Derp## application. | ||||
|  - **DerpStorage**: storage objects for the ##Derp## application. Typically | ||||
|    users can have with the `Derp` application. | ||||
|  - **DerpStorage**: storage objects for the `Derp` application. Typically | ||||
|    there is a base class which extends @{class:PhabricatorLiskDAO} to configure | ||||
|    application-wide storage settings like the application (thus database) name. | ||||
|    Reading more about the @{class:LiskDAO} is highly recommended. | ||||
|  - **DerpView**: view objects for the ##Derp## application. Typically these | ||||
|  - **DerpView**: view objects for the `Derp` application. Typically these | ||||
|    extend @{class:AphrontView}. | ||||
|  - **DerpConduitAPIMethod**: provides any and all ##Derp## application | ||||
|  - **DerpConduitAPIMethod**: provides any and all `Derp` application | ||||
|    functionality that is accessible over Conduit. | ||||
|  | ||||
| However, it is likely that ##Derp## is even more complex, and rather than | ||||
| However, it is likely that `Derp` is even more complex, and rather than | ||||
| containing one class, each directory has several classes. A typical example | ||||
| happens around the CRUD of an object: | ||||
|  | ||||
|  - **DerpBaseController**: typically extends @{class:PhabricatorController}, | ||||
|    implements ##buildStandardPageResponse## with the ##Derp## application name | ||||
|    and other ##Derp##-specific meta-data, and contains any controller-specific | ||||
|    functionality used throughout the ##Derp## application. | ||||
|  - **DerpDeleteController**: typically extends ##DerpBaseController## and | ||||
|    presents a confirmation dialogue to the user about deleting a ##Derp##. | ||||
|  - **DerpEditController**: typically extends ##DerpBaseController## and | ||||
|    presents a form to create and edit ##Derps##. Most likely uses | ||||
|    @{class:AphrontFormView} and various ##AphrontFormXControl## classes such as | ||||
|    implements `buildStandardPageResponse` with the `Derp` application name | ||||
|    and other `Derp`-specific meta-data, and contains any controller-specific | ||||
|    functionality used throughout the `Derp` application. | ||||
|  - **DerpDeleteController**: typically extends `DerpBaseController` and | ||||
|    presents a confirmation dialogue to the user about deleting a `Derp`. | ||||
|  - **DerpEditController**: typically extends `DerpBaseController` and | ||||
|    presents a form to create and edit `Derps`. Most likely uses | ||||
|    @{class:AphrontFormView} and various `AphrontFormXControl` classes such as | ||||
|    @{class:AphrontFormTextControl} to create the form. | ||||
|  - **DerpListController**: typically extends ##DerpBaseController## and displays | ||||
|    a set of one or more ##Derps##. Might use @{class:AphrontTableView} to create | ||||
|    a table of ##Derps##. | ||||
|  - **DerpViewController**: typically extends ##DerpBaseController## and displays | ||||
|    a single ##Derp##. | ||||
|  - **DerpListController**: typically extends `DerpBaseController` and displays | ||||
|    a set of one or more `Derps`. Might use @{class:AphrontTableView} to create | ||||
|    a table of `Derps`. | ||||
|  - **DerpViewController**: typically extends `DerpBaseController` and displays | ||||
|    a single `Derp`. | ||||
|  | ||||
| Some especially awesome directories might have a ##__tests__## subdirectory | ||||
| Some especially awesome directories might have a `__tests__` subdirectory | ||||
| containing all pertinent unit test code for the class. | ||||
|  | ||||
| = Next Steps = | ||||
|   | ||||
| @@ -19,21 +19,21 @@ guidelines, you probably don't need to read this super thoroughly. | ||||
|  | ||||
|   - Use two spaces for indentation. Don't use tab literal characters. | ||||
|   - Use Unix linebreaks ("\n"), not MSDOS ("\r\n") or OS9 ("\r"). | ||||
|   - Put a space after control keywords like ##if## and ##for##. | ||||
|   - Put a space after control keywords like `if` and `for`. | ||||
|   - Put a space after commas in argument lists. | ||||
|   - Put a space around operators like ##=##, ##<##, etc. | ||||
|   - Put a space around operators like `=`, `<`, etc. | ||||
|   - Don't put spaces after function names. | ||||
|   - Parentheses should hug their contents. | ||||
|   - Generally, prefer to wrap code at 80 columns. | ||||
|  | ||||
| = Case and Capitalization = | ||||
|  | ||||
|   - Name variables and functions using ##lowercase_with_underscores##. | ||||
|   - Name classes using ##UpperCamelCase##. | ||||
|   - Name methods and properties using ##lowerCamelCase##. | ||||
|   - Name variables and functions using `lowercase_with_underscores`. | ||||
|   - Name classes using `UpperCamelCase`. | ||||
|   - Name methods and properties using `lowerCamelCase`. | ||||
|   - Use uppercase for common acronyms like ID and HTML. | ||||
|   - Name constants using ##UPPERCASE##. | ||||
|   - Write ##true##, ##false## and ##null## in lowercase. | ||||
|   - Name constants using `UPPERCASE`. | ||||
|   - Write `true`, `false` and `null` in lowercase. | ||||
|  | ||||
| = Comments = | ||||
|  | ||||
| @@ -43,9 +43,9 @@ guidelines, you probably don't need to read this super thoroughly. | ||||
| = PHP Language Style = | ||||
|  | ||||
|   - Use "<?php", not the "<?" short form. Omit the closing "?>" tag. | ||||
|   - Prefer casts like ##(string)## to casting functions like ##strval()##. | ||||
|   - Prefer type checks like ##$v === null## to type functions like | ||||
|     ##is_null()##. | ||||
|   - Prefer casts like `(string)` to casting functions like `strval()`. | ||||
|   - Prefer type checks like `$v === null` to type functions like | ||||
|     `is_null()`. | ||||
|   - Avoid all crazy alternate forms of language constructs like "endwhile" | ||||
|     and "<>". | ||||
|   - Always put braces around conditional and loop blocks. | ||||
|   | ||||
| @@ -9,7 +9,7 @@ libphutil, Arcanist and Phabricator provide and use a simple unit test | ||||
| framework. This document is aimed at project contributors and describes how to | ||||
| use it to add and run tests in these projects or other libphutil libraries. | ||||
|  | ||||
| In the general case, you can integrate ##arc## with a custom unit test engine | ||||
| In the general case, you can integrate `arc` with a custom unit test engine | ||||
| (like PHPUnit or any other unit testing library) to run tests in other projects. | ||||
| See @{article:Arcanist User Guide: Customizing Lint, Unit Tests and Workflows} | ||||
| for information on customizing engines. | ||||
| @@ -18,20 +18,20 @@ for information on customizing engines. | ||||
|  | ||||
| To add new tests to a libphutil, Arcanist or Phabricator module: | ||||
|  | ||||
|   - Create a ##__tests__/## directory in the module if it doesn't exist yet. | ||||
|   - Add classes to the ##__tests__/## directory which extend from | ||||
|   - Create a `__tests__/` directory in the module if it doesn't exist yet. | ||||
|   - Add classes to the `__tests__/` directory which extend from | ||||
|     @{class:PhabricatorTestCase} (in Phabricator) or | ||||
|     @{class@arcanist:PhutilTestCase} (elsewhere). | ||||
|   - Run ##arc liberate## on the library root so your classes are loadable. | ||||
|   - Run `arc liberate` on the library root so your classes are loadable. | ||||
|  | ||||
| = Running Tests = | ||||
|  | ||||
| Once you've added test classes, you can run them with: | ||||
|  | ||||
|   - ##arc unit path/to/module/##, to explicitly run module tests. | ||||
|   - ##arc unit##, to run tests for all modules affected by changes in the | ||||
|   - `arc unit path/to/module/`, to explicitly run module tests. | ||||
|   - `arc unit`, to run tests for all modules affected by changes in the | ||||
|     working copy. | ||||
|   - ##arc diff## will also run ##arc unit## for you. | ||||
|   - `arc diff` will also run `arc unit` for you. | ||||
|  | ||||
| = Example Test Case = | ||||
|  | ||||
| @@ -76,11 +76,11 @@ in a number of ways. From best to worst: | ||||
|     is reasonable. | ||||
|   - Build a real database simulation layer (fairly complex). | ||||
|   - Disable isolation for a single test by using | ||||
|     ##LiskDAO::endIsolateAllLiskEffectsToCurrentProcess();## before your test | ||||
|     and ##LiskDAO::beginIsolateAllLiskEffectsToCurrentProcess();## after your | ||||
|     `LiskDAO::endIsolateAllLiskEffectsToCurrentProcess();` before your test | ||||
|     and `LiskDAO::beginIsolateAllLiskEffectsToCurrentProcess();` after your | ||||
|     test. This will disable isolation for one test. NOT RECOMMENDED. | ||||
|   - Disable isolation for your entire test case by overriding | ||||
|     ##getPhabricatorTestCaseConfiguration()## and providing | ||||
|     ##self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK => false## in the configuration | ||||
|     `getPhabricatorTestCaseConfiguration()` and providing | ||||
|     `self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK => false` in the configuration | ||||
|     dictionary you return. This will disable isolation entirely. STRONGLY NOT | ||||
|     RECOMMENDED. | ||||
|   | ||||
| @@ -105,7 +105,7 @@ https://phabricator.example.com/api/user.whoami?access_token=ykc7ly7vtibj334oga4 | ||||
|  | ||||
| If the token has expired or is otherwise invalid, the client will receive | ||||
| an error indicating as such. In these cases, the client should re-initiate | ||||
| the entire ##Authorization Code Grant## flow. | ||||
| the entire `Authorization Code Grant` flow. | ||||
|  | ||||
| NOTE: See "Scopes" section below for more information on what data is | ||||
| currently exposed through the OAuth Server. | ||||
|   | ||||
| @@ -8,7 +8,7 @@ behavior. | ||||
| = Primitives = | ||||
|  | ||||
| Javascript has two native datatype primitives, Object and Array. Both are | ||||
| classes, so you can use ##new## to instantiate new objects and arrays: | ||||
| classes, so you can use `new` to instantiate new objects and arrays: | ||||
|  | ||||
|   COUNTEREXAMPLE | ||||
|   var a = new Array();    //  Not preferred. | ||||
| @@ -42,7 +42,7 @@ and Array are both classes, but "object" is also a primitive type. Object is | ||||
|  | ||||
| = Objects are Maps, Arrays are Lists = | ||||
|  | ||||
| PHP has a single ##array## datatype which behaves like as both map and a list, | ||||
| PHP has a single `array` datatype which behaves like as both map and a list, | ||||
| and a common mistake is to treat Javascript arrays (or objects) in the same way. | ||||
| **Don't do this.** It sort of works until it doesn't. Instead, learn how | ||||
| Javascript's native datatypes work and use them properly. | ||||
| @@ -94,9 +94,9 @@ Iterate over a list like this: | ||||
|  | ||||
| NOTE: There's some sparse array nonsense being omitted here, see below. | ||||
|  | ||||
| If you try to use ##for (var k in ...)## syntax to iterate over an Array, you'll | ||||
| If you try to use `for (var k in ...)` syntax to iterate over an Array, you'll | ||||
| pick up a  whole pile of keys you didn't intend to and it won't work. If you try | ||||
| to use ##for (var ii = 0; ...)## syntax to iterate over an Object, it won't work | ||||
| to use `for (var ii = 0; ...)` syntax to iterate over an Object, it won't work | ||||
| at all. | ||||
|  | ||||
| If you consistently treat Arrays as lists and Objects as maps and use the | ||||
| @@ -106,7 +106,7 @@ way. | ||||
| = hasOwnProperty() = | ||||
|  | ||||
| An issue with this model is that if you write stuff to Object.prototype, it will | ||||
| show up every time you use enumeration ##for##: | ||||
| show up every time you use enumeration `for`: | ||||
|  | ||||
|   COUNTEREXAMPLE | ||||
|   var o = {}; | ||||
| @@ -117,7 +117,7 @@ show up every time you use enumeration ##for##: | ||||
|  | ||||
| There are two ways to avoid this: | ||||
|  | ||||
|   - test that ##k## exists on ##o## by calling ##o.hasOwnProperty(k)## in every | ||||
|   - test that `k` exists on `o` by calling `o.hasOwnProperty(k)` in every | ||||
|     single loop everywhere in your program and only use libraries which also do | ||||
|     this and never forget to do it ever; or | ||||
|   - don't write to Object.prototype. | ||||
|   | ||||
| @@ -27,7 +27,7 @@ insert semicolons after each statement. You should also prefer to break lines in | ||||
| places where insertion of a semicolon would not make the unparseable parseable, | ||||
| usually after operators. | ||||
|  | ||||
| = ##with## is Bad News = | ||||
| = `with` is Bad News = | ||||
|  | ||||
| `with` is a pretty bad feature, for this reason among others: | ||||
|  | ||||
| @@ -35,12 +35,12 @@ usually after operators. | ||||
|     property = 3; // Might be on object, might be on window: who knows. | ||||
|   } | ||||
|  | ||||
| Avoid ##with##. | ||||
| Avoid `with`. | ||||
|  | ||||
| = ##arguments## is not an Array = | ||||
| = `arguments` is not an Array = | ||||
|  | ||||
| You can convert ##arguments## to an array using JX.$A() or similar. Note that | ||||
| you can pass  ##arguments## to Function.prototype.apply() without converting it. | ||||
| You can convert `arguments` to an array using JX.$A() or similar. Note that | ||||
| you can pass  `arguments` to Function.prototype.apply() without converting it. | ||||
|  | ||||
| = Object, Array, and iteration are needlessly hard = | ||||
|  | ||||
| @@ -82,6 +82,6 @@ objects and can have methods and properties, and inherit from Array.prototype, | ||||
| Number.prototype, etc.) and their logical behavior is at best absurd and at | ||||
| worst strictly wrong. | ||||
|  | ||||
| **Never use** ##new Number()##, ##new String()## or ##new Boolean()## unless | ||||
| **Never use** `new Number()`, `new String()` or `new Boolean()` unless | ||||
| your Javascript is God Tier and you are absolutely sure you know what you are | ||||
| doing. | ||||
|   | ||||
| @@ -31,7 +31,7 @@ complex variables safely. | ||||
|  | ||||
| = isset(), empty() and Truthiness = | ||||
|  | ||||
| A value is "truthy" if it evaluates to true in an ##if## clause: | ||||
| A value is "truthy" if it evaluates to true in an `if` clause: | ||||
|  | ||||
|   $value = something(); | ||||
|   if ($value) { | ||||
| @@ -61,7 +61,7 @@ This is wrong because it prevents users from making the comment "0". //THIS | ||||
| COMMENT IS TOTALLY AWESOME AND I MAKE IT ALL THE TIME SO YOU HAD BETTER NOT | ||||
| BREAK IT!!!// A better test is probably strlen(). | ||||
|  | ||||
| In addition to truth tests with ##if##, PHP has two special truthiness operators | ||||
| In addition to truth tests with `if`, PHP has two special truthiness operators | ||||
| which look like functions but aren't: empty() and isset(). These operators help | ||||
| deal with undeclared variables. | ||||
|  | ||||
| @@ -147,12 +147,12 @@ In a libphutil environment, you can often do this easily with | ||||
|  | ||||
| These functions are much slower for even moderately large inputs than | ||||
| array_intersect_key() and array_diff_key(), because they can not make the | ||||
| assumption that their inputs are unique scalars as the ##key## varieties can. | ||||
| Strongly prefer the ##key## varieties. | ||||
| assumption that their inputs are unique scalars as the `key` varieties can. | ||||
| Strongly prefer the `key` varieties. | ||||
|  | ||||
| = array_uintersect() and array_udiff() are Definitely Slow Too = | ||||
|  | ||||
| These functions have the problems of both the ##usort()## family and the | ||||
| These functions have the problems of both the `usort()` family and the | ||||
| `array_diff()` family. Avoid them. | ||||
|  | ||||
| = foreach() Does Not Create Scope = | ||||
| @@ -205,7 +205,7 @@ emerge unmodified. That is, if you have a function that takes references: | ||||
|   $x = 41; | ||||
|   call_user_func('add_one', $x); | ||||
|  | ||||
| ...##$x## will not be modified. The solution is to use call_user_func_array() | ||||
| ...`$x` will not be modified. The solution is to use call_user_func_array() | ||||
| and wrap the reference in an array: | ||||
|  | ||||
|   $x = 41; | ||||
| @@ -243,7 +243,7 @@ dictionary (vs a list) when passed to json_encode(). | ||||
|  | ||||
| = Invoking "new" With an Argument Vector is Really Hard = | ||||
|  | ||||
| If you have some ##$class_name## and some ##$argv## of constructor | ||||
| If you have some `$class_name` and some `$argv` of constructor | ||||
| arguments and you want to do this: | ||||
|  | ||||
|   new $class_name($argv[0], $argv[1], ...); | ||||
|   | ||||
| @@ -24,11 +24,11 @@ master/remote version of the repository. Specifically, this means that an entire | ||||
| conceptual changeset ("add a foo widget") is represented in the remote as | ||||
| exactly one commit (in some form), not a sequence of checkpoint commits. | ||||
|  | ||||
|   - In SVN, this means don't ##commit## until after an idea has been completely | ||||
|   - In SVN, this means don't `commit` until after an idea has been completely | ||||
|     written. All reasonable SVN workflows naturally enforce this. | ||||
|   - In Git, this means squashing checkpoint commits as you go (with ##git commit | ||||
|     --amend##) or before pushing (with ##git rebase -i## or ##git merge | ||||
|     --squash##), or having a strict policy where your master/trunk contains only | ||||
|   - In Git, this means squashing checkpoint commits as you go (with `git commit | ||||
|     --amend`) or before pushing (with `git rebase -i` or `git merge | ||||
|     --squash`), or having a strict policy where your master/trunk contains only | ||||
|     merge commits and each is a merge between the old master and a branch which | ||||
|     represents a single idea. Although this preserves the checkpoint commits | ||||
|     along the branches, you can view master alone as a series of single-idea | ||||
|   | ||||
| @@ -84,7 +84,7 @@ eventually moved to automatic generation based on production data. | ||||
| = Caches and Serving Content = | ||||
|  | ||||
| In the simplest implementation of static resources, you write out a raw JS tag | ||||
| with something like ##src="/js/base.js"##. This will break disastrously as you | ||||
| with something like `src="/js/base.js"`. This will break disastrously as you | ||||
| scale, because clients will be running with stale versions of resources. There | ||||
| are bunch of subtle problems (especially once you have a CDN), but the big one | ||||
| is that if a user is browsing your site as you push/deploy, their client will | ||||
|   | ||||
| @@ -29,7 +29,7 @@ Celerity's primary API is @{function:require_celerity_resource}, which marks a | ||||
| resource for inclusion when a response is rendered (e.g., when the HTML page is | ||||
| generated, or when the response to an Ajax request is built). For instance, if | ||||
| you use a CSS class like "widget-view", you must ensure the appropriate CSS is | ||||
| included by calling ##require_celerity_resource('widget-view-css')## (or | ||||
| included by calling `require_celerity_resource('widget-view-css')` (or | ||||
| similar), at your use site. | ||||
|  | ||||
| This function uses @{class:CelerityAPI} to access the active | ||||
| @@ -48,14 +48,14 @@ and not all of its dependencies) and any packaging rules (so it may be able to | ||||
| generate fewer resource requests, improving performance). It then generates | ||||
| `<script />` and `<link />` references to these resources. | ||||
|  | ||||
| These references point at ##/res/## URIs, which are handled by | ||||
| These references point at `/res/` URIs, which are handled by | ||||
| @{class:CelerityResourceController}. It responds to these requests and delivers | ||||
| the relevant resources and packages, managing cache lifetimes and handling any | ||||
| neessary preprocessing. It uses @{class:CelerityResourceMap} to locate resources | ||||
| and read packaging rules. | ||||
|  | ||||
| The dependency and packaging maps are generated by ##bin/celerity map##, | ||||
| which updates ##resources/celerity/map.php##. | ||||
| The dependency and packaging maps are generated by `bin/celerity map`, | ||||
| which updates `resources/celerity/map.php`. | ||||
|  | ||||
| @{class:CelerityStaticResourceResponse} also manages some Javelin information, | ||||
| and @{function:celerity_generate_unique_node_id} uses this metadata to provide | ||||
|   | ||||
| @@ -21,20 +21,20 @@ The bot reads a JSON configuration file. You can find an example in: | ||||
|  | ||||
| These are the configuration values it reads: | ||||
|  | ||||
|   - ##server## String, required, the server to connect to. | ||||
|   - ##port## Int, optional, the port to connect to (defaults to 6667). | ||||
|   - ##ssl## Bool, optional, whether to connect via SSL or not (defaults to | ||||
|   - `server` String, required, the server to connect to. | ||||
|   - `port` Int, optional, the port to connect to (defaults to 6667). | ||||
|   - `ssl` Bool, optional, whether to connect via SSL or not (defaults to | ||||
|     false). | ||||
|   - ##nick## String, nickname to use. | ||||
|   - ##user## String, optional, username to use (defaults to ##nick##). | ||||
|   - ##pass## String, optional, password for server. | ||||
|   - ##nickpass## String, optional, password for NickServ. | ||||
|   - ##join## Array, list of channels to join. | ||||
|   - ##handlers## Array, list of handlers to run. These are like plugins for the | ||||
|   - `nick` String, nickname to use. | ||||
|   - `user` String, optional, username to use (defaults to `nick`). | ||||
|   - `pass` String, optional, password for server. | ||||
|   - `nickpass` String, optional, password for NickServ. | ||||
|   - `join` Array, list of channels to join. | ||||
|   - `handlers` Array, list of handlers to run. These are like plugins for the | ||||
|     bot. | ||||
|   - ##conduit.uri##, ##conduit.user##, ##conduit.cert## Conduit configuration, | ||||
|   - `conduit.uri`, `conduit.user`, `conduit.cert` Conduit configuration, | ||||
|     see below. | ||||
|   - ##notification.channels## Notification configuration, see below. | ||||
|   - `notification.channels` Notification configuration, see below. | ||||
|  | ||||
| = Handlers = | ||||
|  | ||||
| @@ -46,14 +46,14 @@ the bot. These are the default handlers available: | ||||
|     up, and says their name with a link to the object. Requires conduit. | ||||
|   - @{class:PhabricatorBotFeedNotificationHandler} This handler posts | ||||
|     notifications about changes to revisions to the channels listed in | ||||
|     ##notification.channels##. | ||||
|     `notification.channels`. | ||||
|   - @{class:PhabricatorBotLogHandler} This handler records chatlogs which can | ||||
|     be browsed in the Phabricator web interface. | ||||
|   - @{class:PhabricatorBotSymbolHandler} This handler posts responses to lookups | ||||
|     for symbols in Diffusion | ||||
|   - @{class:PhabricatorBotMacroHandler} This handler looks for users mentioning | ||||
|     macros, if found will convert image to ASCII and output in chat. Configure | ||||
|     with ##macro.size## and ##macro.aspect## | ||||
|     with `macro.size` and `macro.aspect` | ||||
|  | ||||
| You can also write your own handlers, by extending | ||||
| @{class:PhabricatorBotHandler}. | ||||
| @@ -70,20 +70,20 @@ with. To do this, login to Phabricator as an administrator and go to | ||||
| `People -> Create New Account`. Create a new account and flag them as a | ||||
| "Bot/Script". Then in your configuration file, set these parameters: | ||||
|  | ||||
|   - ##conduit.uri## The URI for your Phabricator install, like | ||||
|     ##http://phabricator.example.com/## | ||||
|   - ##conduit.user## The username your bot should login to Phabricator with -- | ||||
|     whatever you selected above, like ##phabot##. | ||||
|   - ##conduit.cert## The user's certificate, from the "Conduit Certificate" tab | ||||
|   - `conduit.uri` The URI for your Phabricator install, like | ||||
|     `http://phabricator.example.com/` | ||||
|   - `conduit.user` The username your bot should login to Phabricator with -- | ||||
|     whatever you selected above, like `phabot`. | ||||
|   - `conduit.cert` The user's certificate, from the "Conduit Certificate" tab | ||||
|     in the user's administrative view. | ||||
|  | ||||
| Now the bot should be able to connect to Phabricator via Conduit. | ||||
|  | ||||
| = Starting the Bot = | ||||
|  | ||||
| The bot is a Phabricator daemon, so start it with ##phd##: | ||||
| The bot is a Phabricator daemon, so start it with `phd`: | ||||
|  | ||||
|   ./bin/phd launch phabricatorbot <absolute_path_to_config_file> | ||||
|  | ||||
| If you have issues you can try ##debug## instead of ##launch##, see | ||||
| If you have issues you can try `debug` instead of `launch`, see | ||||
| @{article:Managing Daemons with phd} for more information. | ||||
|   | ||||
| @@ -22,8 +22,8 @@ of Phabricator, let us know so we can adjust priorities. | ||||
| Conduit provides an authenticated HTTP API for Phabricator. It is informal and | ||||
| extremely simple: you post a JSON blob and you get a JSON blob back. You can | ||||
| access Conduit in PHP with @{class@libphutil:ConduitClient}, or in any language | ||||
| by executing ##arc call-conduit method## (see ##arc help call-conduit## for | ||||
| more information). You can see and test available methods at ##/conduit/## in | ||||
| by executing `arc call-conduit method` (see `arc help call-conduit` for | ||||
| more information). You can see and test available methods at `/conduit/` in | ||||
| the web interface. | ||||
|  | ||||
| Arcanist is implemented using Conduit, and @{class:PhabricatorBot} is | ||||
| @@ -32,7 +32,7 @@ Phabricator over Conduit. | ||||
|  | ||||
| = Class Relationships = | ||||
|  | ||||
| The primary Conduit workflow is exposed at ##/api/##, which routes to | ||||
| The primary Conduit workflow is exposed at `/api/`, which routes to | ||||
| @{class:PhabricatorConduitAPIController}. This controller builds a | ||||
| @{class:ConduitAPIRequest} representing authentication information and POST | ||||
| parameters, instantiates an appropriate subclass of @{class:ConduitAPIMethod}, | ||||
| @@ -49,7 +49,7 @@ Console", implemented by @{class:PhabricatorConduitConsoleController} at | ||||
| A log of connections and calls is stored by | ||||
| @{class:PhabricatorConduitConnectionLog} and | ||||
| @{class:PhabricatorConduitMethodCallLog}, and can be accessed on the web via | ||||
| @{class:PhabricatorConduitLogController} at ##/conduit/log/##. | ||||
| @{class:PhabricatorConduitLogController} at `/conduit/log/`. | ||||
|  | ||||
| Conduit provides a token-based handshake mechanism used by | ||||
| `arc install-certificate` at `/conduit/token/`, implemented by | ||||
|   | ||||
| @@ -20,8 +20,8 @@ NOTE: Follow these instructions to use Apache. To use nginx or lighttpd, scroll | ||||
| down to their sections. | ||||
|  | ||||
| Get Apache running and verify it's serving a test page. Consult the Apache | ||||
| documentation for help. Make sure ##mod_php## and ##mod_rewrite## are enabled, | ||||
| and ##mod_ssl## if you intend to set up SSL. | ||||
| documentation for help. Make sure `mod_php` and `mod_rewrite` are enabled, | ||||
| and `mod_ssl` if you intend to set up SSL. | ||||
|  | ||||
| If you haven't already, set up a domain name to point to the host you're | ||||
| installing on. You can either install Phabricator on a subdomain (like | ||||
| @@ -177,7 +177,7 @@ root or some other admin user: | ||||
|  | ||||
|   phabricator/ $ ./bin/storage upgrade --user <user> --password <password> | ||||
|  | ||||
| You can avoid the prompt the script issues by passing the ##--force## flag (for | ||||
| You can avoid the prompt the script issues by passing the `--force` flag (for | ||||
| example, if you are scripting the upgrade process). | ||||
|  | ||||
|   phabricator/ $ ./bin/storage upgrade --force | ||||
|   | ||||
| @@ -48,7 +48,7 @@ in your configuration: | ||||
|     default. If your domain is `example.org`, set this to something like | ||||
|     `noreply@example.org`. | ||||
|   - **metamta.domain** should be set to your domain, e.g. `example.org`. | ||||
|   - **metamta.can-send-as-user** should be left as ##false## in most cases, | ||||
|   - **metamta.can-send-as-user** should be left as `false` in most cases, | ||||
|     but see the documentation for details. | ||||
|  | ||||
| = Configuring Mail Adapters = | ||||
| @@ -56,19 +56,19 @@ in your configuration: | ||||
| To choose how mail will be sent, change the `metamta.mail-adapter` key in | ||||
| your configuration. Possible values are listed in the UI: | ||||
|  | ||||
|   - ##PhabricatorMailImplementationAmazonMailgunAdapter##: use Mailgun, see | ||||
|   - `PhabricatorMailImplementationAmazonMailgunAdapter`: use Mailgun, see | ||||
|     "Adapter: Mailgun". | ||||
|   - ##PhabricatorMailImplementationAmazonSESAdapter##: use Amazon SES, see | ||||
|   - `PhabricatorMailImplementationAmazonSESAdapter`: use Amazon SES, see | ||||
|     "Adapter: Amazon SES". | ||||
|   - ##PhabricatorMailImplementationPHPMailerLiteAdapter##: default, uses | ||||
|   - `PhabricatorMailImplementationPHPMailerLiteAdapter`: default, uses | ||||
|     "sendmail", see "Adapter: Sendmail". | ||||
|   - ##PhabricatorMailImplementationPHPMailerAdapter##: uses SMTP, see | ||||
|   - `PhabricatorMailImplementationPHPMailerAdapter`: uses SMTP, see | ||||
|     "Adapter: SMTP". | ||||
|   - ##PhabricatorMailImplementationSendGridAdapter##: use SendGrid, see | ||||
|   - `PhabricatorMailImplementationSendGridAdapter`: use SendGrid, see | ||||
|     "Adapter: SendGrid". | ||||
|   - ##Some Custom Class You Write##: use a custom adapter you write, see | ||||
|   - `Some Custom Class You Write`: use a custom adapter you write, see | ||||
|     "Adapter: Custom". | ||||
|   - ##PhabricatorMailImplementationTestAdapter##: this will | ||||
|   - `PhabricatorMailImplementationTestAdapter`: this will | ||||
|     **completely disable** outbound mail. You can use this if you don't want to | ||||
|     send outbound mail, or want to skip this step for now and configure it | ||||
|     later. | ||||
| @@ -137,7 +137,7 @@ To configure Phabricator to use Amazon SES, set these configuration keys: | ||||
|   - **amazon-ses.secret-key**: set to your Amazon SES secret key. | ||||
|  | ||||
| NOTE: Amazon SES **requires you to verify your "From" address**. Configure which | ||||
| "From" address to use by setting "##metamta.default-address##" in your config, | ||||
| "From" address to use by setting "`metamta.default-address`" in your config, | ||||
| then follow the Amazon SES verification process to verify it. You won't be able | ||||
| to send email until you do this! | ||||
|  | ||||
| @@ -147,7 +147,7 @@ SendGrid is an email delivery service like Amazon SES. You can learn more at | ||||
| <http://sendgrid.com/>. It is easy to configure, but not free. | ||||
|  | ||||
| You can configure SendGrid in two ways: you can send via SMTP or via the REST | ||||
| API. To use SMTP, just configure ##sendmail## and leave Phabricator's setup | ||||
| API. To use SMTP, just configure `sendmail` and leave Phabricator's setup | ||||
| with defaults. To use the REST API, follow the instructions in this section. | ||||
|  | ||||
| To configure Phabricator to use SendGrid, set these configuration keys: | ||||
| @@ -187,7 +187,7 @@ particular: | ||||
|  | ||||
| Run `bin/mail help <command>` for more help on using these commands. | ||||
|  | ||||
| You can monitor daemons using the Daemon Console (##/daemon/##, or click | ||||
| You can monitor daemons using the Daemon Console (`/daemon/`, or click | ||||
| **Daemon Console** from the homepage). | ||||
|  | ||||
| = Next Steps = | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| @title Managing Daemons with phd | ||||
| @group config | ||||
|  | ||||
| Explains Phabricator daemons and the daemon control program ##phd##. | ||||
| Explains Phabricator daemons and the daemon control program `phd`. | ||||
|  | ||||
| = Overview = | ||||
|  | ||||
| @@ -23,8 +23,8 @@ daemons. | ||||
|  | ||||
| = phd = | ||||
|  | ||||
| **phd** is a command-line script (located at ##phabricator/bin/phd##). To get | ||||
| a list of commands, run ##phd help##: | ||||
| **phd** is a command-line script (located at `phabricator/bin/phd`). To get | ||||
| a list of commands, run `phd help`: | ||||
|  | ||||
|   phabricator/ $ ./bin/phd help | ||||
|   NAME | ||||
| @@ -49,7 +49,7 @@ the daemons by running `phd restart`. | ||||
| = Daemon Console = | ||||
|  | ||||
| You can view status and debugging information for daemons in the Daemon Console | ||||
| via the web interface. Go to ##/daemon/## in your install or click | ||||
| via the web interface. Go to `/daemon/` in your install or click | ||||
| **Daemon Console** from "More Stuff". | ||||
|  | ||||
| The Daemon Console shows a list of all the daemons that have ever launched, and | ||||
|   | ||||
| @@ -8,7 +8,7 @@ Differential, Files, and Paste), integrates with static analysis ("lint") and | ||||
| unit tests, and manages common workflows like getting changes into Differential | ||||
| for review. | ||||
|  | ||||
| A detailed command reference is available by running ##arc help##. This | ||||
| A detailed command reference is available by running `arc help`. This | ||||
| document provides an overview of common workflows and installation. | ||||
|  | ||||
| Arcanist has technical, contributor-focused documentation here: | ||||
| @@ -38,34 +38,34 @@ For detailed information about a specific command, run: | ||||
|  | ||||
| Arcanist allows you to do things like: | ||||
|  | ||||
|   - get detailed help about available commands with ##arc help## | ||||
|   - send your code to Differential for review with ##arc diff## (for detailed | ||||
|   - get detailed help about available commands with `arc help` | ||||
|   - send your code to Differential for review with `arc diff` (for detailed | ||||
|     instructions, see @{article:Arcanist User Guide: arc diff}) | ||||
|   - show pending revision information with ##arc list## | ||||
|   - find likely reviewers for a change with ##arc cover## | ||||
|   - apply changes in a revision to the working copy with ##arc patch## | ||||
|   - download a patch from Differential with ##arc export## | ||||
|   - update Git commit messages after review with ##arc amend## | ||||
|   - commit SVN changes with ##arc commit## | ||||
|   - push Git and Mercurial changes with ##arc land## | ||||
|   - view enhanced information about Git branches with ##arc branch## | ||||
|   - show pending revision information with `arc list` | ||||
|   - find likely reviewers for a change with `arc cover` | ||||
|   - apply changes in a revision to the working copy with `arc patch` | ||||
|   - download a patch from Differential with `arc export` | ||||
|   - update Git commit messages after review with `arc amend` | ||||
|   - commit SVN changes with `arc commit` | ||||
|   - push Git and Mercurial changes with `arc land` | ||||
|   - view enhanced information about Git branches with `arc branch` | ||||
|  | ||||
| Once you've configured lint and unit test integration, you can also: | ||||
|  | ||||
|   - check your code for syntax and style errors with ##arc lint## | ||||
|   - check your code for syntax and style errors with `arc lint` | ||||
|     (see @{article:Arcanist User Guide: Lint}) | ||||
|   - run unit tests that cover your changes with ##arc unit## | ||||
|   - run unit tests that cover your changes with `arc unit` | ||||
|  | ||||
| Arcanist integrates with other tools: | ||||
|  | ||||
|   - upload and download files with ##arc upload## and ##arc download## | ||||
|   - create and view pastes with ##arc paste## | ||||
|   - upload and download files with `arc upload` and `arc download` | ||||
|   - create and view pastes with `arc paste` | ||||
|  | ||||
| Arcanist has some advanced features as well, you can: | ||||
|  | ||||
|   - execute Conduit method calls with ##arc call-conduit## | ||||
|   - create or update libphutil libraries with ##arc liberate## | ||||
|   - activate tab completion with ##arc shell-complete## | ||||
|   - execute Conduit method calls with `arc call-conduit` | ||||
|   - create or update libphutil libraries with `arc liberate` | ||||
|   - activate tab completion with `arc shell-complete` | ||||
|   - ...or extend Arcanist and add new commands. | ||||
|  | ||||
| Except where otherwise noted, these workflows are generally agnostic to the | ||||
| @@ -99,7 +99,7 @@ This should leave you with a directory structure like this | ||||
|     arcanist/           # Arcanist-specific code and libraries. | ||||
|     libphutil/          # A shared library Arcanist depends upon. | ||||
|  | ||||
| Now add ##some_install_path/arcanist/bin/## to your PATH environment variable. | ||||
| Now add `some_install_path/arcanist/bin/` to your PATH environment variable. | ||||
| When you type "arc", you should see something like this: | ||||
|  | ||||
|   Usage Exception: No command provided. Try 'arc help'. | ||||
| @@ -137,8 +137,8 @@ able to use: | ||||
|  | ||||
| == Installing Tab Completion == | ||||
|  | ||||
| If you use ##bash##, you can set up tab completion by adding something like this | ||||
| to your ##.bashrc##, ##.profile## or similar: | ||||
| If you use `bash`, you can set up tab completion by adding something like this | ||||
| to your `.bashrc`, `.profile` or similar: | ||||
|  | ||||
|   source /path/to/arcanist/resources/shell/bash-completion | ||||
|  | ||||
|   | ||||
| @@ -22,7 +22,7 @@ For example: | ||||
|   arc unit --detailed-coverage src/some/file.php | ||||
|  | ||||
| Depending on how your test engine is configured, this will run tests relevant | ||||
| to ##src/some/file.php## and give you a detailed coverage report. | ||||
| to `src/some/file.php` and give you a detailed coverage report. | ||||
|  | ||||
| If the test engine enables coverage by default, it will be uploaded to | ||||
| Differential and displayed in the right gutter when viewing diffs. | ||||
| @@ -39,7 +39,7 @@ be automatically enabled. | ||||
|  | ||||
| = Building Coverage Support = | ||||
|  | ||||
| To add coverage support to a unit test engine, just call ##setCoverage()## when | ||||
| To add coverage support to a unit test engine, just call `setCoverage()` when | ||||
| building @{class@arcanist:ArcanistUnitTestResult} objects. Provide a map of | ||||
| file names (relative to the working copy root) to coverage report strings. | ||||
| Coverage report strings look like this: | ||||
|   | ||||
| @@ -34,7 +34,7 @@ nonfinal. | ||||
|  | ||||
| By default, most linters raise lint messages as errors. You may want to reduce | ||||
| the severity of some messages (e.g., reduce errors to warnings). Do this by | ||||
| calling ##setCustomSeverityMap()##: | ||||
| calling `setCustomSeverityMap()`: | ||||
|  | ||||
|   $linter = new ArcanistTextLinter(); | ||||
|  | ||||
| @@ -50,7 +50,7 @@ constants. | ||||
|  | ||||
| = Disabling Rules = | ||||
|  | ||||
| To disable rules entirely, set their severities to ##SEVERITY_DISABLED##: | ||||
| To disable rules entirely, set their severities to `SEVERITY_DISABLED`: | ||||
|  | ||||
|   $linter = new ArcanistTextLinter(); | ||||
|  | ||||
| @@ -91,12 +91,12 @@ information. | ||||
|  | ||||
| == ArcanistTextLinter == | ||||
|  | ||||
|   - Use ##setMaxLineLength()## to change the 80-column warning to something | ||||
|   - Use `setMaxLineLength()` to change the 80-column warning to something | ||||
|     else. | ||||
|  | ||||
| == ArcanistXHPASTLinter == | ||||
|  | ||||
|   - Use ##lint.xhpast.naminghook## in ##.arcconfig## to override naming | ||||
|   - Use `lint.xhpast.naminghook` in `.arcconfig` to override naming | ||||
|     convention rules. See @{class@arcanist:ArcanistXHPASTLintNamingHook} | ||||
|     for details. | ||||
|   - Use ##getXHPASTTreeForPath()## to reuse the AAST in other linters. | ||||
|   - Use `getXHPASTTreeForPath()` to reuse the AAST in other linters. | ||||
|   | ||||
| @@ -30,8 +30,8 @@ Arcanist will load this class and call methods on it in order to run lint. To | ||||
| make this work, you need to do three things: | ||||
|  | ||||
|   - actually write the class; | ||||
|   - add the library where the class exists to your ##.arcconfig##; | ||||
|   - add the class name to your ##.arcconfig## as the **lint.engine**, | ||||
|   - add the library where the class exists to your `.arcconfig`; | ||||
|   - add the class name to your `.arcconfig` as the **lint.engine**, | ||||
|     **unit.engine**, or **arcanist_configuration**. | ||||
|  | ||||
| = Create a libphutil Library = | ||||
| @@ -39,7 +39,7 @@ make this work, you need to do three things: | ||||
| If you haven't created a library for the class to live in yet, you need to do | ||||
| that first. Follow the instructions in | ||||
| @{article:libphutil Libraries User Guide}, then make the library loadable by | ||||
| adding it to your ##.arcconfig## like this: | ||||
| adding it to your `.arcconfig` like this: | ||||
|  | ||||
|   { | ||||
|     // ... | ||||
| @@ -53,7 +53,7 @@ adding it to your ##.arcconfig## like this: | ||||
|   } | ||||
|  | ||||
| You can either specify an absolute path, or a path relative to the project root. | ||||
| When you run ##arc list --trace##, you should see a message to the effect that | ||||
| When you run `arc list --trace`, you should see a message to the effect that | ||||
| it has loaded your library. | ||||
|  | ||||
| For debugging or testing, you can also run Arcanist with the | ||||
| @@ -67,7 +67,7 @@ if you use this flag, Arcanist will ignore any libraries listed in | ||||
|  | ||||
| = Use the Class = | ||||
|  | ||||
| This step is easy: just edit ##.arcconfig## to specify your class name as | ||||
| This step is easy: just edit `.arcconfig` to specify your class name as | ||||
| the appropriate configuration value. | ||||
|  | ||||
|   { | ||||
| @@ -79,7 +79,7 @@ the appropriate configuration value. | ||||
| Now, when you run Arcanist in your project, it will invoke your class when | ||||
| appropriate. | ||||
|  | ||||
| For lint and unit tests, you can also use the ##--engine## flag override the | ||||
| For lint and unit tests, you can also use the `--engine` flag override the | ||||
| default engine: | ||||
|  | ||||
|   arc lint --engine MyCustomArcanistLintEngine | ||||
|   | ||||
| @@ -88,13 +88,13 @@ explain how these settings affect workflows. | ||||
| == History Mutability: Git == | ||||
|  | ||||
| In a workflow with //mutable// history, you rewrite local history. You develop | ||||
| in feature branches, but squash or amend before pushing by using ##git commit | ||||
| --amend##, ##git rebase -i##, or `git merge --squash`. Generally, one idea in | ||||
| in feature branches, but squash or amend before pushing by using `git commit | ||||
| --amend`, `git rebase -i`, or `git merge --squash`. Generally, one idea in | ||||
| the remote is represented by one commit. | ||||
|  | ||||
| In a workflow with //immutable// history, you do not rewrite local history. You | ||||
| develop in feature branches and push them without squashing commits. You do not | ||||
| use ##git commit --amend## or ##git rebase -i##. Generally, one idea in the | ||||
| use `git commit --amend` or `git rebase -i`. Generally, one idea in the | ||||
| remote is represented by many commits. | ||||
|  | ||||
| Practically, these are the differences you'll see based on your setting: | ||||
|   | ||||
| @@ -39,7 +39,7 @@ you are writing; they are adapted from Facebook's internal documentation. | ||||
|   - **Concurrent Change Robustness:** If you're making a refactoring change, is | ||||
|     it robust against people introducing new calls between the time you started | ||||
|     the change and when you commit it? For example, if you change the parameter | ||||
|     order of some function from ##f(a, b)## to ##f(b, a)## and a new callsite is | ||||
|     order of some function from `f(a, b)` to `f(b, a)` and a new callsite is | ||||
|     introduced in the meantime, could it go unnoticed? How bad would that be? | ||||
|     (Because of this risk, you should almost never make parameter order | ||||
|     changes in weakly typed languages like PHP and Javascript.) | ||||
|   | ||||
| @@ -35,7 +35,7 @@ Exuberant Ctags (http://ctags.sourceforge.net): | ||||
|   ./scripts/symbols/generate_ctags_symbols.php | ||||
|  | ||||
| If you want to identify symbols from another language, you need to write a | ||||
| script which can export them (for example, maybe by parsing a ##ctags## file). | ||||
| script which can export them (for example, maybe by parsing a `ctags` file). | ||||
|  | ||||
| The output format of the script should be one symbol per line: | ||||
|  | ||||
| @@ -49,13 +49,13 @@ Context is, broadly speaking, the scope or namespace where the symbol is | ||||
| defined. For object-oriented languages, this is probably a class name. The | ||||
| symbols with that context are class constants, methods, properties, nested | ||||
| classes, etc. When printing symbols without a context (those that are defined | ||||
| globally, for instance), the ##<context>## field should be empty (that is, the | ||||
| globally, for instance), the `<context>` field should be empty (that is, the | ||||
| line should start with a space). | ||||
|  | ||||
| Your script should enumerate all the symbols in your project, and provide paths | ||||
| from the project root (where ".arcconfig" is) beginning with a "/". | ||||
|  | ||||
| You can look at ##generate_php_symbols.php## for an example of how you might | ||||
| You can look at `generate_php_symbols.php` for an example of how you might | ||||
| write such a script, and run this command to see its output: | ||||
|  | ||||
|   $ cd phabricator/ | ||||
| @@ -69,7 +69,7 @@ To actually build the symbol index, pipe this data to the | ||||
| Then just set up a cronjob to run that however often you like. | ||||
|  | ||||
| You can test that the import worked by querying for symbols using the Conduit | ||||
| method ##diffusion.findsymbols##. Some features (like that method, and the | ||||
| method `diffusion.findsymbols`. Some features (like that method, and the | ||||
| IRC bot integration) will start working immediately. Others will require more | ||||
| configuration. | ||||
|  | ||||
|   | ||||
| @@ -154,11 +154,11 @@ The constant for this event is | ||||
| This event is dispatched before a task is edited, and allows you to respond to | ||||
| or alter the edit. Data available on this event: | ||||
|  | ||||
|   - ##task## The @{class:ManiphestTask} being edited. | ||||
|   - ##transactions## The list of edits (objects of class | ||||
|   - `task` The @{class:ManiphestTask} being edited. | ||||
|   - `transactions` The list of edits (objects of class | ||||
|     @{class:ManiphestTransaction}) being applied. | ||||
|   - ##new## A boolean indicating if this task is being created. | ||||
|   - ##mail## If this edit originates from email, the | ||||
|   - `new` A boolean indicating if this task is being created. | ||||
|   - `mail` If this edit originates from email, the | ||||
|     @{class:PhabricatorMetaMTAReceivedMail} object. | ||||
|  | ||||
| This is similar to the next event (did edit task) but occurs before the edit | ||||
| @@ -172,11 +172,11 @@ The constant for this event is | ||||
| This event is dispatched after a task is edited, and allows you to react to the | ||||
| edit. Data available on this event: | ||||
|  | ||||
|   - ##task## The @{class:ManiphestTask} that was edited. | ||||
|   - ##transactions## The list of edits (objects of class | ||||
|   - `task` The @{class:ManiphestTask} that was edited. | ||||
|   - `transactions` The list of edits (objects of class | ||||
|     @{class:ManiphestTransaction}) that were applied. | ||||
|   - ##new## A boolean indicating if this task was newly created. | ||||
|   - ##mail## If this edit originates from email, the | ||||
|   - `new` A boolean indicating if this task was newly created. | ||||
|   - `mail` If this edit originates from email, the | ||||
|     @{class:PhabricatorMetaMTAReceivedMail} object. | ||||
|  | ||||
| This is similar to the previous event (will edit task) but occurs after the | ||||
| @@ -190,8 +190,8 @@ The constant for this event is | ||||
| This event is dispatched before Differential decides if a file is generated (and | ||||
| doesn't need to be reviewed) or not. Data available on this event: | ||||
|  | ||||
|   - ##corpus## Body of the file. | ||||
|   - ##is_generated## Boolean indicating if this file should be treated as | ||||
|   - `corpus` Body of the file. | ||||
|   - `is_generated` Boolean indicating if this file should be treated as | ||||
|     generated. | ||||
|  | ||||
| == Diffusion: Did Discover Commit == | ||||
|   | ||||
| @@ -27,7 +27,7 @@ buttons in the interface. | ||||
|  | ||||
| == Configuring: TextMate on OS X == | ||||
|  | ||||
| TextMate installs a ##txmt://## handler by default, so it's easy to configure | ||||
| TextMate installs a `txmt://` handler by default, so it's easy to configure | ||||
| this feature if you use TextMate. | ||||
|  | ||||
| First, create a local directory with symlinks for each repository callsign. For | ||||
|   | ||||
| @@ -43,8 +43,8 @@ the actions for any matching rules are taken. | ||||
|  | ||||
| To create a new Herald rule, choose which type of event you want to act on | ||||
| (e.g., changes to Differential Revisions, or Commits), and then set a list of | ||||
| conditions. For example, you might add the condition ##Author is alincoln | ||||
| (Abraham Lincoln)## to keep track of everything alincoln does. Finally, set | ||||
| conditions. For example, you might add the condition `Author is alincoln | ||||
| (Abraham Lincoln)` to keep track of everything alincoln does. Finally, set | ||||
| a list of actions to take when the conditions match, like adding yourself to the | ||||
| CC list. | ||||
|  | ||||
| @@ -90,7 +90,7 @@ A few features in Herald are particularly complicated: | ||||
|   filename of the changed file; the second will be used to match the content. | ||||
|   For example, if you want to match revisions which add or remove calls to | ||||
|   a "muffinize" function, //but only in JS files//, you can set the value | ||||
|   to ##["/\\.js$/", "/muffinize/"]## or similar. | ||||
|   to `["/\\.js$/", "/muffinize/"]` or similar. | ||||
|   - **Another Herald rule**: you can create Herald rules which depend on other | ||||
|   rules. This can be useful if you need to express a more complicated predicate | ||||
|   than "all" vs "any" allows, or have a common set of conditions which you want | ||||
|   | ||||
| @@ -17,15 +17,15 @@ Phabricator to load it. | ||||
| In general, you perform these one-time setup steps: | ||||
|  | ||||
|   - Create a new directory. | ||||
|   - Use ##arc liberate## to initialize and name the library. | ||||
|   - Use `arc liberate` to initialize and name the library. | ||||
|   - Add a dependency on Phabricator if necessary. | ||||
|   - Add the library to your Phabricator config or ##.arcconfig## so it will be | ||||
|   - Add the library to your Phabricator config or `.arcconfig` so it will be | ||||
|     loaded at runtime. | ||||
|  | ||||
| Then, to add new code, you do this: | ||||
|  | ||||
|   - Write or update classes. | ||||
|   - Update the library metadata by running ##arc liberate## again. | ||||
|   - Update the library metadata by running `arc liberate` again. | ||||
|  | ||||
| = Creating a New Library = | ||||
|  | ||||
| @@ -61,13 +61,13 @@ you should get some details about the library initialization: | ||||
|  | ||||
| This will write three files: | ||||
|  | ||||
|   - ##src/.phutil_module_cache## This is a cache which makes "arc liberate" | ||||
|   - `src/.phutil_module_cache` This is a cache which makes "arc liberate" | ||||
|     faster when you run it to update the library. You can safely remove it at | ||||
|     any time. If you check your library into version control, you can add this | ||||
|     file to ignore rules (like .gitignore). | ||||
|   - ##src/__phutil_library_init__.php## This records the name of the library and | ||||
|   - `src/__phutil_library_init__.php` This records the name of the library and | ||||
|     tells libphutil that a library exists here. | ||||
|   - ##src/__phutil_library_map__.php## This is a map of all the symbols | ||||
|   - `src/__phutil_library_map__.php` This is a map of all the symbols | ||||
|     (functions and classes) in the library, which allows them to be autoloaded | ||||
|     at runtime and dependencies to be statically managed by "arc liberate". | ||||
|  | ||||
| @@ -78,7 +78,7 @@ with Arcanist or are building something else on libphutil) you can skip this | ||||
| step. | ||||
|  | ||||
| But, if you intend to use this library with Phabricator, you need to define its | ||||
| dependency on Phabricator by creating a ##.arcconfig## file which points at | ||||
| dependency on Phabricator by creating a `.arcconfig` file which points at | ||||
| Phabricator. For example, you might write this file to | ||||
| `libcustom/.arcconfig`: | ||||
|  | ||||
| @@ -88,19 +88,19 @@ Phabricator. For example, you might write this file to | ||||
|     ] | ||||
|   } | ||||
|  | ||||
| For details on creating a ##.arcconfig##, see | ||||
| For details on creating a `.arcconfig`, see | ||||
| @{article:Arcanist User Guide: Configuring a New Project}. In general, this | ||||
| tells ##arc liberate## that it should look for symbols in Phabricator when | ||||
| tells `arc liberate` that it should look for symbols in Phabricator when | ||||
| performing static analysis. | ||||
|  | ||||
| NOTE: If Phabricator isn't located next to your custom library, specify a | ||||
| path which actually points to the ##phabricator/## directory. | ||||
| path which actually points to the `phabricator/` directory. | ||||
|  | ||||
| You do not need to declare dependencies on ##arcanist## or ##libphutil##, | ||||
| since ##arc liberate## automatically loads them. | ||||
| You do not need to declare dependencies on `arcanist` or `libphutil`, | ||||
| since `arc liberate` automatically loads them. | ||||
|  | ||||
| Finally, edit your Phabricator config to tell it to load your library at | ||||
| runtime, by adding it to ##load-libraries##: | ||||
| runtime, by adding it to `load-libraries`: | ||||
|  | ||||
|   ... | ||||
|   'load-libraries' => array( | ||||
| @@ -117,7 +117,7 @@ To actually write classes, create a new module and put code in it: | ||||
|   libcustom/ $ mkdir src/example/ | ||||
|   libcustom/ $ nano src/example/ExampleClass.php # Edit some code. | ||||
|  | ||||
| Now, run ##arc liberate## to regenerate the static resource map: | ||||
| Now, run `arc liberate` to regenerate the static resource map: | ||||
|  | ||||
|   libcustom/ $ arc liberate src/ | ||||
|  | ||||
| @@ -126,7 +126,7 @@ This will automatically regenerate the static map of the library. | ||||
| = What You Can Extend And Invoke = | ||||
|  | ||||
| libphutil, Arcanist and Phabricator are strict about extensibility of classes | ||||
| and visibility of methods and properties. Most classes are marked ##final##, and | ||||
| and visibility of methods and properties. Most classes are marked `final`, and | ||||
| methods have the minimum required visibility (protected or private). The goal of | ||||
| this strictness is to make it clear what you can safely extend, access, and | ||||
| invoke, so your code will keep working as the upstream changes. | ||||
| @@ -137,7 +137,7 @@ should respect method and property visibility and extend only classes marked | ||||
| example: @{class@libphutil:AbstractDirectedGraph}). These classes are external | ||||
| interfaces intended for extension. | ||||
|  | ||||
| If you want to extend a class but it is not marked ##@stable##, here are some | ||||
| If you want to extend a class but it is not marked `@stable`, here are some | ||||
| approaches you can take: | ||||
|  | ||||
|   - Good: If possible, use composition rather than extension to build your | ||||
|   | ||||
| @@ -34,7 +34,7 @@ to write more sophisticated mail rules. | ||||
| Phabricator sends a variety of mail headers that can be useful in crafting rules | ||||
| to route and manage mail. | ||||
|  | ||||
| Headers in plural contain lists. A list containing two items, ##1## and | ||||
| Headers in plural contain lists. A list containing two items, `1` and | ||||
| `15` will generally be formatted like this: | ||||
|  | ||||
|   X-Header: <1>, <15> | ||||
| @@ -49,33 +49,33 @@ expressions or wildcards (namely Outlook). | ||||
|  | ||||
| The headers Phabricator adds to mail are: | ||||
|  | ||||
|   - ##X-Phabricator-Sent-This-Message##: this is attached to all mail | ||||
|   - `X-Phabricator-Sent-This-Message`: this is attached to all mail | ||||
|     Phabricator sends. You can use it to differentiate between email from | ||||
|     Phabricator and replies/forwards of Phabricator mail from human beings. | ||||
|   - ##X-Phabricator-To##: this is attached to all mail Phabricator sends. | ||||
|   - `X-Phabricator-To`: this is attached to all mail Phabricator sends. | ||||
|     It shows the PHIDs of the original "To" line, before any mutation | ||||
|     by the mailer configuration. | ||||
|   - ##X-Phabricator-Cc##: this is attached to all mail Phabricator sends. | ||||
|   - `X-Phabricator-Cc`: this is attached to all mail Phabricator sends. | ||||
|     It shows the PHIDs of the original "Cc" line, before any mutation by the | ||||
|     mailer configuration. | ||||
|   - ##X-Differential-Author##: this is attached to Differential mail and shows | ||||
|   - `X-Differential-Author`: this is attached to Differential mail and shows | ||||
|     the revision's author. You can use it to filter mail about your revisions | ||||
|     (or other users' revisions). | ||||
|   - ##X-Differential-Reviewer##: this is attached to Differential mail and | ||||
|   - `X-Differential-Reviewer`: this is attached to Differential mail and | ||||
|     shows the reviewers. You can use it to filter mail about revisions you | ||||
|     are reviewing, versus revisions you are explicitly CC'd on or CC'd as | ||||
|     a result of Herald rules. | ||||
|   - ##X-Differential-Reviewers##: list version of the previous. | ||||
|   - ##X-Differential-CC##: this is attached to Differential mail and shows | ||||
|   - `X-Differential-Reviewers`: list version of the previous. | ||||
|   - `X-Differential-CC`: this is attached to Differential mail and shows | ||||
|     the CCs on the revision. | ||||
|   - ##X-Differential-CCs##: list version of the previous. | ||||
|   - ##X-Differential-Explicit-CC##: this is attached to Differential mail and | ||||
|   - `X-Differential-CCs`: list version of the previous. | ||||
|   - `X-Differential-Explicit-CC`: this is attached to Differential mail and | ||||
|     shows the explicit CCs on the revision (those that were added by humans, | ||||
|     not by Herald). | ||||
|   - ##X-Differential-Explicit-CCs##: list version of the previous. | ||||
|   - ##X-Phabricator-Mail-Tags##: this is attached to some mail and has | ||||
|   - `X-Differential-Explicit-CCs`: list version of the previous. | ||||
|   - `X-Phabricator-Mail-Tags`: this is attached to some mail and has | ||||
|     a list of descriptors about the mail. (This is fairly new and subject | ||||
|     to some change.) | ||||
|   - ##X-Herald-Rules##: this is attached to some mail and shows Herald rule | ||||
|   - `X-Herald-Rules`: this is attached to some mail and shows Herald rule | ||||
|     IDs which have triggered for the object. You can use this to sort or | ||||
|     categorize mail that has triggered specific rules. | ||||
|   | ||||
| @@ -61,7 +61,7 @@ identify and fix the problems pretty easily. | ||||
|  | ||||
| If you have a prohibitively large number of UTF-8 issues in your source code, | ||||
| Phabricator doesn't include any default tools to help you process them in a | ||||
| systematic way. You could hack up ##utf8.php## as a starting point, or use other | ||||
| systematic way. You could hack up `utf8.php` as a starting point, or use other | ||||
| tools to batch-process your source files. | ||||
|  | ||||
| = Support for Alternate Encodings = | ||||
|   | ||||
| @@ -52,18 +52,18 @@ The callback you pass to @{function:JX.behavior} should have this signature: | ||||
|  | ||||
| The function will be invoked once for each configuration dictionary passed to | ||||
| @{function:JX.initBehaviors}, and the dictionary will be passed as the | ||||
| ##config## parameter. For example, to alert the user that they've won two hogs: | ||||
| `config` parameter. For example, to alert the user that they've won two hogs: | ||||
|  | ||||
|   lang=js | ||||
|   JX.initBehaviors({ | ||||
|     "win-a-hog" : [{hogName : "Ethel"}, {hogName: "Beatrice"}] | ||||
|   }); | ||||
|  | ||||
| This will invoke the function twice, once for each ##config## dictionary. | ||||
| This will invoke the function twice, once for each `config` dictionary. | ||||
| Usually, you invoke a behavior multiple times if you have several similar | ||||
| controls on a page, like multiple @{class:JX.Tokenizer}s. | ||||
|  | ||||
| An initially empty object will be passed in the ##statics## parameter, but | ||||
| An initially empty object will be passed in the `statics` parameter, but | ||||
| changes to this object will persist across invocations of the behavior. For | ||||
| example: | ||||
|  | ||||
| @@ -142,7 +142,7 @@ code like this in order to address some of the other problems: | ||||
| By 2010 (particularly with the introduction of XHP) the API had become more | ||||
| sophisticated, but this is basically how most of Facebook's glue code still | ||||
| works as of mid-2011. If you view the source of any page, you'll see a bunch | ||||
| of ##onloadRegister()## calls in the markup which are generated like this. | ||||
| of `onloadRegister()` calls in the markup which are generated like this. | ||||
|  | ||||
| This mitigates many of the problems but is still fairly awkward. Escaping is | ||||
| easier, but still possible to get wrong. Stuff is a bit easier to grep for, but | ||||
| @@ -168,7 +168,7 @@ Javelin behaviors provide a more structured solution to some of these problems: | ||||
|   - The entire interface the server may invoke against can be readily inferred. | ||||
|  | ||||
| Note that Javelin does provide @{function:JX.onload}, which behaves like | ||||
| ##onloadRegister()##. However, its use is discouraged. | ||||
| `onloadRegister()`. However, its use is discouraged. | ||||
|  | ||||
| The two major downsides to the behavior design appear to be: | ||||
|  | ||||
|   | ||||
| @@ -111,10 +111,10 @@ parameter and listens only for events within that node: | ||||
|       // ... | ||||
|     }); | ||||
|  | ||||
| This is similar to setting ##node.onclick## or ##node.addEventListener##, but | ||||
| This is similar to setting `node.onclick` or `node.addEventListener`, but | ||||
| uses the Javelin delegation core. You can also provide a sigil set, which works | ||||
| just like @{method:JX.Stratcom.listen} general events. This is useful if your | ||||
| node is a container, like a ##<div />##, with a lot of stuff in it. | ||||
| node is a container, like a `<div />`, with a lot of stuff in it. | ||||
|  | ||||
|  | ||||
| = DOM Event Flow = | ||||
| @@ -144,7 +144,7 @@ before the listener subscribed to 'outer' | ||||
| = Listening to Class Events = | ||||
|  | ||||
| Beyond DOM events, you can also listen to class events. Every class installed | ||||
| by Javelin has static and instance methods called ##listen## (see | ||||
| by Javelin has static and instance methods called `listen` (see | ||||
| @{method:JX.Base.listen}). The static method allows you to listen for all events | ||||
| emitted by every instance of a class and its descendants: | ||||
|  | ||||
| @@ -172,14 +172,14 @@ specific instance: | ||||
| Javelin implements general delegation by building and comparing sigil sets. Some | ||||
| of these sigils are not DOM sigils, but derived from other things: | ||||
|  | ||||
|   - ##id:*## ID sigils are generated when an examined node has an "id" property. | ||||
|   - ##obj:*## Object sigils are generated when an event affects a class | ||||
|   - `id:*` ID sigils are generated when an examined node has an "id" property. | ||||
|   - `obj:*` Object sigils are generated when an event affects a class | ||||
|     instance. | ||||
|   - ##class:*## Class sigils are generated while walking an affected instance's | ||||
|   - `class:*` Class sigils are generated while walking an affected instance's | ||||
|     class chain. | ||||
|   - ##tag:*## Tag sigils are generated by examining the tag names of DOM nodes. | ||||
|   - `tag:*` Tag sigils are generated by examining the tag names of DOM nodes. | ||||
|  | ||||
| For instance, you can listen to all clicks on ##<a />## tags in a document like | ||||
| For instance, you can listen to all clicks on `<a />` tags in a document like | ||||
| this: | ||||
|  | ||||
|   lang=js | ||||
|   | ||||
| @@ -21,7 +21,7 @@ about the structure of the document. | ||||
| It is reasonable to think of sigils as being CSS class names in a different, | ||||
| semantic namespace. | ||||
|  | ||||
| If you're emitting raw tags, you specify sigils by adding a ##data-sigil## | ||||
| If you're emitting raw tags, you specify sigils by adding a `data-sigil` | ||||
| attribute to a node: | ||||
|  | ||||
|   lang=html | ||||
| @@ -94,7 +94,7 @@ This calls the function you provide when the user clicks on a "like" link, but | ||||
| you need to be able to distinguish between the different links so you can know | ||||
| which story the user is trying to like. Javelin allows you to do this by | ||||
| attaching **metadata** to each node. Metadata is attached to a node by adding a | ||||
| ##data-meta## attribute which has an index into data later provided to | ||||
| `data-meta` attribute which has an index into data later provided to | ||||
| @{method:JX.Stratcom.mergeData}: | ||||
|  | ||||
|   lang=html | ||||
|   | ||||
| @@ -8,9 +8,9 @@ Information specific to Javelin at Facebook. | ||||
| Javelin now ships with the source to build several libfbjs-based binaries, which | ||||
| serve to completely sever its dependencies on trunk: | ||||
|  | ||||
|   - ##javelinsymbols##: used for lint | ||||
|   - ##jsast##: used for documentation generation | ||||
|   - ##jsxmin##: used to crush packages | ||||
|   - `javelinsymbols`: used for lint | ||||
|   - `jsast`: used for documentation generation | ||||
|   - `jsxmin`: used to crush packages | ||||
|  | ||||
| To build these, first build libfbjs: | ||||
|  | ||||
| @@ -36,8 +36,8 @@ To synchronize Javelin **from** Facebook trunk, run the synchronize script: | ||||
|  | ||||
|   javelin/ $ ./scripts/sync-from-facebook.php ~/www | ||||
|  | ||||
| ...where ##~/www## is the root you want to pull Javelin files from. The script | ||||
| will copy files out of ##html/js/javelin## and build packages, and leave the | ||||
| ...where `~/www` is the root you want to pull Javelin files from. The script | ||||
| will copy files out of `html/js/javelin` and build packages, and leave the | ||||
| results in your working copy. From there you can review changes and commit, and | ||||
| then push, diff, or send a pull request. | ||||
|  | ||||
| @@ -46,18 +46,18 @@ script: | ||||
|  | ||||
|   javelin/ $ ./scripts/sync-to-facebook.php ~/www | ||||
|  | ||||
| ...where ##~/www## is the root you want to push Javelin files to. The script | ||||
| will copy files out of the working copy into your ##www## and leave you with a | ||||
| dirty ##www##. From there you can review changes. | ||||
| ...where `~/www` is the root you want to push Javelin files to. The script | ||||
| will copy files out of the working copy into your `www` and leave you with a | ||||
| dirty `www`. From there you can review changes. | ||||
|  | ||||
| Once Facebook moves to pure git for ##www## we can probably just submodule | ||||
| Once Facebook moves to pure git for `www` we can probably just submodule | ||||
| Javelin into it and get rid of all this nonsense, but the mixed SVN/git | ||||
| environment makes that difficult until then. | ||||
|  | ||||
| = Building Documentation = | ||||
|  | ||||
| Check out ##diviner## and ##libphutil## from Facebook github, and put them in a | ||||
| directory with ##javelin##: | ||||
| Check out `diviner` and `libphutil` from Facebook github, and put them in a | ||||
| directory with `javelin`: | ||||
|  | ||||
|   somewhere/ $ ls | ||||
|   diviner/ | ||||
| @@ -65,7 +65,7 @@ directory with ##javelin##: | ||||
|   libphutil/ | ||||
|   somewhere/ $ | ||||
|  | ||||
| Now run ##diviner## on ##javelin##: | ||||
| Now run `diviner` on `javelin`: | ||||
|  | ||||
|   somewhere/ $ cd javelin | ||||
|   somewhere/javelin/ $ ../diviner/bin/diviner . | ||||
| @@ -73,10 +73,10 @@ Now run ##diviner## on ##javelin##: | ||||
|   [JavelinDivinerEngine] Generating documentation for 74 files... | ||||
|   somewhere/javelin/ $ | ||||
|  | ||||
| Documentation is now available in ##javelin/docs/##. | ||||
| Documentation is now available in `javelin/docs/`. | ||||
|  | ||||
| = Editing javelinjs.com = | ||||
|  | ||||
| The source for javelinjs.com lives in ##javelin/support/webroot/##. The site | ||||
| The source for javelinjs.com lives in `javelin/support/webroot/`. The site | ||||
| itself is served off the phabricator.com host. You need access to that host to | ||||
| push it. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Joshua Spence
					Joshua Spence