diff --git a/docs/dev/cpp-code-conventions.md b/docs/dev/cpp-code-conventions.md new file mode 100644 index 000000000..8610a87ed --- /dev/null +++ b/docs/dev/cpp-code-conventions.md @@ -0,0 +1,193 @@ +# C++ Code Conventions + +This chapter describes code conventions which should be followed when writing +C++ code. + +## Code Style + +Memgraph uses the Google Style Guide for C++ in most of its code. You should +follow them whenever writing new code. The style guide can be found +[here](https://google.github.io/styleguide/cppguide.html). + +### Additional Style Conventions + +Code style conventions which are left undefined by Google are specified here. + +#### Template parameter naming + +Template parameter names should start with capital letter 'T' followed by a +short descriptive name. For example: + +```cpp +template <typename TKey, typename TValue> +class KeyValueStore +``` + +## Code Formatting + +You should install `clang-format` and run it on code you change or add. The +root of Memgraph's project contains the `.clang-format` file, which specifies +how formatting should behave. Running `clang-format -style=file` in the +project's root will read the file and behave as expected. For ease of use, you +should integrate formatting with your favourite editor. + +The code formatting isn't enforced, because sometimes manual formatting may +produce better results. Though, running `clang-format` is strongly encouraged. + +## Documentation + +Besides following the comment guidelines from [Google Style +Guide](https://google.github.io/styleguide/cppguide.html#Comments), your +documentation of the public API should be +[Doxygen](https://github.com/doxygen/doxygen) compatible. For private parts of +the code or for comments accompanying the implementation, you are free to +break doxygen compatibility. In both cases, you should write your +documentation as full sentences, correctly written in English. + +## Doxygen + +To start a Doxygen compatible documentation string, you should open your +comment with either a JavaDoc style block comment (`/**`) or a line comment +containing 3 slashes (`///`). Take a look at the 2 examples below. + +### Block Comment + +```cpp +/** + * One sentence, brief description. + * + * Long form description. + */ +``` + +### Line Comment + +```cpp +/// +/// One sentence, brief description. +/// +/// Long form description. +/// +``` + +If you only have a brief description, you may collapse the documentation into +a single line. + +### Block Comment + +```cpp +/** Brief description. */ +``` + +### Line Comment + +```cpp +/// Brief description. +``` + +Whichever style you choose, keep it consistent across the whole file. + +Doxygen supports various commands in comments, such as `@file` and `@param`. +These help Doxygen to render specified things differently or to track them for +cross referencing. If you want to learn more, take a look at these two links: + + * http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html + * http://www.stack.nl/~dimitri/doxygen/manual/commands.html + +## Examples + +Below are a few examples of documentation from the codebase. + +### Function + +```cpp +/** + * Removes whitespace characters from the start and from the end of a string. + * + * @param s String that is going to be trimmed. + * + * @return Trimmed string. + */ +inline std::string Trim(const std::string &s); +``` + +### Class + +```cpp +/** Base class for logical operators. + * + * Each operator describes an operation, which is to be performed on the + * database. Operators are iterated over using a @c Cursor. Various operators + * can serve as inputs to others and thus a sequence of operations is formed. + */ +class LogicalOperator + : public ::utils::Visitable<HierarchicalLogicalOperatorVisitor> { + public: + /** Constructs a @c Cursor which is used to run this operator. + * + * @param GraphDbAccessor Used to perform operations on the database. + */ + virtual std::unique_ptr<Cursor> MakeCursor(GraphDbAccessor &db) const = 0; + + /** Return @c Symbol vector where the results will be stored. + * + * Currently, outputs symbols are only generated in @c Produce operator. + * @c Skip, @c Limit and @c OrderBy propagate the symbols from @c Produce (if + * it exists as input operator). In the future, we may want this method to + * return the symbols that will be set in this operator. + * + * @param SymbolTable used to find symbols for expressions. + * @return std::vector<Symbol> used for results. + */ + virtual std::vector<Symbol> OutputSymbols(const SymbolTable &) const { + return std::vector<Symbol>(); + } + + virtual ~LogicalOperator() {} +}; +``` + +### File Header + +```cpp +/// @file visitor.hpp +/// +/// This file contains the generic implementation of visitor pattern. +/// +/// There are 2 approaches to the pattern: +/// +/// * classic visitor pattern using @c Accept and @c Visit methods, and +/// * hierarchical visitor which also uses @c PreVisit and @c PostVisit +/// methods. +/// +/// Classic Visitor +/// =============== +/// +/// Explanation on the classic visitor pattern can be found from many +/// sources, but here is the link to hopefully most easily accessible +/// information: https://en.wikipedia.org/wiki/Visitor_pattern +/// +/// The idea behind the generic implementation of classic visitor pattern is to +/// allow returning any type via @c Accept and @c Visit methods. Traversing the +/// class hierarchy is relegated to the visitor classes. Therefore, visitor +/// should call @c Accept on children when visiting their parents. To implement +/// such a visitor refer to @c Visitor and @c Visitable classes. +/// +/// Hierarchical Visitor +/// ==================== +/// +/// Unlike the classic visitor, the intent of this design is to allow the +/// visited structure itself to control the traversal. This way the internal +/// children structure of classes can remain private. On the other hand, +/// visitors may want to differentiate visiting composite types from leaf types. +/// Composite types are those which contain visitable children, unlike the leaf +/// nodes. Differentiation is accomplished by providing @c PreVisit and @c +/// PostVisit methods, which should be called inside @c Accept of composite +/// types. Regular @c Visit is only called inside @c Accept of leaf types. +/// To implement such a visitor refer to @c CompositeVisitor, @c LeafVisitor and +/// @c Visitable classes. +/// +/// Implementation of hierarchical visiting is modelled after: +/// http://wiki.c2.com/?HierarchicalVisitorPattern +``` + diff --git a/docs/dev/quick-start.md b/docs/dev/quick-start.md new file mode 100644 index 000000000..9aa4eec36 --- /dev/null +++ b/docs/dev/quick-start.md @@ -0,0 +1,78 @@ +# Quick Start + +A short chapter on downloading the Memgraph source, compiling and running. + +## Obtaining the Source Code + +Memgraph uses `git` for source version control. You will need to install `git` +on your machine before you can download the source code. + +On Debian systems, you can do it inside a terminal with the following +command: + + sudo apt-get install git + +On ArchLinux or Gentoo, you probably already know what to do. + +After installing `git`, you are now ready to fetch your own copy of Memgraph +source code. Run the following command: + + git clone https://phabricator.memgraph.io/diffusion/MG/memgraph.git + +The above will create a `memgraph` directory and put all source code there. + +## Compiling Memgraph + +With the source code, you are now ready to compile Memgraph. Well... Not +quite. You'll need to download Memgraph's dependencies first. + +In your terminal, position yourself in the obtained memgraph directory. + + cd memgraph + +### Installing Dependencies + +On Debian systems, all of the dependencies should be setup by running the +`init` script: + + ./init -s + +Currently, other systems aren't supported in the `init` script. But you can +issue the needed steps manually. First run the `init` script. + + ./init + +The script will output the required packages, which you should be able to +install via your favorite package manager. For example, `pacman` on ArchLinux. +After installing the packages, issue the following commands: + + mkdir -p build + ./libs/setups.sh + +### Compiling + +With all of the dependencies installed, you need to configure the build +system. To do that, execute the following: + + cd build + cmake .. + +If everything went OK, you can now, finally, compile Memgraph. + + make -j$(nproc) + +### Running + +After the compilation verify that Memgraph works: + + ./memgraph --version + +To make extra sure, run the unit tests: + + ctest -R unit -j$(nproc) + +## Problems + +If you have any trouble running the above commands, contact your nearest +developer who successfully built Memgraph. Ask for help and insist on getting +this document updated with correct steps! diff --git a/docs/dev/workflow.md b/docs/dev/workflow.md new file mode 100644 index 000000000..62f2839c3 --- /dev/null +++ b/docs/dev/workflow.md @@ -0,0 +1,177 @@ +# Memgraph Workflow + +This chapter describes the usual workflow for working on Memgraph. + +## Git + +Memgraph uses [git](https://git-scm.com/) for source version control. If you +obtained the source, you probably already have it installed. Before you can +track new changes, you need to setup some basic information. + +First, tell git your name: + + git config --global user.name "FirstName LastName" + +Then, set your Memgraph email: + + git config --global user.email "my.email@memgraph.com" + +Finally, make git aware of your favourite editor: + + git config --global core.editor "vim" + +## Phabricator + +All of the code in Memgraph needs to go through code review before it can be +accepted in the codebase. This is done through +[Phabricator](https://phacility.com/phabricator/). The command line tool for +interfacing with Phabricator is +[arcanist](https://phacility.com/phabricator/arcanist/). You should already +have it installed if you followed the steps in [Quick Start](quick-start.md). + +The only required setup is to go in the root of Memgraph's project and run: + + arc install-certificate + +## Working on Your Feature Branch + +Git has a concept of source code *branches*. The `master` branch contains all +of the changes which were reviewed and accepted in Memgraph's code base. The +`master` branch is selected by default. + +### Creating a Branch + +When working on a new feature or fixing a bug, you should create a new branch +out of the `master` branch. For example, let's say you are adding static type +checking to the query language compiler. You would create a branch called +`mg_query_static_typing` with the following command: + + git branch mg_query_static_typing + +To switch to that branch, type: + + git checkout mg_query_static_typing + +Since doing these two steps will happen often, you can use a shortcut command: + + git checkout -b mg_query_static_typing + +Note that a branch is created from the currently selected branch. So, if you +wish to create another branch from `master` you need to switch to `master` +first. + +The usual convention for naming your branches is `mg_<feature_name>`, you may +switch underscores ('\_') for hyphens ('-'). + +Do take care not to mix the case of your branch names! Certain operating +systems (like Windows) don't distinguish the casing in git branches. This may +cause hard to track down issues when trying to switch branches. Therefore, you +should always name your branches with lowercase letters. + +### Making and Committing Changes + +When you have a branch for your new addition, you can now actually start +implementing it. After some amount of time, you may have created new files, +modified others and maybe even deleted unused files. You need to tell git to +track those changes. This is accomplished with `git add` and `git rm` +commands. + + git add path-to-new-file path-to-modified-file + git rm path-to-deleted-file + +To check that everything is correctly tracked, you may use the `git status` +command. It will also print the name of the currently selected branch. + +If everything seems OK, you should commit these changes to git. + + git commit + +You will be presented with an editor where you need to type the commit +message. Writing a good commit message is an art in itself. You should take a +look at the links below. We try to follow these conventions as much as +possible. + + * [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) + * [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) + * [stopwritingramblingcommitmessages](http://stopwritingramblingcommitmessages.com/) + +### Sending Changes on a Review + +After finishing your work on your feature branch, you will want to send it on +code review. This is done through Arcanist. To do that, run the following +command: + + arc diff + +You will, once again, be presented with an editor where you need to describe +your whole work. `arc` will by default fill that description with your commit +messages. The title and summary of your work should also follow the +conventions of git messages as described above. If you followed the +guidelines, the message filled by `arc` should be fine. + +In addition to the message, you need to fill the `Reviewers:` line with +usernames of people who should do the code review. + +You changes will be visible on Phabricator as a so called "diff". You can find +the default view of active diffs +[here](https://phabricator.memgraph.io/differential/) + +### Updating Changes Based on Review + +When you get comments in the code review, you will want to make additional +modifications to your work. The same workflow as before applies: [Making and +Committing Changes](#making-and-committing-changes) + +After making those changes, send them back on code review: + + arc diff + + +### Updating From New Master + +Let's say that, while you were working, someone else added some new features +to the codebase that you would like to use in your current work. To obtain +those changes you should update your `master` branch: + + git checkout master + git pull origin master + +Now, these changes are on `master`, but you want them in your local branch. To +do that, use `git rebase`: + + git checkout mg_query_static_typing + git rebase master + +During `git rebase`, you may get reports that some files have conflicting +changes. If you need help resolving them, don't be afraid to ask around! After +you've resolved them, mark them as done with `git add` command. You may +then continue with `git rebase --continue`. + +After the `git rebase` is done, you will now have new changes from `master` on +your feature branch as if you just created and started working on that branch. +You may continue with the usual workflow of [Making and Committing +Changes](#making-and-committing-changes) and [Sending Changes on a +Review](#sending-changes-on-a-review). + +### Sending Your Changes on Master Branch + +When your changes pass the code review, you are ready to integrate them in the +`master` branch. To do that, run the following command: + + arc land + +Arcanist will take care of obtaining the latest changes from `master` and +merging your changes on top. If the `land` was successful, Arcanist will +delete your local branch and you will be back on `master`. Continuing from the +examples above, the deleted branch would be `mg_query_static_typing`. + +This marks the completion of your changes, and you are ready to work on +something else. + +### Note For People Familiar With Git + +Since Arcanist takes care of merging your git commits and pushing them on +`master`, you should *never* have to call `git merge` and `git push`. If you +find yourself typing those commands, check that you are doing the right thing. +The most common mistake is to use `git merge` instead of `git rebase` for the +case described in [Updating From New Master](#updating-from-new-master).