From 442ec5d4f1760c0f73e708ab8125e7f8e53e4fc1 Mon Sep 17 00:00:00 2001 From: Paul Tan Date: Wed, 6 Dec 2017 13:36:09 +0800 Subject: [PATCH 1/4] DeveloperGuide, UserGuide: use full xrefstyle By default, the cross-reference text when cross-referencing another section, figure, table etc. will be the title of that section, figure, table etc. For example, the following cross-reference in the DeveloperGuide: <> will be replaced with: Architecture which is the name of that section. However, in a printed or non-interactive medium, cross-reference hyperlinks do not work. As such, it would be more useful to provide the section/figure/table number as well, so that readers will be able to quickly locate the reference target by its number, rather than needing to manually find its name in the document. As such, lets set the xrefstyle of the UserGuide and DeveloperGuide to `full`. With this change, the <> cross-reference would be replaced with: Section 2.1, "Architecture" As the xrefstyle feature[1] was only introduced in asciidoctor 1.5.6[2], we'll need to upgrade our asciidoctor plugin as well. [1] http://asciidoctor.org/docs/user-manual/#customizing-the-cross-reference-text [2] https://github.com/asciidoctor/asciidoctor/commit/8e80317dee56483e48a07451bff0cd14f0bfd59c --- build.gradle | 2 +- docs/DeveloperGuide.adoc | 1 + docs/UserGuide.adoc | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 912e03b1fdb1..80147c4c1ead 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { id 'checkstyle' id "com.github.kt3k.coveralls" version "2.4.0" id "com.github.johnrengelman.shadow" version '1.2.3' - id 'org.asciidoctor.convert' version '1.5.3' + id 'org.asciidoctor.convert' version '1.5.6' id 'application' } diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 13d9fcd6050e..48e07c06f2f3 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -5,6 +5,7 @@ :sectnums: :imagesDir: images :stylesDir: stylesheets +:xrefstyle: full ifdef::env-github[] :tip-caption: :bulb: :note-caption: :information_source: diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 87f4cd6ab596..2ca85544a26b 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -5,6 +5,7 @@ :sectnums: :imagesDir: images :stylesDir: stylesheets +:xrefstyle: full :experimental: ifdef::env-github[] :tip-caption: :bulb: From 230a27eead6da49f4e3c4a31a8d913454dc4968e Mon Sep 17 00:00:00 2001 From: Paul Tan Date: Wed, 6 Dec 2017 22:58:48 +0800 Subject: [PATCH 2/4] DeveloperGuide, UserGuide: use cross references instead of manual links The UserGuide and DeveloperGuide contains many links to other sections in the document. However, these links are written using the link: syntax rather than using the cross reference syntax. In many cases, the link text simply repeats the title of the referenced section. Such uses result in unnecessary verbosity, and are also fragile since someone who modifies the title of the referenced section could easily forget to change the link text of links referencing that section as well. Let's fix this by changing the links to use the cross reference syntax instead, which provide automatic link text, so we do not need to repeat the section titles. If the anchor IDs of the referenced sections change, it would lead to dead links as well. As such, let's also give the referenced sections explicit anchor IDs to make sure they do not change. --- docs/DeveloperGuide.adoc | 45 +++++++++++++++++++++++++--------------- docs/UserGuide.adoc | 3 ++- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 48e07c06f2f3..7a3c28eb45d5 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -49,7 +49,7 @@ This will generate all resources required by the application and tests. === Verifying the setup . Run the `seedu.address.MainApp` and try a few commands -. link:#testing[Run the tests] to ensure they all pass. +. <> to ensure they all pass. === Configurations to do before writing code @@ -83,11 +83,12 @@ Having both Travis and AppVeyor ensures your App works on both Unix-based platfo When you are ready to start coding, -1. Get some sense of the overall design by reading the link:#architecture[Architecture] section. -2. Take a look at the section link:#suggested-programming-tasks-to-get-started[Suggested Programming Tasks to Get Started]. +1. Get some sense of the overall design by reading <>. +2. Take a look at <>. == Design +[[Design-Architecture]] === Architecture image::Architecture.png[width="600"] @@ -103,17 +104,17 @@ The `.pptx` files used to create diagrams in this document can be found in the l * At app launch: Initializes the components in the correct sequence, and connects them up with each other. * At shut down: Shuts down the components and invokes cleanup method where necessary. -link:#common-classes[*`Commons`*] represents a collection of classes used by multiple other components. Two of those classes play important roles at the architecture level. +<> represents a collection of classes used by multiple other components. Two of those classes play important roles at the architecture level. * `EventsCenter` : This class (written using https://github.com/google/guava/wiki/EventBusExplained[Google's Event Bus library]) is used by components to communicate with other components using events (i.e. a form of _Event Driven_ design) * `LogsCenter` : Used by many classes to write log messages to the App's log file. The rest of the App consists of four components. -* link:#ui-component[*`UI`*] : The UI of the App. -* link:#logic-component[*`Logic`*] : The command executor. -* link:#model-component[*`Model`*] : Holds the data of the App in-memory. -* link:#storage-component[*`Storage`*] : Reads data from, and writes data to, the hard disk. +* <>: The UI of the App. +* <>: The command executor. +* <>: Holds the data of the App in-memory. +* <>: Reads data from, and writes data to, the hard disk. Each of the four components @@ -146,6 +147,7 @@ Note how the event is propagated through the `EventsCenter` to the `Storage` and The sections below give more details of each component. +[[Design-Ui]] === UI component image::UiClassDiagram.png[width="800"] @@ -163,6 +165,7 @@ The `UI` component, * Binds itself to some data in the `Model` so that the UI can auto-update when data in the `Model` change. * Responds to events raised from various parts of the App and updates the UI accordingly. +[[Design-Logic]] === Logic component image::LogicClassDiagram.png[width="800"] @@ -184,6 +187,7 @@ Given below is the Sequence Diagram for interactions within the `Logic` componen image::DeletePersonSdForLogic.png[width="800"] _Figure 2.3.1 : Interactions Inside the Logic Component for the `delete 1` Command_ +[[Design-Model]] === Model component image::ModelClassDiagram.png[width="800"] @@ -198,6 +202,7 @@ The `Model`, * exposes an unmodifiable `ObservableList` that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. * does not depend on any of the other three components. +[[Design-Storage]] === Storage component image::StorageClassDiagram.png[width="800"] @@ -210,6 +215,7 @@ The `Storage` component, * can save `UserPref` objects in json format and read it back. * can save the Address Book data in xml format and read it back. +[[Design-Commons]] === Common classes Classes used by multiple components are in the `seedu.addressbook.commons` package. @@ -349,7 +355,7 @@ image::UndoRedoActivityDiagram.png[width="200"] We are using `java.util.logging` package for logging. The `LogsCenter` class is used to manage the logging levels and logging destinations. -* The logging level can be controlled using the `logLevel` setting in the configuration file (See link:#configuration[Configuration]) +* The logging level can be controlled using the `logLevel` setting in the configuration file (See <>) * The `Logger` for a class can be obtained using `LogsCenter.getLogger(Class)` which will log messages according to the specified logging level * Currently log messages are output through: `Console` and to a `.log` file. @@ -360,6 +366,7 @@ We are using `java.util.logging` package for logging. The `LogsCenter` class is * `INFO` : Information showing the noteworthy actions by the App * `FINE` : Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size +[[Implementation-Configuration]] === Configuration Certain properties of the application can be controlled (e.g App name, logging level) through the configuration file (default: `config.json`). @@ -394,6 +401,7 @@ Here are the steps to convert the project documentation files to PDF format. image::chrome_save_as_pdf.png[width="300"] _Figure 5.6.1 : Saving documentation as PDF files in Chrome_ +[[Testing]] == Testing === Running Tests @@ -468,15 +476,17 @@ A project often depends on third-party libraries. For example, Address Book depe a. Include those libraries in the repo (this bloats the repo size) + b. Require developers to download those libraries manually (this creates extra work for developers) +[[GetStartedProgramming]] [appendix] == Suggested Programming Tasks to Get Started Suggested path for new programmers: -1. First, add small local-impact (i.e. the impact of the change does not go beyond the component) enhancements to one component at a time. Some suggestions are given in this section link:#improving-each-component[Improving a Component]. +1. First, add small local-impact (i.e. the impact of the change does not go beyond the component) enhancements to one component at a time. Some suggestions are given in <>. -2. Next, add a feature that touches multiple components to learn how to implement an end-to-end feature across all components. The section link:#creating-a-new-command-code-remark-code[Creating a new command: `remark`] explains how to go about adding such a feature. +2. Next, add a feature that touches multiple components to learn how to implement an end-to-end feature across all components. <> explains how to go about adding such a feature. +[[GetStartedProgramming-EachComponent]] === Improving each component Each individual exercise in this section is component-based (i.e. you would not need to modify the other components to get it to work). @@ -485,7 +495,7 @@ Each individual exercise in this section is component-based (i.e. you would not ==== `Logic` component [TIP] -Do take a look at the link:#logic-component[Design: Logic Component] section before attempting to modify the `Logic` component. +Do take a look at <> before attempting to modify the `Logic` component. . Add a shorthand equivalent alias for each of the individual commands. For example, besides typing `clear`, the user can also type `c` to remove all persons in the list. + @@ -502,7 +512,7 @@ Do take a look at the link:#logic-component[Design: Logic Component] section bef ==== `Model` component [TIP] -Do take a look at the link:#model-component[Design: Model Component] section before attempting to modify the `Model` component. +Do take a look at <> before attempting to modify the `Model` component. . Add a `removeTag(Tag)` method. The specified tag will be removed from everyone in the address book. + @@ -519,7 +529,7 @@ Do take a look at the link:#model-component[Design: Model Component] section bef ==== `Ui` component [TIP] -Do take a look at the link:#ui-component[Design: UI Component] section before attempting to modify the `UI` component. +Do take a look at <> before attempting to modify the `UI` component. . Use different colors for different tags inside person cards. For example, `friends` tags can be all in grey, and `colleagues` tags can be all in red. + @@ -583,7 +593,7 @@ image::getting-started-ui-status-after.png[width="500"] ==== `Storage` component [TIP] -Do take a look at the link:#storage-component[Design: Storage Component] section before attempting to modify the `Storage` component. +Do take a look at <> before attempting to modify the `Storage` component. . Add a new method `backupAddressBook(ReadOnlyAddressBook)`, so that the address book can be saved in a fixed temporary location. + @@ -595,6 +605,7 @@ Do take a look at the link:#storage-component[Design: Storage Component] section ** See this https://github.com/se-edu/addressbook-level4/pull/594/files[PR] for the full solution. **** +[[GetStartedProgramming-RemarkCommand]] === Creating a new command: `remark` By creating this command, you will get a chance to learn how to implement a feature end-to-end, touching all major components of the app. @@ -729,7 +740,7 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un |`* * *` |user |find a person by name |locate details of persons without having to go through the entire list -|`* *` |user |hide link:#private-contact-detail[private contact details] by default |minimize chance of someone else seeing them by accident +|`* *` |user |hide <> by default |minimize chance of someone else seeing them by accident |`*` |user with many persons in the address book |sort persons by name |locate a person easily |======================================================================= @@ -772,7 +783,7 @@ Use case resumes at step 2. [appendix] == Non Functional Requirements -. Should work on any link:#mainstream-os[mainstream OS] as long as it has Java `1.8.0_60` or higher installed. +. Should work on any <> as long as it has Java `1.8.0_60` or higher installed. . Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage. . A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse. diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 2ca85544a26b..1414966336f5 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -38,8 +38,9 @@ e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. * **`delete`**`3` : deletes the 3rd contact shown in the current list * *`exit`* : exits the app -. Refer to the link:#features[Features] section below for details of each command. +. Refer to <> for details of each command. +[[Features]] == Features ==== From 8628533e989e3a52358a8cb79c65dd3a6ac522c1 Mon Sep 17 00:00:00 2001 From: Paul Tan Date: Wed, 6 Dec 2017 13:33:33 +0800 Subject: [PATCH 3/4] DeveloperGuide: use proper syntax for figure captions The DeveloperGuide manually numbers each figure. Such manually numbering of figures is error prone and leads to a problem where inserting a figure between two other figures causes a "snowball" effect where all subsequent figure numbers needs to be updated, which pollutes the commit diff. As such, let's switch to using asciidoctor's automatic figure numbering instead, which kicks in when we switch to using the proper syntax for figure captions -- by defining the caption text as the title of the block image[1]. As a side benefit of using the figure caption syntax, we can now also use the cross reference syntax to reference other figures, which will give us the desired behavior of referencing that figure with the correct figure number. One downside of this approach is that the automatic figure numbers are not hierarchical, i.e. they just go 1, 2, 3... without taking the section numbers into account. However, the upside of not having to manually update figure numbers is much more valuable. [1] http://asciidoctor.org/docs/user-manual/#images --- docs/DeveloperGuide.adoc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 7a3c28eb45d5..bb453e57270d 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -91,8 +91,8 @@ When you are ready to start coding, [[Design-Architecture]] === Architecture +.Architecture Diagram image::Architecture.png[width="600"] -_Figure 2.1.1 : Architecture Diagram_ The *_Architecture Diagram_* given above explains the high-level design of the App. Given below is a quick overview of each component. @@ -123,24 +123,24 @@ Each of the four components For example, the `Logic` component (see the class diagram given below) defines it's API in the `Logic.java` interface and exposes its functionality using the `LogicManager.java` class. +.Class Diagram of the Logic Component image::LogicClassDiagram.png[width="800"] -_Figure 2.1.2 : Class Diagram of the Logic Component_ [discrete] ==== Events-Driven nature of the design The _Sequence Diagram_ below shows how the components interact for the scenario where the user issues the command `delete 1`. +.Component interactions for `delete 1` command (part 1) image::SDforDeletePerson.png[width="800"] -_Figure 2.1.3a : Component interactions for `delete 1` command (part 1)_ [NOTE] Note how the `Model` simply raises a `AddressBookChangedEvent` when the Address Book data are changed, instead of asking the `Storage` to save the updates to the hard disk. The diagram below shows how the `EventsCenter` reacts to that event, which eventually results in the updates being saved to the hard disk and the status bar of the UI being updated to reflect the 'Last Updated' time. +.Component interactions for `delete 1` command (part 2) image::SDforDeletePersonEventHandling.png[width="800"] -_Figure 2.1.3b : Component interactions for `delete 1` command (part 2)_ [NOTE] Note how the event is propagated through the `EventsCenter` to the `Storage` and `UI` without `Model` having to be coupled to either of them. This is an example of how this Event Driven approach helps us reduce direct coupling between components. @@ -150,8 +150,8 @@ The sections below give more details of each component. [[Design-Ui]] === UI component +.Structure of the UI Component image::UiClassDiagram.png[width="800"] -_Figure 2.2.1 : Structure of the UI Component_ *API* : link:{repoURL}/src/main/java/seedu/address/ui/Ui.java[`Ui.java`] @@ -168,11 +168,12 @@ The `UI` component, [[Design-Logic]] === Logic component +[[fig-LogicClassDiagram]] +.Structure of the Logic Component image::LogicClassDiagram.png[width="800"] -_Figure 2.3.1 : Structure of the Logic Component_ +.Structure of Commands in the Logic Component. This diagram shows finer details concerning `XYZCommand` and `Command` in <> image::LogicCommandClassDiagram.png[width="800"] -_Figure 2.3.2 : Structure of Commands in the Logic Component. This diagram shows finer details concerning `XYZCommand` and `Command` in Figure 2.3.1_ *API* : link:{repoURL}/src/main/java/seedu/address/logic/Logic.java[`Logic.java`] @@ -184,14 +185,14 @@ link:{repoURL}/src/main/java/seedu/address/logic/Logic.java[`Logic.java`] Given below is the Sequence Diagram for interactions within the `Logic` component for the `execute("delete 1")` API call. +.Interactions Inside the Logic Component for the `delete 1` Command image::DeletePersonSdForLogic.png[width="800"] -_Figure 2.3.1 : Interactions Inside the Logic Component for the `delete 1` Command_ [[Design-Model]] === Model component +.Structure of the Model Component image::ModelClassDiagram.png[width="800"] -_Figure 2.4.1 : Structure of the Model Component_ *API* : link:{repoURL}/src/main/java/seedu/address/model/Model.java[`Model.java`] @@ -205,8 +206,8 @@ The `Model`, [[Design-Storage]] === Storage component +.Structure of the Storage Component image::StorageClassDiagram.png[width="800"] -_Figure 2.5.1 : Structure of the Storage Component_ *API* : link:{repoURL}/src/main/java/seedu/address/storage/Storage.java[`Storage.java`] @@ -398,8 +399,8 @@ Here are the steps to convert the project documentation files to PDF format. . Within Chrome, click on the `Print` option in Chrome's menu. . Set the destination to `Save as PDF`, then click `Save` to save a copy of the file in PDF format. For best results, use the settings indicated in the screenshot below. +.Saving documentation as PDF files in Chrome image::chrome_save_as_pdf.png[width="300"] -_Figure 5.6.1 : Saving documentation as PDF files in Chrome_ [[Testing]] == Testing From 85225ab61e1cf2285cb482e5c9282f8821417bc2 Mon Sep 17 00:00:00 2001 From: Paul Tan Date: Sat, 9 Dec 2017 21:15:55 +0800 Subject: [PATCH 4/4] Setup CircleCI for previewing documentation changes When submitting a PR with changes to the documentation, it would be useful to give the reviewer a way to easily see the results of the changes in the built HTML documentation so that they do not need to build the documentation themselves. Presently, this is usually done by: (1) adding screenshots highlighting the changes to the reviewer, or (2) temporarily hosting the built documentation somewhere. For (1), screenshots may not paint a complete picture of the impact of the changes (e.g. whther link anchors in a HTML file work properly or not), and so a reviewer might need the *whole* website in order to give a good assessment of the changes. On the other hand, (2) requires quite a bit of effort on the PR author's part, and there is always the concern that the hosted website may not be kept updated with the actual changes in the PR. So, we need a solution that builds the PR just like AppVeyor and Travis CI does, but stores the built documentation and hosts it somewhere for reviewers to look at. Something like AppVeyor's build artifacts feature. However, while AppVeyor does allow us to store build artifacts, it does not serve the hosted artifacts with the correct MIME type. Visitors to those files will simply be prompted by their web browser to download the file. Travis CI does not support storing build artifacts, requiring them to be uploaded to another service such as Amazon S3. As such, we will need to find another way. CircleCI[1] is a popular CI service that does provide what we want. Our builds can upload build artifacts, and CircleCI will serve them with the correct MIME type, allowing reviewers to easily browse the built documentation files via their web browser. So, let's add a CircleCI config file to our repo telling CircleCI how to build our documentation, and store it as a build artifact. Reviewers can then view the built documentation by navigating to the build job page, clicking on the "Artifacts" tab and then clicking on the file they want to view. Why not run tests as well? Well, there is a slight problem: CircleCI's free plan only gives us 1500 minutes of build time, and our full build + tests presently take around 3 minutes to run (and might increase in the future as more system tests are added). So, considering the fact that we will setup CircleCI to run on all our PRs, and some developers might prefer to use our CIs rather than running tests locally on their own computers, this 1500 minutes limit might be problematic for us. As such, for now, we'll just configure CircleCI to only build our documentation, so that builds complete much faster (around 30s). We have Travis CI to run our tests, anyway. [1] https://circleci.com/ --- .circleci/config.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000000..a97fcbfb8abb --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,36 @@ +# CircleCI configuration file +# For more details see https://circleci.com/docs/2.0/ + +version: 2 +jobs: + build: + docker: + - image: openjdk:8-jdk + working_directory: ~/project + steps: + - checkout + - run: + name: Setup environment variables + command: echo 'export TERM=dumb' >>"$BASH_ENV" + - restore_cache: + keys: + # Increment the version number e.g. v2-gradle-cache-... + # to force the caches to be "invalidated". + - v1-gradle-cache-{{ checksum "build.gradle" }} + - v1-gradle-cache- + - run: + name: Build documentation + command: ./gradlew clean asciidoctor + - store_artifacts: + path: ~/project/build/docs/html5 + destination: docs + - run: + name: Cleanup for save_cache + command: >- + rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + - save_cache: + key: v1-gradle-cache-{{ checksum "build.gradle" }} + paths: + - ~/.gradle/caches + - ~/.gradle/wrapper