Mercurial > template
changeset 0:a8462a503697
Initial import
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 31 Jan 2017 21:51:25 +0100 |
parents | |
children | 9bf9b4634339 |
files | CHANGES.md CONTRIBUTE.md CREDITS.md INSTALL.md LICENSE.md README.md STYLE_CPP.md |
diffstat | 7 files changed, 572 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CHANGES.md Tue Jan 31 21:51:25 2017 +0100 @@ -0,0 +1,11 @@ +PROJECT NAME CHANGES +==================== + +pname current +----------------------------- + +project name 1.0.0 2017-12-25 +----------------------------- + + - Some topic, + - Other topics.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CONTRIBUTE.md Tue Jan 31 21:51:25 2017 +0100 @@ -0,0 +1,170 @@ +PROJECT NAME CONTRIBUTING GUIDE +=============================== + +Read this guide if you want to contribute to PROJECT NAME. The purpose of this +document is to describe the steps to submit a patch. + +You may submit a patch when: + + - You want to fix a bug / typo, + - You want to add a new feature, + - You want to change something. + +There a lot of steps before submitting a patch. First, be sure to respect the +style defined in the STYLE.md file. We never accept patches that do not match +the rules. + +Subscribe to the mailing list +----------------------------- + +Discussion and patches are sent to the *PROJECT NAME (at) malikania (dot) fr* mailing +list. You need to subscribe by dropping a mail to +*PROJECT NAME+subscribe (at) malikania (dot) fr* first. + +Create your patch +----------------- + +Usually, when you create a patch, you should have your own copy of PROJECT NAME +in your directory. + +The following steps assumes that you have already cloned the PROJECT NAME +repository somewhere. + +**Note**: the recommended way is to create one unique revision. + +### Quick way + +If you plan to create a very small patch that consists of several lines, you can +use the following way by disabling the @ bookmark to avoid moving it. + + $ hg pull # fetch last changesets + $ hg up @ # update to the last revision + $ hg book -i @ # disable the @ bookmark (optional but recommended) + (edit some files) + $ hg commit # create a unique revision + $ hg email -r . # send a mail about the current revision (interactive) + +### Bookmark way + +We use Mercurial bookmarks as our workflow but we do share only @ bookmark +except when a long feature is being developed in parallel. Otherwise bookmarks +stay locally most of the time. + +When you start working on a new feature, you **must** always start from the @ +bookmark. + +You can use this workflow if you plan to create a patch that consists of +multiple revisions. + +Example: + + $ hg pull + $ hg up @ + $ hg book feature-xyz + (work) + $ hg commit + (work) + $ hg commit + $ hg email -r first:last + +Here, you must specify **first** and **last** as the initial and last revisions +respectively. You can check these revisions using `hg log` (also try `hg log -G` +or the nice TortoiseHg interface). + +Example, I've started to work on an a feature named **feature-xyz**, the log +looks like this: + + changeset: 22:3fb15d8fc454 + bookmark: feature-xyz + tag: tip + user: François Jean <fj@gmail.com> + date: Thu Dec 08 16:08:40 2016 +0100 + summary: Topic: some other changes + + changeset: 21:f27e577c5504 + user: François Jean <fj@gmail.com> + date: Thu Dec 08 16:03:06 2016 +0100 + summary: Topic: some changes + + changeset: 20:777023816ff9 + bookmark: @ + user: David Demelier <markand@malikania.fr> + date: Thu Dec 08 16:02:26 2016 +0100 + summary: Misc: fix a bug + +The two revisions I want to export are 21 and 22, so I use `hg email -r 21:22`, +once done, see the section below. + +Additional topics +----------------- + +### Your patch is accepted + +The safest choice is to just pull from the central repository and update to the +@ bookmark. + + $ hg pull + $ hg up @ + +You can also call `hg rebase` (from rebase extension) to move your revisions on +top of upstream. If the patches were incorporated verbatim, they will be safely +discarded automatically. + + $ hg pull + $ hg up @ + $ hg rebase -b feature-xyz -d @ + $ hg book -d feature-xyz + +If you didn't created a bookmark replace **feature-xyz** with your revision +number. + +Finally, if you prefer to remove the revisions you have created, use `hg strip` +like explained in the see section below. + +### Your patch is discarded + +For some reasons, your patch can not be integrated within the official +repository, you can remove the revisions you have commited or keep them. + +If you want to remove the revisions, you can use the `hg strip` command (from +the strip extension. + +**Warning**: it will **remove** the revisions from history so use with care. + + $ hg strip -r 21:22 # using the example above + $ hg book -d feature-xyz # delete the bookmark + +You can just go back on the @ bookmark as it's the safest choice. + + $ hg pull # fetch changesets + $ hg up @ # update to @ + +### How to merge upstream code to continue my patch + +Sometimes when you started working on a topic, you may need to pull changes from +the repository. The idea is to pull the changes and rebase your work on top of +it. + +You must run these commands while your bookmark is active + + $ hg up feature-xyz + $ hg pull -B @ + $ hg rebase -b feature-xyz -d @ + +### I forgot to create a bookmark and accidentally moved the @ bookmark + +If you forgot to create a custom bookmark or disable @ before committing, you +may have moved the @ bookmark in your repository. The `hg pull` command can +recover it. + +First, we create it now to point at your local revisions (optional). + + $ hg book feature-xyz + +Then, put it where it should be. + + $ hg pull -B @ + +Now @ will be placed to the same revision as the central repository. If some +changesets have been pulled, you may look at the previous topic to rebase your +work on top of it.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CREDITS.md Tue Jan 31 21:51:25 2017 +0100 @@ -0,0 +1,7 @@ +PROJECT NAME CREDITS +==================== + +Libraries and projects +---------------------- + +Add external libraries as markdown list.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/INSTALL.md Tue Jan 31 21:51:25 2017 +0100 @@ -0,0 +1,27 @@ +PROJECT NAME INSTALL +==================== + +Installation instructions. + +Requirements +------------ + + - [Library](http://example.org), Short description, + - [Tool](http://example.org), Short description, + +Optional: + + - [Library](http://example.org), Short recommandation, + +Basic installation +------------------ + +Quick install. + + $ tar xvzf PROJECT NAME-x.y.z-tar.xz + $ cd PROJECT NAME-x.y.z + $ mkdir _build_ + $ cd _build_ + $ cmake .. -DCMAKE_BUILD_TYPE=Release + $ make + # sudo make install
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE.md Tue Jan 31 21:51:25 2017 +0100 @@ -0,0 +1,16 @@ +PROJECT NAME ISC LICENSE +======================== + +Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.md Tue Jan 31 21:51:25 2017 +0100 @@ -0,0 +1,19 @@ +PROJECT NAME +============ + +Long description. + +Documentation +------------- + +Author +------ + +Author + +Contributors +------------ + + - Contributor 1, + - Contributor 2, + - Contributor 3.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/STYLE_CPP.md Tue Jan 31 21:51:25 2017 +0100 @@ -0,0 +1,322 @@ +PROJECT NAME C++ CODING STYLE +============================= + +Style +----- + + - Always use 4 spaces as indentation, + - Do not exceed 120 characters for lines of code, + - Do not exceed 80 characters for comments, + - Never write two blank consecutives blank lines, + +### Braces + +Braces follow the K&R style, they are never placed on their own lines except for +function definitions. + +In addition to the K&R style, they are required everywhere even if a block +contains only one statement. + + if (condition) { + apply(); + add(); + } else { + ok(); + } + + if (condition) { + validate(); + } + +And a lambda has its braces on the same lines too: + + sort([&] (object&) { + return true; + }); + +### Spaces + +Each reserved keyword (e.g. `if`, `for`, `while`) requires a single space before +its argument. + +Normal function calls do not require it. + + if (foo) { + destroy(sizeof (int)); + } + +### References and pointers + +References and pointers are always next to the type name and not the variable. + + T& get(const std::string& name); + + int* p = &x; + +### Naming + + - English names, + - Member variables starts with `m_`, + - No hungarian notation. + +Everything is in `underscore_case` except template parameters and macros. + + #if defined(FOO) + # include <foo.hpp> + #endif + + namespace baz { + + class object { + private: + std::string m_name; + + public: + inline const std::string& name() const noexcept + { + return m_name; + } + }; + + template <typename Archive> + void open(const Archive& ar) + { + bool is_valid = false; + } + + } // !baz + +### Header guards + +Do not use `#pragma once`. + +Header guards are usually named **PROJECT_COMPONENT_FILENAME_HPP**. + + #ifndef FOO_COMMON_UTIL_HPP + #define FOO_COMMON_UTIL_HPP + + #endif // !FOO_COMMON_UTIL_HPP + +### Enums + +Enumerations constants are always defined in separate line to allow commenting +them as doxygen. + +Enum class are encouraged. + + enum class color { + blue, + red, + green + }; + +### Files + + - Use `.cpp` and `.hpp` as file extensions, + - Filenames are all lowercase. + +### Comments + +Avoid useless comments in source files. Comment complex things or why it is done +like this. However any public function in the .hpp **must** be documented as +doxygen without exception. + + /* + * Multi line comments look like + * this. + */ + + // Short comment + +### Includes + +The includes should always come in the following order. + + 1. C++ headers + 2. C header + 3. Third party libraries + 4. Application headers in "" + + #include <cstring> + #include <cerrno> + + #include <sys/stat.h> + + #include <libircclient.h> + + #include "foo.h" + +**Note**: always use C++ headers for C equivalent, stdio.h -> cstdio, etc. + +### Commit messages + +Commit messages are written using the following syntax: + + Topic: short message less than 80 characters + + Optional additional description if needed. + +Replace `Topic` with one of the following: + + - **CMake**: for the build system, + - **Docs**: for the documentation, + - **Misc**: for miscellaneous files, + - **Tests**: for the unit tests, + +Programming +----------- + +### C language + +Do not use old C stuff like `void *`, `srand/rand`, `printf` or anything that +can be rewritten in modern C++. + +### RTTI + +Usage of `dynamic_cast` and `typeid` are completely disallowed in any shape of +form. + +### Arguments + +It is recommended to pass parameters by value or const reference. Usage of +non-const reference as output parameter is **discouraged** and should be avoided +in many case because it does not allow chaining of expressions like: + + std::cout << reverse(upper(clean(" hello world! "))) << std::endl; + +If your function is designed to return a modified value passed as argument, it +is better to take it by value and modify it directly. + + std::string clean(std::string input) + { + if (!input.empty() && input.back() == '\r') { + input.pop_back(); + } + + return input; + } + +Never pass primitive types as const value. + +### Assertions + +Use the `assert` macro from the cassert header file to verify programming +errors. + +For example, you may use `assert` to verify that the developer access the data +between the bounds of an array: + + T& operator[](unsigned index) + { + assert(index < m_length); + + return m_data[index]; + } + +The `assert` macro is not meant to check that a function succeeded, this code +must not be written that way: + + assert(listen(10)); + +### Exceptions + +You must use exceptions to indicate an error that was unexpected such as: + + - Failing to open a file, + - I/O unexpected errors, + - Parsing errors, + - User errors. + +You may use the C++ standard exceptions defined in the stdexcept header but if +you need to carry more data within your exception, you should derive from +`std::exception`. + +### Free functions + +Basic utility functions should be defined in a namespace as a free function not +as a static member function, we're doing C++ not Java. + +Example: + + namespace util { + + std::string clean(std::string input); + + } // !util + +### Variables initialization + +Use parentheses to initialize non primitive types: + + throw std::runtime_error("foo"); + + my_class obj("bar"); + +Use brace initialization when you want to use an initializer list, type +elision: + + std::vector<int> v{1, 2, 3}; + + foo({1, 2}); // type deduced + + return { "true", false }; // std::pair returned + +Use the assignment for primitive types: + + int x = 123; + bool is_valid = true; + +### Classes + +Classes are usually defined in the following order: + + 1. Public inner types (enums, classes), + 2. Protected/private members + 3. Public functions + + class foo { + public: + enum class type { + a, + b + }; + + private: + int m_member{0}; + + public: + void some_function(); + } + +### Structs + +Do not use C structs unless you have very good reason to do so. If you want to +pack some data, just use `class` and make all fields public. + + class point { + public: + int x; + int y; + }; + +### Return + +The preferred style is to return early in case of errors. That makes the code +more linear and not highly indented. + +This code is preferred: + + if (a_condition_is_not_valid) { + return nullptr; + } else if (an_other_condition) { + return nullptr; + } + + auto x = std::make_shared<object>(); + + x->start(); + x->save(); + + return x; + +Do never put parentheses between the returned value.