********************************** Developer guide for SVN operations ********************************** .. contents:: :depth: 1 Source code organisation ======================== Building from several checkouts ------------------------------- | As of now, the NEMO code is build from different sources in the repository, via SVN external definitions which are special versioned properties specified on its sub-items (folders and file). | For more, read `the documentation on external definitions in ​the SVN book `_. On one hand, the *core code*, which is actively developed from one release to another, is still present and unique for a branch. :./cfgs: Reference configurations :./doc: Reference manuals (LaTeX) and user guide (reStructuredText) :./src: Modelling routines :./tests: Test cases | On the other hand, the *complementary code*, defined by minor modifications between consecutive releases, is managed apart from the default development organisation (``branches``, ``releases``, `tags` and ``trunk``). | It has been extracted to another locations in the repository and can considered from now on as external sources. :./arch: Settings for computing architecture :./ext: External dependencies (AGRIF for nesting, FCM for compilation and IOIPSL for IO) :./makenemo: Script for building NEMO executable :./mk: Compilation sub-scripts :./tools: User tools .. note:: The major benefit of this implementation is the convenient way of sharing code. Part of the source code can be develop in one location, in-house or externally, and distribute to several working copies. External sources in working copy -------------------------------- Here is the current list of these externals for the NEMO code: .. code:: sh # Relative URL Item # '^': alias for repository root ^/utils/build/arch@{HEAD,${REV}} arch ^/utils/build/makenemo@{HEAD,${REV}} makenemo ^/utils/build/mk@{HEAD,${REV}} mk ^/utils/tools@{HEAD,${REV}} tools ^/vendors/AGRIF/dev@{HEAD,${REV}} ext/AGRIF ^/vendors/FCM@{HEAD,${REV}} ext/FCM ^/vendors/IOIPSL@{HEAD,${REV}} ext/IOIPSL .. important:: Regarding the main branches of NEMO development, official releases and tagged snapshots will have fixed externals, however the trunk will always refer to the ``HEAD`` of the repository. .. note:: | As we cannot add comments in the context of versioned properties, the revision number of an external source could be a major information for those would starting to scrutinize the code. | Revision changes have to be limited it to what is strictly necessary, i.e. only for the external(s) at stake, and each definition must refer to an effective revision considered as reliable. Developer perspective --------------------- | The external definitions are retained by branching operations so in the first place a development branch created from the trunk will update its external sources to the latest. | From that the developer makes a choice for each external in the development branch +--------------------------+---------------------------------------------------------+ | *Set explicit revision* | Isolated from unwanted commits | | | | | | Get back to or reproduce confidently a previous version | +--------------------------+---------------------------------------------------------+ | *Keep ``HEAD`` revision* | Modify directly the external and receive all updates | | | | | | No commit record in the meantime | +--------------------------+---------------------------------------------------------+ | Due to different attributes exposed above, **it is strongly recommended to set explicit revisions on externals for a development branch**. | Nevertheless the developer can have its reasons to have implicit revision for given item(s) and can update the definitions on a case-by-case basis. The SVN commands for managing external definitions are below, modified externals are reported in the 2 :sup:`nd` column of ``svn {st,status}`` output. .. code:: sh ## Get the current definitions $ svn propget svn:externals ${PATH} ## Edit them in external editor (SVN_EDITOR env. variable) $ svn propedit svn:externals ${PATH} .. warning:: Think about committing your new definitions Recommended development environment =================================== Lightweight repository copy --------------------------- .. |download| replace:: **download** .. _download: https://forge.ipsl.jussieu.fr/nemo/export/HEAD/utils/dev/install_dev_env.sh Although each developer can have its own approach for developing the NEMO source code, **we recommend to** |download|_ **and run** ``install_dev_env.sh`` **script to set up a clean and minimal environment**. From there, the developer would be able to start his developments but also to support the NEMO shared reference in the same working copy. | Actually the script will checkout the repository in a slightly different manner from the usual way, using the ``--depth`` and ``--set-depth`` SVN options in order to download the sub-paths of the default development organisation in various depths (``branches``, ``releases``, ``tags`` and ``trunk``). | In the end, the developer will have a versioned copy of the repository first levels with empty folders, except for the `trunk` (``/NEMO/trunk``) and the last official release (``/NEMO/releases/release-X.X``) which have been fully downloaded. The benefits of this new approach are numerous - **Possibility to work offline like git**: create a development branch by copying the `trunk` locally and start coding without a first commit to the remote repository, instead of creating the development branch remotely on the repository, then downloading it to begin to work. - **Simple UNIX-like syntax for SVN commands** (``svn {add,cat,cp,ls,mv,rm} ...``) and no more tedious URL scheme to use (``svn+ssh://...``). - **All developments handled in one common location** by putting an end at the branches scattering with several isolated working copies (usually one single checkout per branch). Examples -------- Usage of ``install_dev_env.sh`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: console $ ./install_dev_env.sh [${DEVELOPER_ID} [repo]] Positional arguments in option 1. ``DEVELOPER_ID``: configure the working copy in developer mode, i.e. URL in ``svn info`` begins with |DEV_URL| ... instead of |URL|, so the developer can commit to the repository right away (switching can be made later if needed). 2. ``repo``: download the whole layout of the repository instead of the default development organisation to manage the development of the sources used as externals. By default, the checkout is from root directory ``/NEMO`` with ``branches``, ``releases``, ``tags`` and ``trunk``. With ``repo`` argument, it does from the root of repository with ``/NEMO``, ``/utils``, ``/vendors``. Create a branch ^^^^^^^^^^^^^^^ .. code:: console $ svn copy {${URL_SRC},${PATH_SRC}}[@${REV}] {${URL_DST},${PATH_DST}} +------------------+--------------------------------------------------------------------+-----------------------------------------------+ | local -> local | ``PATH_SRC`` = ``trunk`` | *Copy unversioned items to the new branch* | | | | | | | ``PATH_DST`` = ``branches/${YEAR}/${BRANCH_NAME}`` | | +------------------+--------------------------------------------------------------------+-----------------------------------------------+ | local -> remote | ``PATH_SRC`` = ``trunk`` | *New branch created only in the repository* | | | | | | | ``URL_DST`` = ``${DEV_URL}/NEMO/branches/${YEAR}/${BRANCH_NAME}`` | | +------------------+--------------------------------------------------------------------+-----------------------------------------------+ | remote -> local | ``URL_SRC`` = ``${URL}/NEMO/trunk`` | *Clean copy of the trunk from the repository* | | | | | | | ``PATH_DST`` = ``branches/${YEAR}/${BRANCH_NAME}`` | | +------------------+--------------------------------------------------------------------+-----------------------------------------------+ | remote -> remote | ``URL_SRC`` = ``${URL}/NEMO/trunk`` | *All done on server side* | | | | | | | ``URL_DST`` = ``${DEV_URL}/NEMO/branches/${YEAR}/${BRANCH_NAME}`` | | +------------------+--------------------------------------------------------------------+-----------------------------------------------+ .. |URL| replace:: ``http://forge.ipsl.jussieu.fr/nemo/svn`` .. |DEV_URL| replace:: ``svn+ssh://${DEVELOPER_ID}@forge.ipsl.jussieu.fr/ipsl/forge/projets/nemo/svn`` .. note:: | ``URL`` = |URL| | ``DEV_URL`` = |DEV_URL| | Usual convention for the naming of the development branches: | ``BRANCH_NAME`` = ``dev_r${TRUNK_REVISION_ON_FORK}_${ACTION_NAME_IN_WORKPLAN}`` Download a branch from the repository ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: console List the remote branches in the repository $ svn ls branches/${YEAR} Download the one chosen $ svn update branches/${YEAR}/${BRANCH_NAME} Delete the local copy of a branch ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: console Set branch depth to 'exclude' => Tag the branch as to be deleted $ svn update --set-depth exclude branches/${YEAR}/${BRANCH_NAME} D dev_r.... Effective removal $ svn update branches/${YEAR} Working smart with available resources ====================================== Make link between commit and ticket(s) -------------------------------------- If a commit is related to ticket(s), we highly suggest to mention it in the commit log message: - the commit will be converted into a comment in the ticket thread(s) - URL link(s) to selected ticket(s) will be provided in the email notification and the changeset page. | To do so, you can use a word from this list ``addresses re references refs see`` followed by usual ticket link(s). | For instance .. code:: console $ svn commit -m '[...] see #${TICKET_ID} [...]' Close ticket(s) when committing ------------------------------- | If a commit is a fix, you can close targeted ticket(s) with the commit operation without the need of a browser. | For this, you can use a word from the list ``close closed closes fix fixed fixes`` followed by usual ticket link(s). | For instance .. code:: console $ svn commit -m '[...] fix #${TICKET_ID} [...]'