diff --git a/.travis.yml b/.artenolis.yml
similarity index 83%
rename from .travis.yml
rename to .artenolis.yml
index 74f4b2a..8f51993 100644
--- a/.travis.yml
+++ b/.artenolis.yml
@@ -48,7 +48,7 @@ script:
- cd $CURRENT_DIR;
# launch the tests
- - sh ./runtests.sh;
+ - sh ./.artenolis/runtests.sh;
- cd ~/fork-MATLAB.devTools.CI;
- git reset --hard origin/develop;
@@ -58,4 +58,8 @@ after_success:
# remove the cloned fork-repo
- if [ "$MATLAB_VER" == "R2016b" ]; then
bash <(curl -s https://codecov.io/bash) -f "!*.lst";
+ export PATH="/home/sbg-jenkins/.local/bin":$PATH;
+ cd $CURRENT_DIR;
+ pip install --upgrade --user -r docs/requirements.txt;
+ python -c "from documenter.deploy import Documentation; doc = Documentation('github.com/opencobra/MATLAB.devTools', ci='jenkins'); doc.deploy()";
fi
diff --git a/.artenolis/runtests.sh b/.artenolis/runtests.sh
new file mode 100644
index 0000000..a401247
--- /dev/null
+++ b/.artenolis/runtests.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+cd ./test
+/mnt/prince-data/MATLAB/$MATLAB_VER/bin/./matlab -nodesktop -nosplash -r "launchTests;" < inputCI.txt;
+CODE=$?
+exit $CODE
diff --git a/.gitignore b/.gitignore
index fafff2e..1ee3278 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,40 @@
+build
+*.*~
.DS_Store
-Thumbs.db
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# Windows shortcuts
+*.lnk
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Documentation related files
+docs/source/_static/json/functions.json
+*.pyc
diff --git a/FAQ.md b/FAQ.md
deleted file mode 100644
index 7b8735e..0000000
--- a/FAQ.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# Frequently Asked Questions (FAQ)
-
-## Mismatch of the version of `openSSL` (Linux)
-
-You might be in the situation that you receive the following error:
-````
-OpenSSL version mismatch. Built against 1000207f, you have 100010bf
-````
-In that case, you should run the following command:
-````
-sudo mv /bin/glnxa64/libcrypto.so.1.0.0 /bin/glnxa64/libcrypto.so.1.0.0_bk
-````
-where `` corresponds to the installation of `MATLAB`, e.g., `/usr/local/MATLAB/R2016b`
-
-## How do I submit a Pull Request?
-
-Once you submit your contribution (menu item 3), you will be presented with a link that leads you directly to the pull request (PR).
-
-## Turn on the verbose mode
-
-If you encounter a problem, or suspect that something is not behaving properly, please run:
-```
->> contribute(true)
-```
-and follow the process as normally. You can also set `gitConf.verbose = true;` in `assets/confDevTools.m`.
-
-## Resolve unexpected behavior - reset
-
-If you encounter unexpected behavior, please try to reset the `devTools` with:
-```
->> resetDevTools
-```
-
-If you have files or changes that appear and would like to reset your local fork (without re-cloning) again, type:
-```
->> resetLocalFork
-```
-
-## How can I abort a process?
-
-You can abort any process using `CTRL-C` (hit `CTRL` and `C` on your keyboard).
-
-## How should I name my contribution?
-
-Initiate a contribution per theme/topic/feature/bug fix that you work on. Don't mix features and think of an explicit name, i.e. `bug-fix-function1` or `add-tests-function2`. Avoid generic names, such as `my-great-feature` or `fix` or `contribution-myName`.
-
-## How can I check the history of a file?
-
-You can check the history of a file by typing in MATLAB:
-```
->> history('fileName.m')
-```
diff --git a/PREREQUISITES.md b/PREREQUISITES.md
deleted file mode 100644
index f923a81..0000000
--- a/PREREQUISITES.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# Pre-requisites
-
-## GitHub SSH configuration
-
-You have to register the SSH key of each computer that you are planning to use the `MATLAB.devTools` on.
-
-- **Check if you already have an SSH key:**
-````
-$ ls -al ~/.ssh
-````
-If there is a file with an extension `.pub`, you already have an SSH key. Now, you have to **add your SSH key to Github**. More help is [here](https://help.github.com/articles/checking-for-existing-ssh-keys/).
-
-- **Generate the SSH key on your computer:**
-If you don't have yet an SSH key (see previous step), you have to generate one (more help is [here](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/)):
-````
-$ ssh-keygen -t rsa -C "first.last@server.com"
-````
-
-- **Add the SSH** to [your Github account](https://github.com/settings/keys) by following the steps [here](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/).
-
-## Can I check if everything is properly set up before I start?
-
-Please ensure that you have a working `MATLAB` installation.
-
-You can check if you have a working installation of `git` by typing in the terminal (or GUI Bash):
-```bash
-$ git --version
-```
-This will return `git version 2.10.1 [...]` or similar with another version number.
-
-You can then check if your `git` is properly configured by typing in the terminal (or GUI Bash):
-```bash
-$ git config --get user.github-username
-```
-which will return your Github username if everything is properly set up. Similarly, check the configured email by typing in the terminal (or GUI Bash):
-```bash
-$ git config --get user.email
-```
-
-You can check if you have a working installation of `curl` by typing in the terminal (or GUI Bash):
-```bash
-$ curl --version
-```
-which will return `curl 7.51.0 [...]` or similar with another version number.
-
-## System configuration
-
-You must have `git` and `curl` installed. Please also ensure that you have `MATLAB` [installed](https://nl.mathworks.com/help/install/).
-
-**Linux (Ubuntu or Debian)**
-
-```bash
-$ sudo apt-get install git-all curl
-```
-
-**macOS**
-
-In order to install `git`, install the [Xcode Command Line Tools](http://osxdaily.com/2014/02/12/install-command-line-tools-mac-os-x/). For `curl`, follow the instructions [here](http://macappstore.org/curl/).
-
-**Windows**
-
-Please download the `git` tools for Windows from [here](https://git-scm.com/download/win). During the installation process, please ensure that you select **Use Git Bash and optional Unix tools from the Windows Command prompt**. In addition, please make sure that you select **Checkout as-is, commit Unix-style line endings**.
-
-
- .
-
-
-## Github and local `git` configuration
-
-If you don't have a GitHub account, please sign up [here](https://github.com/join). For the very first time, you must **fork** the repository of The COBRA Toolbox. Browse to the [original repository](https://github.com/opencobra/cobratoolbox) and click on the button
-.
-
-On **Linux (Ubuntu)** or **macOS**, start the terminal (or any other shell). On **Windows**, start `GUI Bash`. Then type
-```bash
-$ git config --global user.github-username "yourGitHubUsername"
-$ git config --global user.email "first.last@server.com"
-```
-Please replace `"yourGitHubUsername"` and `"first.last@server.com"` with your respective credentials.
diff --git a/README.md b/README.md
deleted file mode 100644
index af1872f..0000000
--- a/README.md
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
-
-| MATLAB R2016b | MATLAB R2015b | Code Coverage | Code Grade |
-|--------|--------|--------|--------|
-| [![Build Status](https://prince.lcsb.uni.lu/jenkins/buildStatus/icon?job=devTools-branches-auto/MATLAB_VER=R2016b)](https://prince.lcsb.uni.lu/jenkins/job/devTools-branches-auto/MATLAB_VER=R2016b/) | [![Build Status](https://prince.lcsb.uni.lu/jenkins/buildStatus/icon?job=devTools-branches-auto/MATLAB_VER=R2015b)](https://prince.lcsb.uni.lu/jenkins/job/devTools-branches-auto/MATLAB_VER=R2015b/)| [![codecov](https://codecov.io/gh/opencobra/MATLAB.devTools/branch/master/graph/badge.svg)](https://codecov.io/gh/opencobra/MATLAB.devTools/branch/master) | ![Code grade](https://prince.lcsb.uni.lu/jenkins/userContent/codegrade-MATLABdevTools.svg?maxAge=0 "Ratio of the number of inefficient code lines and the total number of lines of code (in percent). A: 0-3%, B: 3-6%, C: 6-9%, D: 9-12%, E: 12-15%, F: > 15%.")
-
-# MATLAB.devTools - Contribute the smart way
-
-## Pre-requisites
-
-Please follow the [configuration instructions](https://github.com/opencobra/MATLAB.devTools/blob/master/PREREQUISITES.md) carefully. You may skip this if your system is already set up and you have `git` configured.
-
- **IMPORTANT**: Please make sure that you have configured your SSH key in Github as explained [here](https://github.com/opencobra/MATLAB.devTools/blob/master/PREREQUISITES.md).
-
-## Installation
-
-Download this repository (the folder `./MATLAB.devTools/` will be created). You can clone the repository using:
-````bash
-$ git clone git@github.com:opencobra/MATLAB.devTools.git MATLAB.devTools
-````
- Run this command in `Terminal` (on and ) or in `Git Bash` (on ) - **not** in .
-
-
-## Do you want to contribute to The COBRA Toolbox?
-
-Please follow the [installation and contributing instructions](https://github.com/opencobra/cobratoolbox/blob/master/README.md).
-
-[![asciicast](https://asciinema.org/a/7zg2ce5gfth7ruywptgc3i3yy.png)](https://asciinema.org/a/7zg2ce5gfth7ruywptgc3i3yy)
-
-## How do I use the `MATLAB.devTools`?
-
-Making a contribution to any `git` repository from is straightforward. Type in within the `MATLAB.devTools` folder:
-```Matlab
->> contribute
-```
-
-You will then be presented by a menu:
-```
- [1] Start a new feature (branch).
- [2] Select an existing feature (branch) to work on.
- [3] Publish a feature (branch).
- [4] Delete a feature (branch).
- [5] Update the fork.
-
--> Please select what you want to do (enter the number):
-```
-
-The original repository will be downloaded (cloned) the first time to a folder named `fork-gitRepoName`. **Only files in the `fork-gitRepoName` folder** will be considered for contribution (any changes made to a downloaded official `git` repository will be ignored).
-
- If you get stuck or are faced with an system error message, please read the [FAQ](https://github.com/opencobra/MATLAB.devTools/blob/master/FAQ.md).
-
-## How can I update my fork without contributing?
-
-In order to only update your fork, run `>> contribute` and select menu item `[5]`.
-
-## Configure the `MATLAB.devTools` for another repository
-
- The `MATLAB.devTools` can only be used with **publicly accessible** repositories.
-
-If you want to use the `MATLAB.devTools` with a repository other than the default repository, you must set the following variables:
-
-```Matlab
-launcher = '\n\n ~~~ MATLAB.devTools ~~~\n\n'; % a message for the repository (any string)
-remoteRepoURL = 'https://server.com/repositoryName.git'; % the remote url
-nickName = 'repoNickName'; % a nickName of the repository (any string)
-verbose = false; % turn the verbose mode on (true) or off (false)
-```
-and run:
-```Matlab
->> confDevTools(launcher, remoteRepoURL, nickName, verbose); % sets the configuration
-```
-
-In order to reset the configuration, type:
-```Matlab
->> resetDevTools();
-```
-If you want your changes to be permanent, you can set the above mentioned variables in `./assets/confDevTools.m`.
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..5a1e307
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,262 @@
+.. raw:: html
+
+
+
+
+
+
+ MATLAB.devTools - Contribute the smart way
+
+
++----------------+----------------+---------------+--------------+
+| MATLAB R2016b | MATLAB R2015b | Code Coverage | Code Grade |
++================+================+===============+==============+
+| |Build Status| | |Build Status| | |codecov| | |Code grade| |
++----------------+----------------+---------------+--------------+
+
+.. begin-description-marker
+
+All repositories on Github are version controlled using `git
+`__, a free and open-source distributed, version control
+system, which tracks changes in computer files and is used for coordinating
+work on those files by multiple people.
+
+In order to lower the technological barrier to the use of the popular software
+development tool `git `__, we have developed
+`MATLAB.devTools`, a new user-friendly software extension that enables
+submission of new COBRA software and tutorials, in particular for `The COBRA
+Toolbox `__ and the
+`COBRA.tutorials `__.
+
+The `MATLAB.devTools `__ are
+highly recommended for contributing code (in particular `MATLAB` code) to
+existing repositories in a user-friendly and convenient way, even for those
+without basic knowledge of `git`.
+
+.. end-description-marker
+
+
+Pre-requisites
+--------------
+
+.. begin-prerequisites-marker
+
+Please follow the `configuration
+instructions `__
+carefully. You may skip this if your system is already set up and you
+have ``git`` configured.
+
+|important| **IMPORTANT**: Please make sure that you have configured your SSH key
+in Github as explained
+`here `__.
+
+.. end-prerequisites-marker
+
+Installation
+------------
+
+.. begin-installation-marker
+
+Download this repository (the folder ``./MATLAB.devTools/`` will be
+created). You can clone the repository using:
+
+.. code:: bash
+
+ $ git clone git@github.com:opencobra/MATLAB.devTools.git MATLAB.devTools
+
+|important| Run this command in ``Terminal`` (on |macOS| and |linux|) or in ``Git Bash`` (on |windows|) -
+**not** in |matlab|.
+
+Some issues that can arise during installation are addressed in the
+`FAQ `__.
+
+.. end-installation-marker
+
+Do you want to contribute to The COBRA Toolbox?
+-----------------------------------------------
+
+|asciicast|
+
+More information about `the COBRA Toolbox
+`__ is given `here
+`__.
+
+How do I use the ``MATLAB.devTools``?
+-------------------------------------
+
+.. begin-getstarted-marker
+
+Making a contribution to any ``git`` repository from |matlab| is straightforward.
+Type in |matlab| within the ``MATLAB.devTools`` folder:
+
+.. code:: matlab
+
+ >> contribute
+
+You will then be presented by a menu:
+
+::
+
+ [1] Start a new feature (branch).
+ [2] Select an existing feature (branch) to work on.
+ [3] Publish a feature (branch).
+ [4] Delete a feature (branch).
+ [5] Update the fork.
+
+ -> Please select what you want to do (enter the number):
+
+The original repository will be downloaded (cloned) the first time to a
+folder named ``fork-gitRepoName``. **Only files in the
+fork-gitRepoName folder** will be considered for contribution (any
+changes made to a downloaded official ``git`` repository will be
+ignored).
+
+|important| If you get stuck or are faced with an system error message, please read
+the `FAQ `__.
+
+.. end-getstarted-marker
+
+How can I update my fork without contributing?
+----------------------------------------------
+
+In order to only update your fork, run ``>> contribute`` and select menu
+item ``[5]``.
+
+Configure the ``MATLAB.devTools`` for ``COBRA.tutorials``
+---------------------------------------------------------
+
+.. begin-contribute-cobratutorials-marker
+
+If you want to use the ``MATLAB.devTools`` when contributing to the
+`COBRA.tutorials `__, you can simply configure
+the ``MATLAB.devTools`` on-the-fly by typing:
+
+.. code:: matlab
+
+ >> contribute('opencobra/COBRA.tutorials')
+
+.. end-contribute-cobratutorials-marker
+
+
+Configure the ``MATLAB.devTools`` for another repository
+--------------------------------------------------------
+
+.. begin-contribute-other-repo-marker
+
+|important| The ``MATLAB.devTools`` can only be used with **publicly accessible** repositories.
+
+If you want to use the ``MATLAB.devTools`` with a repository other than
+the default repository, you may run:
+
+.. code:: matlab
+
+ >> contribute('userName/repositoryName')
+
+where ``userName`` is the name on Github of the organization or the user, and
+``repositoryName`` is the name of the repository. The URL of the repository
+would be `https://github.com/userName/repositoryName`. Please note that this
+command looks for a repository on `github.com `__.
+
+.. end-contribute-other-repo-marker
+
+How to reset the ``MATLAB.devTools``
+------------------------------------
+
+.. begin-reset-marker
+
+In order to reset the configuration of the ``MATLAB.devTools``, type:
+
+.. code:: matlab
+
+ >> resetDevTools();
+
+This performs a so-called `soft` reset (clears the local configuration). In
+order to perform a hard reset (clears and resets the local ``git``
+configuration), run:
+
+.. code:: matlab
+
+ >> resetDevTools(true);
+
+Once the devTools have been `hard` reset, all details for the configuration
+have to be set again next time ``contribute`` is run.
+
+.. end-reset-marker
+
+How to cite the ``MATLAB.devTools``
+-----------------------------------
+
+.. begin-how-to-cite-marker
+
+As the ``MATLAB.devTools`` have first been developed for the COBRA Toolbox, the
+paper of The COBRA Toolbox shall we cited when referring to the ``MATLAB.devTools``.
+
+ Laurent Heirendt & Sylvain Arreckx, Thomas Pfau, Sebastian N.
+ Mendoza, Anne Richelle, Almut Heinken, Hulda S. Haraldsdottir, Jacek
+ Wachowiak, Sarah M. Keating, Vanja Vlasov, Stefania Magnusdottir,
+ Chiam Yu Ng, German Preciat, Alise Zagare, Siu H.J. Chan, Maike K.
+ Aurich, Catherine M. Clancy, Jennifer Modamio, John T. Sauls,
+ Alberto Noronha, Aarash Bordbar, Benjamin Cousins, Diana C. El
+ Assal, Luis V. Valcarcel, Inigo Apaolaza, Susan Ghaderi, Masoud
+ Ahookhosh, Marouen Ben Guebila, Andrejs Kostromins, Nicolas
+ Sompairac, Hoai M. Le, Ding Ma, Yuekai Sun, Lin Wang, James T.
+ Yurkovich, Miguel A.P. Oliveira, Phan T. Vuong, Lemmer P. El Assal,
+ Inna Kuperstein, Andrei Zinovyev, H. Scott Hinton, William A.
+ Bryant, Francisco J. Aragon Artacho, Francisco J. Planes, Egils
+ Stalidzans, Alejandro Maass, Santosh Vempala, Michael Hucka, Michael
+ A. Saunders, Costas D. Maranas, Nathan E. Lewis, Thomas Sauter,
+ Bernhard Ø. Palsson, Ines Thiele, Ronan M.T. Fleming, **Creation and
+ analysis of biochemical constraint-based models: the COBRA Toolbox
+ v3.0** (submitted), 2017,
+ `arXiv:1710.04038 `__.
+
+.. end-how-to-cite-marker
+
+
+.. |Build Status| image:: https://prince.lcsb.uni.lu/jenkins/buildStatus/icon?job=devTools-branches-auto/MATLAB_VER=R2016b
+ :target: https://prince.lcsb.uni.lu/jenkins/job/devTools-branches-auto/MATLAB_VER=R2016b/
+.. |Build Status| image:: https://prince.lcsb.uni.lu/jenkins/buildStatus/icon?job=devTools-branches-auto/MATLAB_VER=R2015b
+ :target: https://prince.lcsb.uni.lu/jenkins/job/devTools-branches-auto/MATLAB_VER=R2015b/
+.. |codecov| image:: https://codecov.io/gh/opencobra/MATLAB.devTools/branch/master/graph/badge.svg
+ :target: https://codecov.io/gh/opencobra/MATLAB.devTools/branch/master
+.. |Code grade| image:: https://prince.lcsb.uni.lu/jenkins/userContent/codegrade-MATLABdevTools.svg?maxAge=0
+
+
+.. begin-screencast-marker
+
+.. |asciicast| image:: https://asciinema.org/a/7zg2ce5gfth7ruywptgc3i3yy.png
+ :target: https://asciinema.org/a/7zg2ce5gfth7ruywptgc3i3yy
+
+.. end-screencast-marker
+
+
+.. begin-icon-marker
+.. |macos| raw:: html
+
+
+
+.. |linux| raw:: html
+
+
+
+.. |windows| raw:: html
+
+
+
+.. |matlab| raw:: html
+
+
+
+.. |important| raw:: html
+
+
+
+.. |warning| raw:: html
+
+
+
+.. |bulb| raw:: html
+
+
+
+.. end-icon-marker
diff --git a/assets/confDevTools.m b/assets/confDevTools.m
deleted file mode 100644
index 9310add..0000000
--- a/assets/confDevTools.m
+++ /dev/null
@@ -1,37 +0,0 @@
-function confDevTools(launcher, remoteRepoURL, nickName, verbose)
-% devTools
-%
-% PURPOSE: define the configuration of the devTools
-%
-
- global gitConf
- global gitCmd
-
- % definition of parameters
- gitConf.leadForkDirName = 'fork-';
- gitConf.exampleBranch = 'add-constraints';
-
- if nargin < 4 % default values
- gitConf.verbose = false;
- gitConf.launcher = '\n\n _____ _____ _____ _____ _____ |\n / ___| / _ \\ | _ \\ | _ \\ / ___ \\ | COnstraint-Based Reconstruction and Analysis\n | | | | | | | |_| | | |_| | | |___| | | The COBRA Toolbox - 2017\n | | | | | | | _ { | _ / | ___ | |\n | |___ | |_| | | |_| | | | \\ \\ | | | | | Documentation:\n \\_____| \\_____/ |_____/ |_| \\_\\ |_| |_| | http://opencobra.github.io/cobratoolbox\n | \n\n';
- gitConf.remoteRepoURL = 'https://github.com/opencobra/cobratoolbox.git';
- gitConf.nickName = 'cobratoolbox';
- else
- gitConf.verbose = verbose;
- gitConf.launcher = launcher;
- gitConf.remoteRepoURL = remoteRepoURL;
- gitConf.nickName = nickName;
- end
-
- % define the URL of the devTools
- gitConf.devToolsURL_SSH = 'git@github.com:opencobra/MATLAB.devTools.git';
- gitConf.devToolsURL_HTTPS = 'https://github.com/opencobra/MATLAB.devTools.git';
- gitConf.devTools_name = 'MATLAB.devTools';
-
- % definition of commands
- gitCmd.lead = 'dev> ';
- gitCmd.success = ' (Success) ';
- gitCmd.fail = ' (Error) ';
- gitCmd.trail = '\n';
-
-end
diff --git a/contribute.m b/contribute.m
index f51f371..af50fc7 100644
--- a/contribute.m
+++ b/contribute.m
@@ -1,4 +1,4 @@
-function contribute(verbose)
+function contribute(repoName, printLevel)
% devTools
%
% PURPOSE: displays a menu and calls the respective subfunctions
@@ -7,9 +7,18 @@ function contribute(verbose)
% 2. Select an existing feature (branch) to work on.
% 3. Publish a feature (branch).
% 4. Delete a feature (branch).
+%
+% INPUT:
+%
+% printLevel: 0: minimal printout (default)
+% 1: detailed printout (debug mode)
global gitConf
global gitCmd
+ global resetDevToolsFlag
+ global DEFAULTREPONAME
+
+ resetDevToolsFlag = true;
% retrieve the current directory
currentDir = pwd;
@@ -17,18 +26,29 @@ function contribute(verbose)
% adding the src folder of the devTools
addpath(genpath(fileparts(which(mfilename))));
- % check the system and set the configuration
- checkSystem(mfilename);
+ % treatment of input arguments
+ if ~exist('repoName', 'var')
+ DEFAULTREPONAME = 'opencobra/cobratoolbox'; % set the default repository
+ repoName = DEFAULTREPONAME;
+ end
- if nargin > 0
- if verbose
- gitConf.verbose = verbose;
- else
- gitConf.verbose = false;
+ % soft reset if the repository name is different
+ if ~isempty(gitConf)
+ if ~strcmpi(repoName, [gitConf.remoteUserName '/' gitConf.remoteRepoName])
+ resetDevTools();
end
end
- devToolsDir = fileparts(which('contribute.m'));
+ % check the system and set the configuration
+ if exist('printLevel', 'var')
+ checkSystem(mfilename, repoName, printLevel);
+ else
+ checkSystem(mfilename, repoName);
+ end
+
+ finishup = onCleanup(@() resetDevTools());
+
+ devToolsDir = fileparts(which(mfilename));
% change to the directory of the devTools
cd(devToolsDir);
@@ -38,7 +58,7 @@ function contribute(verbose)
fprintf(gitConf.launcher);
- choice = input('\n (You can abort any process using CTRL-C)\n\n [1] Start a new feature (branch).\n [2] Select an existing feature (branch) to work on.\n [3] Publish a feature (branch).\n [4] Delete a feature (branch).\n [5] Update the fork.\n\n -> Please select what you want to do (enter the number): ', 's');
+ choice = input('\n (You can abort any process using CTRL+C)\n\n [1] Start a new feature (branch).\n [2] Select an existing feature (branch) to work on.\n [3] Publish a feature (branch).\n [4] Delete a feature (branch).\n [5] Update the fork.\n\n -> Please select what you want to do (enter the number): ', 's');
choice = str2num(choice);
@@ -69,7 +89,7 @@ function contribute(verbose)
exitFlag = false;
else
% initialize the development tools
- initDevTools();
+ initDevTools(repoName);
% change to the fork diretory
cd(gitConf.fullForkDir);
@@ -128,6 +148,9 @@ function contribute(verbose)
end
end
+ resetDevToolsFlag = false;
+
% change back to the current directory
cd(currentDir);
+
end
diff --git a/docs/.documenter.enc b/docs/.documenter.enc
new file mode 100644
index 0000000..e69de29
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..489d6fd
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,228 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help
+help:
+ @echo "Please use \`make ' where is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " applehelp to make an Apple Help Book"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " epub3 to make an epub3"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " xml to make Docutils-native XML files"
+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+ @echo " coverage to run coverage check of the documentation (if enabled)"
+ @echo " dummy to check syntax errors of document sources"
+
+.PHONY: clean
+clean:
+ rm -rf $(BUILDDIR)/*
+
+.PHONY: html
+html:
+ @echo "Generating list of suggestions for the websearch."
+ python generateJSONList.py
+ @echo
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+.PHONY: dirhtml
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+.PHONY: singlehtml
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+.PHONY: pickle
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+.PHONY: json
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+.PHONY: htmlhelp
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+.PHONY: qthelp
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MWE.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MWE.qhc"
+
+.PHONY: applehelp
+applehelp:
+ $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
+ @echo
+ @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
+ @echo "N.B. You won't be able to view it unless you put it in" \
+ "~/Library/Documentation/Help or install it in your application" \
+ "bundle."
+
+.PHONY: devhelp
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/MWE"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/MWE"
+ @echo "# devhelp"
+
+.PHONY: epub
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+.PHONY: epub3
+epub3:
+ $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
+ @echo
+ @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
+
+.PHONY: latex
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+.PHONY: latexpdf
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+.PHONY: latexpdfja
+latexpdfja:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through platex and dvipdfmx..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+.PHONY: text
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+.PHONY: man
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+.PHONY: texinfo
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+.PHONY: info
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+.PHONY: gettext
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+.PHONY: changes
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+.PHONY: linkcheck
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+.PHONY: doctest
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+.PHONY: coverage
+coverage:
+ $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
+ @echo "Testing of coverage in the sources finished, look at the " \
+ "results in $(BUILDDIR)/coverage/python.txt."
+
+.PHONY: xml
+xml:
+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+ @echo
+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+.PHONY: pseudoxml
+pseudoxml:
+ $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+ @echo
+ @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
+
+.PHONY: dummy
+dummy:
+ $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
+ @echo
+ @echo "Build finished. Dummy builder generates no files."
diff --git a/docs/generateJSONList.py b/docs/generateJSONList.py
new file mode 100644
index 0000000..53f9038
--- /dev/null
+++ b/docs/generateJSONList.py
@@ -0,0 +1,44 @@
+import os
+import json
+import errno
+
+def mkdir_p(path):
+ try:
+ os.makedirs(path)
+ except OSError as exc: # Python >2.5
+ if exc.errno == errno.EEXIST and os.path.isdir(path):
+ pass
+ else:
+ raise
+
+
+def mkdir_p(path):
+ try:
+ os.makedirs(path)
+ except OSError as exc: # Python >2.5
+ if exc.errno == errno.EEXIST and os.path.isdir(path):
+ pass
+ else:
+ raise
+
+def path_to_list(path):
+ d = []
+ path_length = len(path)
+ print path_length, path
+ for root, directories, filenames in os.walk(path):
+ for filename in filenames:
+ print os.path.join('source', 'modules', root[path_length+1:], 'index.rst')
+ if filename[-2:] == '.m' and os.path.isfile(os.path.join('source', 'modules', root[path_length+1:], 'index.rst')):
+ website_url = os.path.join("modules", root[path_length+1:], "index.html")
+ website_url += "?highlight=" + filename[:-2]
+ website_url += "#" + '.'.join(['src'] + [filename[:-2]])
+ d.append({'name': filename[:-2],
+ 'website_url': website_url})
+ print root, filename
+ return d
+
+destination_dir = os.path.join('source', '_static', 'json')
+mkdir_p(destination_dir)
+with open(os.path.join(destination_dir, 'functions.json'), 'w') as f:
+ d = path_to_list('../src/.')
+ json.dump(d, f)
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 0000000..175c844
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,6 @@
+git+https://github.com/uni-lu/sphinx.git@develop#egg=sphinx
+git+https://github.com/syarra/sphinxcontrib-matlabdomain#egg=sphinxcontrib-matlabdomain
+sphinx_rtd_theme
+git+https://github.com/uni-lu/sphinx_julia_theme.git@develop#egg=sphinx_julia_theme
+git+https://github.com/syarra/Documenter.py@develop#egg=documenter
+git+https://github.com/uni-lu/sphinxcontrib-napoleon.git@develop#egg=sphinxcontrib_napoleon
diff --git a/docs/source/_static/browserconfig.xml b/docs/source/_static/browserconfig.xml
new file mode 100644
index 0000000..efcaaf6
--- /dev/null
+++ b/docs/source/_static/browserconfig.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+ #da532c
+
+
+
diff --git a/docs/source/_static/img/android-chrome-192x192.png b/docs/source/_static/img/android-chrome-192x192.png
new file mode 100644
index 0000000..6bc6706
Binary files /dev/null and b/docs/source/_static/img/android-chrome-192x192.png differ
diff --git a/docs/source/_static/img/android-chrome-384x384.png b/docs/source/_static/img/android-chrome-384x384.png
new file mode 100644
index 0000000..7e97089
Binary files /dev/null and b/docs/source/_static/img/android-chrome-384x384.png differ
diff --git a/docs/source/_static/img/apple-touch-icon.png b/docs/source/_static/img/apple-touch-icon.png
new file mode 100644
index 0000000..fc8de68
Binary files /dev/null and b/docs/source/_static/img/apple-touch-icon.png differ
diff --git a/docs/source/_static/img/favicon-16x16.png b/docs/source/_static/img/favicon-16x16.png
new file mode 100644
index 0000000..a9da3d2
Binary files /dev/null and b/docs/source/_static/img/favicon-16x16.png differ
diff --git a/docs/source/_static/img/favicon-32x32.png b/docs/source/_static/img/favicon-32x32.png
new file mode 100644
index 0000000..1d6637e
Binary files /dev/null and b/docs/source/_static/img/favicon-32x32.png differ
diff --git a/docs/source/_static/img/favicon.ico b/docs/source/_static/img/favicon.ico
new file mode 100644
index 0000000..86ba614
Binary files /dev/null and b/docs/source/_static/img/favicon.ico differ
diff --git a/assets/devTools_logo.png b/docs/source/_static/img/logo_devTools.png
similarity index 100%
rename from assets/devTools_logo.png
rename to docs/source/_static/img/logo_devTools.png
diff --git a/docs/source/_static/img/mstile-150x150.png b/docs/source/_static/img/mstile-150x150.png
new file mode 100644
index 0000000..1a5cebd
Binary files /dev/null and b/docs/source/_static/img/mstile-150x150.png differ
diff --git a/docs/source/_static/img/safari-pinned-tab.svg b/docs/source/_static/img/safari-pinned-tab.svg
new file mode 100644
index 0000000..c686f93
--- /dev/null
+++ b/docs/source/_static/img/safari-pinned-tab.svg
@@ -0,0 +1,37 @@
+
+
+
diff --git a/docs/source/_static/json/manifest.json b/docs/source/_static/json/manifest.json
new file mode 100644
index 0000000..870e24e
--- /dev/null
+++ b/docs/source/_static/json/manifest.json
@@ -0,0 +1,18 @@
+{
+ "name": "",
+ "icons": [
+ {
+ "src": "../img/android-chrome-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "../img/android-chrome-384x384.png",
+ "sizes": "384x384",
+ "type": "image/png"
+ }
+ ],
+ "theme_color": "#ffffff",
+ "background_color": "#ffffff",
+ "display": "standalone"
+}
diff --git a/docs/source/cite.rst b/docs/source/cite.rst
new file mode 100644
index 0000000..a8af629
--- /dev/null
+++ b/docs/source/cite.rst
@@ -0,0 +1,62 @@
+How to cite
+===========
+
+.. include:: ../../README.rst
+ :start-after: begin-how-to-cite-marker
+ :end-before: end-how-to-cite-marker
+
+
+.. |macos| raw:: html
+
+
+
+
+.. |linux| raw:: html
+
+
+
+
+.. |windows| raw:: html
+
+
+
+
+.. |warning| raw:: html
+
+
+
+
+.. |matlab| raw:: html
+
+
+
+
+.. |tada| raw:: html
+
+
+
+
+.. |thumbsup| raw:: html
+
+
+
+
+.. |bulb| raw:: html
+
+
+
+
+.. |tutorials| raw:: html
+
+
+
+
+.. |latest| raw:: html
+
+
+
+
+.. |forum| raw:: html
+
+
+
diff --git a/docs/source/conf.py b/docs/source/conf.py
new file mode 100644
index 0000000..70e5355
--- /dev/null
+++ b/docs/source/conf.py
@@ -0,0 +1,394 @@
+# -*- coding: utf-8 -*-
+#
+# Documentation build configuration file, created by
+# sphinx-quickstart on Fri Nov 18 11:12:41 2016.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+
+import os
+import sys
+
+sys.path.append('sphinxext')
+from github_linkcode import github_linkcode_resolve
+
+
+sys.path.insert(0, os.path.abspath(os.path.join('..', '..', '..')))
+# sys.path.insert(0, os.path.abspath('.'))
+
+# tell Sphinx matlab extension where to find matlab code.
+matlab_src_dir = os.path.abspath(os.path.join('..', '..'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinxcontrib.napoleon',
+ 'sphinxcontrib.matlab',
+ 'github',
+ 'sphinx.ext.mathjax',
+ 'sphinx.ext.linkcode',
+ 'sphinxcontrib.fulltoc']
+
+mathjax_path = 'https://cdn.rawgit.com/mathjax/MathJax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML'
+
+def linkcode_resolve(domain, info):
+ return github_linkcode_resolve(
+ domain=domain,
+ info=info,
+ allowed_module_names=['src'],
+ github_org_id='opencobra',
+ github_repo_id='MATLAB.devTools',
+ branch='master',
+ source_prefix='')
+
+
+# autodoc_member_order='groupwise'
+primary_domain = 'mat'
+
+# remove path in function names
+add_module_names = False
+
+# Add any paths that contain templates here, relative to this directory.
+# templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+source_suffix = ['.rst']
+
+# The encoding of source files.
+#
+source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'contents'
+
+# General information about the project.
+project = u'MATLAB.devTools'
+copyright = u'2017-2018, the MATLAB.devTools developers'
+author = u'The MATLAB.devTools developers'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = u'0.1'
+# The full version, including alpha/beta/rc tags.
+release = u'0.1.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+conf_py_path = os.getcwd()
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#
+# today = ''
+#
+# Else, today_fmt is used as the format for a strftime call.
+#
+# today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This patterns also effect to html_static_path and html_extra_path
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#
+# default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#
+# add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#
+# add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#
+# show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+# modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+# keep_warnings = False
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = True
+
+
+# -- Options for HTML output ----------------------------------------------
+
+html_theme = "sphinx_julia_theme"
+
+import sphinx_julia_theme
+import sphinx_rtd_theme
+
+html_theme_path = [sphinx_rtd_theme.get_html_theme_path(),
+ sphinx_julia_theme.get_theme_dir()]
+print html_theme_path
+html_sidebars = sphinx_julia_theme.default_sidebars()
+
+# shutil.copy()
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#
+html_theme_options = {'display_version': False}
+
+html_context = {'conf_py_path': os.path.join(os.sep, 'docs', 'source', ''),
+ 'github_user': 'opencobra',
+ 'github_repo': 'MATLAB.devTools',
+ 'github_version': 'master',
+ 'logo': 'img/logo_devTools.png',
+ 'favicon_apple_touch': 'img/apple-touch-icon.png',
+ 'favicon32x32': 'img/favicon-32x32.png',
+ 'favicon16x16': 'img/favicon-16x16.png',
+ 'favicon_safari_pinned_tab': 'img/safari-pinned-tab.svg',
+ 'manifest': 'json/manifest.json',
+ 'browserconfig': 'browserconfig.xml',
+ 'theme_logo_only': False,
+ 'show_source': False}
+# 'display_github': True}
+# Add any paths that contain custom themes here, relative to this directory.
+# html_theme_path = []
+
+# The name for this set of Sphinx documents.
+# " v documentation" by default.
+#
+html_title = u'MATLAB.devTools'
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#
+# html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#
+html_logo = '_static/img/logo_devTools.png'
+
+# The name of an image file (relative to this directory) to use as a favicon of
+# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#
+html_favicon = '_static/img/favicon.ico'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#
+# html_extra_path = []
+
+# If not None, a 'Last updated on:' timestamp is inserted at every page
+# bottom, using the given strftime format.
+# The empty string is equivalent to '%b %d, %Y'.
+#
+# html_last_updated_fmt = None
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#
+# html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#
+# html_sidebars = {'index': 'indexsidebar.html'}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#
+# html_index = 'index.html'
+# html_additional_pages = {'index': 'index.html'}
+
+# If false, no module index is generated.
+#
+# html_domain_indices = True
+
+# If false, no index is generated.
+#
+# html_use_index = False
+
+# If true, the index is split into individual pages for each letter.
+#
+# html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#
+# html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#
+# html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#
+# html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#
+# html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+# html_file_suffix = None
+
+# Language to be used for generating the HTML full-text search index.
+# Sphinx supports the following languages:
+# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
+# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
+#
+# html_search_language = 'en'
+
+# A dictionary with options for the search language support, empty by default.
+# 'ja' uses this config value.
+# 'zh' user can custom change `jieba` dictionary path.
+#
+# html_search_options = {'type': 'default'}
+
+# The name of a javascript file (relative to the configuration directory) that
+# implements a search results scorer. If empty, the default will be used.
+#
+# html_search_scorer = 'scorer.js'
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'MATLAB.devToolsDoc'
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ #
+ # 'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ #
+ # 'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ #
+ # 'preamble': '',
+
+ # Latex figure (float) alignment
+ #
+ # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (master_doc, 'MATLAB.devTools.tex', u'The MATLAB.devTools Documentation',
+ u'The MATLAB.devTools developers', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#
+# latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#
+# latex_use_parts = False
+
+# If true, show page references after internal links.
+#
+# latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#
+# latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#
+# latex_appendices = []
+
+# It false, will not define \strong, \code, itleref, \crossref ... but only
+# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added
+# packages.
+#
+# latex_keep_old_macro_names = True
+
+# If false, no module index is generated.
+#
+# latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ (master_doc, 'MATLAB.devTools', u'The MATLAB.devTools Documentation',
+ [author], 1)
+]
+
+# If true, show URL addresses after external links.
+#
+# man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ (master_doc, 'MATLAB.devTools', u'The MATLAB.devTools Documentation',
+ author, 'MATLAB.devTools', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#
+# texinfo_appendices = []
+
+# If false, no module index is generated.
+#
+# texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#
+# texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#
+# texinfo_no_detailmenu = False
diff --git a/docs/source/contents.rst b/docs/source/contents.rst
new file mode 100644
index 0000000..7da0986
--- /dev/null
+++ b/docs/source/contents.rst
@@ -0,0 +1,15 @@
+MATLAB.devTools
+===============
+
+.. toctree::
+ :maxdepth: 2
+
+ Home
+ installation
+ getstarted
+ contribute
+ modules/index
+ faq
+ troubleshooting
+ cite
+ funding
diff --git a/docs/source/contr_cobratoolbox.rst b/docs/source/contr_cobratoolbox.rst
new file mode 100644
index 0000000..fa53b5b
--- /dev/null
+++ b/docs/source/contr_cobratoolbox.rst
@@ -0,0 +1,213 @@
+The COBRA Toolbox
+^^^^^^^^^^^^^^^^^
+
+|asciicast|
+
+.. include:: ../../README.rst
+ :start-after: begin-screencast-marker
+ :end-before: end-screencast-marker
+
+Introduction
+------------
+
+A comprehensive code base such as the COBRA Toolbox evolves constantly. The
+open-source community is very active, and collaborators submit their
+contributions frequently. The more a new feature or bug fix is interlinked with
+existing functions, the higher the risk of a new addition breaking instantly
+code that is heavily used on a daily basis. In order to decrease this risk, a
+continuous integration setup interlinked with the version control system git
+has been set up. A git-tracked repository is essentially a folder with code or
+other documents of which all incremental changes are tracked by date and user.
+
+Any incremental changes to the code are called commits. The main advantage of
+git over other version control systems is the availability of branches. In
+simple terms, a branch contains a sequence of incremental changes to the code.
+A branch is also commonly referred to as a feature. Consequently, a
+contribution generally consists of several commits on a branch.
+
+Contributing to the COBRA Toolbox is straightforward. As a contributor to the
+COBRA Toolbox is likely more familiar with MATLAB than with the internal
+mechanics of git, the `MATLAB.devTools` have been developed specifically
+to contribute to a git-tracked repository located on the Github server. In
+Figure 6, an overview of the two online repositories as well as their local
+copies is given. There are two ways of using the COBRA Toolbox, which depends
+on the type of user. A regular user might only want to use the opencobra
+repository and enjoy stability (option A), whereas more advanced users might
+want to develop their own features and actively make contributions to the
+opencobra repository (option B).
+
+|branchModel|
+
+ - **Option A** The `opencobra/cobratoolbox `_ repository is a
+ public repository that is read-only. Once the opencobra repository has been
+ installed in the folder `cobratoolbox`, all branches
+ (including ``master`` and ``develop``) are available locally. In the local directory
+ `cobratoolbox` folder, the user has read and write access, but cannot push eventual
+ changes back to the opencobra repository. It is the default and stable ``master``
+ branch only that should be used. The local copy located in the cobratoolbox
+ directory can be updated (both branches).
+
+ - **Option B** In order to make changes to the
+ opencobra repository, or, in other words, contribute, you must obtain your own
+ personal copy first. You must register on the `Github website `_ in order to obtain a username. First, click on the button FORK at the top
+ right corner of the official `opencobra/cobratoolbox `_ repository website
+ in order to create a personal copy
+ (or fork) with write and read access of the opencobra repository. This copy is
+ accessible under `https://github.com//cobratoolbox`, where `` is
+ your Github username. In the
+ `fork-cobratoolbox` folder, other user specific branches may exist in addition to
+ the ``master`` and ``develop`` branches.
+
+After initialisation of the MATLAB.devTools, the user and developer may have two
+folders: a ``cobratoolbox`` folder with the stable ``master`` branch checked out, and a
+``fork-cobratoolbox`` folder with the ``develop`` branch checked out. Detailed
+instructions for troubleshooting and/or contributing to the COBRA Toolbox using
+the terminal (or shell) are provided :ref:`here `.
+
+After the official opencobra version of the COBRA Toolbox has been installed,
+it is possible to install the MATLAB.devTools from within MATLAB:
+
+.. code:: console
+
+ >> installDevTools
+
+With this command, the directory MATLAB.devTools is created next to the
+cobratoolbox installation directory. The MATLAB.devTools can also be installed
+from the terminal (or shell):
+
+.. code:: console
+
+ $ git clone git@github.com:opencobra/MATLAB.devTools
+
+|warning| A working internet connection is required and git and curl must be
+installed. Installation instructions are provided on the main repository page
+of the MATLAB.devTools. A valid passphrase-less SSH key must be set in the
+Github account settings in order to contribute without entering a password
+while securely communicating with the Github server.
+
+Start a new contribution
+------------------------
+
+The MATLAB.devTools are configured on the fly or whenever the configuration
+details are not present. The first time a user runs contribute, the personal
+repository (fork) is downloaded (cloned) into a new folder named
+`fork-cobratoolbox` at the location specified by the user. In this local folder,
+both ``master`` and ``develop`` branches exist, but it is the ``develop`` branch that is
+automatically selected (checked out). Any new contributions are derived from
+the develop branch. Initialising a contribution using the MATLAB.devTools is
+straightforward. In MATLAB, type:
+
+.. code:: matlab
+
+ >> contribute % then select procedure [1]
+
+If the MATLAB.devTools are already configured, procedure [1] updates the fork
+(if necessary) and initialises a new branch with a name requested during the
+process. Once the contribution is initialised, files can be added, modified or
+deleted in the `fork-cobratoolbox` folder. A contribution is successfully
+initialised when the user is presented with a brief summary of configuration
+details. Instructions on how to proceed are also provided.
+
+|warning| The location of the fork must be specified as the root directory.
+There will be a warning issued if the path already contains another git-tracked
+repository.
+
+Continue an existing contribution
+---------------------------------
+
+An existing contribution can be continued after a while. This step is
+particularly important in order to retrieve all changes that have been made to
+the opencobra repository in the meantime.
+
+.. code:: matlab
+
+ >> contribute % then select procedure [2]
+
+Procedure ``[2]`` pulls all changes from the opencobra repository, and rebases the
+existing contribution. In other words, existing commits are shifted forward and
+placed after all commits made on the develop branch of the opencobra
+repository.
+
+|warning| Before attempting to continue working on an existing
+feature, make sure that you published your commits.
+
+Publish a contribution
+-----------------------
+
+Publishing a contribution means uploading the incremental code changes to the
+fork. The changes are available in public, but not yet available in the
+opencobra repository. A contribution may only be accepted in the official
+repository once a pull request has been submitted. It is not necessary to open
+a pull request if you want to simply upload your contribution to your fork.
+
+.. code:: matlab
+
+ >> contribute % then select procedure [3]
+
+When running procedure ``[3]``, you have two options:
+
+- **Option A** Simple contribution without opening a pull request: All changes
+ to the code are individually listed and the user is asked explicitly which
+ changes shall be added to the commit. Once all changes have been added, a
+ commit message must be entered. Upon confirmation, the changes are pushed to
+ the online fork automatically.
+
+- **Option B** Publishing and opening a pull request: The procedure for
+ submitting a pull request is the same as option (A) with the difference that
+ when selecting to open a pull request, a link is provided that leads to a
+ pre-configured website according to the contributing guidelines. The pull
+ request is then one click away.
+
+|warning| After following procedures ``[1]`` and ``[2]``, all changes should be
+published using procedure ``[3]`` before stopping to work on that contribution.
+When following procedure ``[3]``, the incremental changes are uploaded to the
+remote server. It is advised to publish often, and make small incremental
+changes to the code. There is no need for opening a pull request immediately
+(option **A**) if there are more changes to be made. A pull request may be opened
+at any time, even manually directly from the Github website.
+
+Deleting a contribution
+-----------------------
+
+If a contribution has been merged into the develop branch of the opencobra
+repository (accepted pull request), the contribution (feature or branch) can be
+safely deleted both locally and remotely on the fork by running contribute and
+selecting procedure ``[4]``.
+
+Note that deleting a contribution deletes all the changes that have been made
+on that feature (branch). It is not possible to selectively delete a commit
+using the MATLAB.devTools. Instead, create a new branch by following procedure
+``[1]``, and follow the instructions to cherry-pick (see
+:ref:`troubleshooting`).
+
+|warning| Make sure that your changes are either merged or saved locally if you
+need them. Once procedure ``[4]`` is concluded, all changes on the deleted
+branch are removed, both locally and remotely. No commits can be recovered.
+
+Update your fork
+----------------
+
+It is sometimes useful to simply update the fork without starting a new
+contribution. The local fork can be updated using procedure ``[5]`` of the
+contribute menu.
+
+.. code:: matlab
+
+ >> contribute % then select procedure [5]
+
+Before updating your fork, make sure that no changes are present in the local
+directory `fork-cobratoolbox`. You can do so by typing:
+
+.. code:: matlab
+
+ >> checkStatus
+
+If there are changes listed, publish them by selecting procedure ``[3]`` of the
+contribute menu.
+
+.. |branchModel| image:: https://prince.lcsb.uni.lu/img/figure6.png
+
+.. include:: ../../README.rst
+ :start-after: begin-icon-marker
+ :end-before: end-icon-marker
+
diff --git a/docs/source/contr_cobratutorials.rst b/docs/source/contr_cobratutorials.rst
new file mode 100644
index 0000000..da33a76
--- /dev/null
+++ b/docs/source/contr_cobratutorials.rst
@@ -0,0 +1,9 @@
+COBRA.tutorials
+^^^^^^^^^^^^^^^
+
+.. include:: ../../README.rst
+ :start-after: begin-contribute-cobratutorials-marker
+ :end-before: end-contribute-cobratutorials-marker
+
+In case of troubleshooting, please refer `this <>`__ section.
+
diff --git a/docs/source/contr_otherrepo.rst b/docs/source/contr_otherrepo.rst
new file mode 100644
index 0000000..18d0643
--- /dev/null
+++ b/docs/source/contr_otherrepo.rst
@@ -0,0 +1,11 @@
+Other repository
+^^^^^^^^^^^^^^^^
+
+.. include:: ../../README.rst
+ :start-after: begin-contribute-other-repo-marker
+ :end-before: end-contribute-other-repo-marker
+
+.. include:: ../../README.rst
+ :start-after: begin-icon-marker
+ :end-before: end-icon-marker
+
diff --git a/docs/source/contribute.rst b/docs/source/contribute.rst
new file mode 100644
index 0000000..945d50d
--- /dev/null
+++ b/docs/source/contribute.rst
@@ -0,0 +1,8 @@
+.. _contribute:
+
+How to configure and use
+========================
+
+.. include:: contr_cobratoolbox.rst
+.. include:: contr_cobratutorials.rst
+.. include:: contr_otherrepo.rst
diff --git a/docs/source/faq.rst b/docs/source/faq.rst
new file mode 100644
index 0000000..2cf3c72
--- /dev/null
+++ b/docs/source/faq.rst
@@ -0,0 +1,111 @@
+.. _faq:
+
+Frequently Asked Questions (FAQ)
+================================
+
+General questions
+-----------------
+
+How should I name my contribution?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Initiate a contribution per theme/topic/feature/bug fix that you work
+on. Don’t mix features and think of an explicit name, i.e.
+``bug-fix-function1`` or ``add-tests-function2``. Avoid generic names,
+such as ``my-great-feature`` or ``fix`` or ``contribution-myName``.
+
+How can I check the history of a file?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can check the history of a file by typing in MATLAB:
+
+.. code:: matlab
+
+ >> history('fileName.m')
+
+How do I submit a Pull Request (PR)?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Once you submit your contribution (menu option [3]), you will be
+presented with a link that leads you directly to the pull request (PR).
+
+Print more detailed debugging information (verbose)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you encounter a problem, or suspect that something is not behaving
+properly, please run:
+
+.. code:: matlab
+
+ >> contribute(1)
+
+and follow the process as normally. This will set ``printLevel = 1``.
+You can also set permanently ``gitConf.printLevel = 1;`` in
+``assets/confDevTools.m``.
+
+
+Technical questions
+-------------------
+
+I receive a ``Permission denied`` error. What can I do?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You may encounter the following error:
+
+::
+
+ Permission denied (publickey)
+ fatal: could not read from the repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
+
+This error can have multiple reasons, but most likely, the SSH key is
+not configured properly. Please follow the `configuration
+instructions `__
+carefully.
+
+Another source of this error may be that you have set a passphrase when
+generating the SSH key. Please leave the passphrase empty when
+generating the SSH key.
+
+Mismatch of the version of ``openSSL`` (Linux)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You might be in the situation that you receive the following error:
+
+::
+
+ OpenSSL version mismatch. Built against 1000207f, you have 100010bf
+
+In that case, you should run the following command:
+
+::
+
+ sudo mv /bin/glnxa64/libcrypto.so.1.0.0 /bin/glnxa64/libcrypto.so.1.0.0_bk
+
+where ```` corresponds to the installation of
+``MATLAB``, e.g., ``/usr/local/MATLAB/R2016b``
+
+Resolve unexpected behavior - reset
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you encounter unexpected behavior, please try to reset the
+``MATLAB.devTools`` using the ``resetDevTools`` functionality.
+
+.. include:: ../../README.rst
+ :start-after: begin-reset-marker
+ :end-before: end-reset-marker
+
+If you have files or changes that appear and would like to reset your
+local fork (without re-cloning) again, type:
+
+.. code:: matlab
+
+ >> resetLocalFork
+
+How can I abort a process?
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can abort any process using ``CTRL+C`` (hit ``CTRL`` and ``C`` on
+your keyboard).
diff --git a/docs/source/funding.rst b/docs/source/funding.rst
new file mode 100644
index 0000000..3449415
--- /dev/null
+++ b/docs/source/funding.rst
@@ -0,0 +1,58 @@
+Funding
+=======
+
+.. raw:: html
+
+
+
+
+
+
+
+
+
+
+
+
+ National Centre of Excellence in Research (NCER) on Parkinson’s disease.
+
+
+
+
+
+
+
+
+
+
+ U.S. Department of Energy, Offices of Advanced Scientific Computing Research and the Biological and Environmental Research as part of the Scientific Discovery Through Advanced Computing program, grant no. DE-SC0010429
+
+
+
+
+
+
+
+ Fonds National de la Recherche grant O16/11402054 and the Luxembourg National Research Fund (FNR) ATTRACT program grant (FNR/A12/01).
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/source/getstarted.rst b/docs/source/getstarted.rst
new file mode 100644
index 0000000..b69b1a8
--- /dev/null
+++ b/docs/source/getstarted.rst
@@ -0,0 +1,11 @@
+How to get started
+==================
+
+.. include:: ../../README.rst
+ :start-after: begin-getstarted-marker
+ :end-before: end-getstarted-marker
+
+.. include:: ../../README.rst
+ :start-after: begin-icon-marker
+ :end-before: end-icon-marker
+
diff --git a/docs/source/index.rst b/docs/source/index.rst
new file mode 100644
index 0000000..11386cb
--- /dev/null
+++ b/docs/source/index.rst
@@ -0,0 +1,27 @@
+.. _index:
+
+.. image:: _static/img/logo_devTools.png
+ :align: center
+ :width: 160px
+
+MATLAB.devTools
+===============
+
+.. rst-class:: under-title
+
+MATLAB.devTools - Contribute the smart way
+
+.. raw:: html
+
+
+
+
+ View MATLAB.devTools source code on .
+
+
+.. include:: ../../README.rst
+ :start-after: begin-description-marker
+ :end-before: end-description-marker
+
diff --git a/docs/source/installation.rst b/docs/source/installation.rst
new file mode 100644
index 0000000..36534d5
--- /dev/null
+++ b/docs/source/installation.rst
@@ -0,0 +1,19 @@
+.. _installation:
+
+Installation
+============
+
+.. include:: prerequisites.rst
+
+
+Installation
+------------
+
+.. include:: ../../README.rst
+ :start-after: begin-installation-marker
+ :end-before: end-installation-marker
+
+.. include:: ../../README.rst
+ :start-after: begin-icon-marker
+ :end-before: end-icon-marker
+
diff --git a/docs/source/modules/index.rst b/docs/source/modules/index.rst
new file mode 100644
index 0000000..d475b7b
--- /dev/null
+++ b/docs/source/modules/index.rst
@@ -0,0 +1,8 @@
+.. _modules_functions:
+
+Functions
+---------
+
+.. automodule:: src
+ :members:
+
diff --git a/docs/source/prerequisites.rst b/docs/source/prerequisites.rst
new file mode 100644
index 0000000..cd32dbb
--- /dev/null
+++ b/docs/source/prerequisites.rst
@@ -0,0 +1,134 @@
+Pre-requisites
+--------------
+
+GitHub SSH configuration
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+You have to register the SSH key of each computer that you are planning
+to use the ``MATLAB.devTools`` on.
+
+- **Check if you already have an SSH key:**
+
+.. code:: console
+
+ $ ls -al ~/.ssh
+
+If there is a file with an extension ``.pub``, you already have an SSH
+key. Now, you have to **add your SSH key to Github**. More help is
+`here `__.
+
+- **Generate the SSH key on your computer:** If you don’t have yet an
+ SSH key (see previous step), you have to generate one (more help is
+ `here `__):
+
+.. code:: console
+
+ $ ssh-keygen -t rsa -C "first.last@server.com"
+
+ Leave the passphrase empty when generating the SSH key.
+
+- **Add the SSH** to `your Github
+ account `__ by following the steps
+ `here `__.
+
+Can I check if everything is properly set up before I start?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Please ensure that you have a working ``MATLAB`` installation.
+
+You can check if you have a working installation of ``git`` by typing in
+the ``Terminal`` (on ``linux`` and ``macOS``) or ``cmd`` (in
+``Windows``, not ``Git Bash``):
+
+.. code:: bash
+
+ $ git --version
+
+If installed properly, this will return ``git version 2.13.1 [...]`` or
+similar with another version number.
+
+You can then check if your ``git`` is properly configured by typing in
+the terminal (or GUI Bash):
+
+.. code:: bash
+
+ $ git config --get user.github-username
+
+which will return your Github username if everything is properly set up.
+Similarly, check the configured email by typing in the terminal (or GUI
+Bash):
+
+.. code:: bash
+
+ $ git config --get user.email
+
+You can check if you have a working installation of ``curl`` by typing
+in the terminal (``cmd`` on Windows, not ``Git Bash``):
+
+.. code:: bash
+
+ $ curl --version
+
+which will return ``curl 7.51.0 [...]`` or similar with another version
+number if installed properly.
+
+System configuration
+^^^^^^^^^^^^^^^^^^^^
+
+You must have ``git`` and ``curl`` installed. Please also ensure that
+you have ``MATLAB``
+`installed `__.
+
+**Windows**
+
+Please download the ``git`` tools for Windows from
+`here `__. During the installation
+process, please ensure that you select **Use Git Bash and optional Unix
+tools from the Windows Command prompt**. In addition, please make sure
+that you select **Checkout as-is, commit Unix-style line endings**.
+
+|windows0| |windows1|
+
+**Linux (Ubuntu or Debian)**
+
+.. code:: bash
+
+ $ sudo apt-get install git-all curl
+
+**macOS**
+
+In order to install ``git``, install the `Xcode Command Line
+Tools `__.
+For ``curl``, follow the instructions
+`here `__.
+
+Github and local ``git`` configuration
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you don’t have a GitHub account, please sign up
+`here `__. For the very first time, you must
+**fork** the repository of The COBRA Toolbox. Browse to the `original
+repository `__ and click on
+the button .
+
+On **Linux (Ubuntu)** or **macOS**, start the terminal (or any other
+shell). On **Windows**, start ``GUI Bash``. Then type
+
+.. code:: bash
+
+ $ git config --global user.github-username "yourGitHubUsername"
+ $ git config --global user.email "first.last@server.com"
+
+Please replace ``"yourGitHubUsername"`` and ``"first.last@server.com"``
+with your respective credentials.
+
+.. |windows0| image:: https://prince.lcsb.uni.lu/img/installation_git_windows_0.png
+ :width: 280px
+
+.. |windows1| image:: https://prince.lcsb.uni.lu/img/installation_git_windows_1.png
+ :width: 280px
+
+.. include:: ../../README.rst
+ :start-after: begin-icon-marker
+ :end-before: end-icon-marker
+
diff --git a/docs/source/sphinxext/__init__.py b/docs/source/sphinxext/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/docs/source/sphinxext/github_linkcode.py b/docs/source/sphinxext/github_linkcode.py
new file mode 100644
index 0000000..dfe9e61
--- /dev/null
+++ b/docs/source/sphinxext/github_linkcode.py
@@ -0,0 +1,243 @@
+"""Sphinx extension to link to source code on GitHub.
+
+This links to source code for modules, classes, etc. to the correct line on
+GitHub. This prevents having to bundle the source code along with the
+documentation, and better ties everything together.
+
+
+Setup
+=====
+
+To use this, you'll need to import the module and define your own
+:py:func:`linkcode_resolve` in your :file:`conf.py`::
+
+ from beanbag_docutils.sphinx.ext.github import github_linkcode_resolve
+
+ extensions = [
+ ...
+ 'sphinx.ext.linkcode',
+ ...
+ ]
+
+ def linkcode_resolve(domain, info):
+ return github_linkcode_resolve(
+ domain=domain,
+ info=info,
+ allowed_module_names=['mymodule'],
+ github_org_id='myorg',
+ github_repo_id='myrepo',
+ branch='master',
+ source_prefix='src/')
+
+``source_prefix`` and ``allowed_module_names`` are optional. See the
+docs for :py:func:`github_linkcode_resolve` for more information.
+"""
+
+from __future__ import unicode_literals
+
+import inspect
+import re
+import subprocess
+import sys
+
+
+GIT_BRANCH_CONTAINS_RE = re.compile(r'^\s*([^\s]+)\s+([0-9a-f]+)\s.*')
+
+
+_head_ref = None
+
+
+def _run_git(cmd):
+ """Run git with the given arguments, returning the output.
+
+ Args:
+ cmd (list of unicode):
+ A list of arguments to pass to :command:`git`.
+
+ Returns:
+ str:
+ The resulting output from the command.
+
+ Raises:
+ subprocess.CalledProcessError:
+ Error calling into git.
+ """
+ p = subprocess.Popen(['git'] + cmd, stdout=subprocess.PIPE)
+ output, error = p.communicate()
+ ret_code = p.poll()
+
+ if ret_code:
+ raise subprocess.CalledProcessError(ret_code, 'git')
+
+ return output
+
+
+def _git_get_nearest_tracking_branch(merge_base, remote='origin'):
+ """Return the nearest tracking branch for the given Git repository.
+
+ Args:
+ merge_base (unicode):
+ The merge base used to locate the nearest tracking branch.
+
+ remote (origin, optional):
+ The remote name.
+
+ Returns:
+ unicode:
+ The nearest tracking branch, or ``None`` if not found.
+ """
+ try:
+ _run_git(['fetch', 'origin', '%s:%s' % (merge_base, merge_base)])
+ except Exception:
+ # Ignore, as we may already have this. Hopefully it won't fail later.
+ pass
+
+ lines = _run_git(['branch', '-rv', '--contains', merge_base]).splitlines()
+
+ remote_prefix = '%s/' % remote
+ best_distance = None
+ best_ref_name = None
+
+ for line in lines:
+ m = GIT_BRANCH_CONTAINS_RE.match(line.strip())
+
+ if m:
+ ref_name = m.group(1)
+ sha = m.group(2)
+
+ if (ref_name.startswith(remote_prefix) and
+ not ref_name.endswith('/HEAD')):
+
+ distance = len(_run_git(['log',
+ '--pretty=format:%%H',
+ '...%s' % sha]).splitlines())
+
+ if best_distance is None or distance < best_distance:
+ best_distance = distance
+ best_ref_name = ref_name
+
+ if best_ref_name and best_ref_name.startswith(remote_prefix):
+ # Strip away the remote.
+ best_ref_name = best_ref_name[len(remote_prefix):]
+
+ return best_ref_name
+
+
+def _get_git_doc_ref(branch):
+ """Return the commit SHA used for linking to source code on GitHub.
+
+ The commit SHA will be cached for future lookups.
+
+ Args:
+ branch (unicode):
+ The branch to use as a merge base.
+
+ Returns:
+ unicode:
+ The commit SHA used for any links, if found, or ``None`` if not.
+ """
+ global _head_ref
+
+ if not _head_ref:
+ try:
+ tracking_branch = _git_get_nearest_tracking_branch(branch)
+ _head_ref = _run_git(['rev-parse', tracking_branch]).strip()
+ except subprocess.CalledProcessError:
+ _head_ref = None
+
+ return _head_ref
+
+
+def github_linkcode_resolve(domain, info, github_org_id, github_repo_id,
+ branch, source_prefix='', allowed_module_names=[]):
+ """Return a link to the source on GitHub for the given autodoc info.
+
+ This takes some basic information on the GitHub project, branch, and
+ what modules are considered acceptable, and generates a link to the
+ approprite line on the GitHub repository browser for the class, function,
+ variable, or other object.
+
+ Args:
+ domain (unicode):
+ The autodoc domain being processed. This only accepts "py", and
+ comes from the original :py:func:`linkcode_resolve` call.
+
+ info (dict):
+ Information on the item being linked to. This comes from the
+ original :py:func:`linkcode_resolve` call.
+
+ github_org_id (unicode):
+ The GitHub organization ID.
+
+ github_repo_id (unicode):
+ The GitHub repository ID.
+
+ branch (unicode):
+ The branch used as a merge base to find the appropriate commit
+ to link to. Callers may want to compute this off of the version
+ number of the project, or some other information.
+
+ source_prefix (unicode, optional):
+ A prefix for any linked filename, in case the module is not at
+ the top of the source tree.
+
+ allowed_module_names (list of unicode, optional):
+ The list of top-level module names considered valid for links.
+ If provided, links will only be generated if residing somewhere
+ in one of the provided module names.
+ """
+ module_name = info['module']
+
+ # print domain != 'mat'
+ # print not module_name
+ # print module_name.split('.')[0]
+ # print allowed_module_names
+ # print (allowed_module_names and
+ # module_name.split('.')[0] not in allowed_module_names)
+ if (domain != 'mat' or
+ not module_name or
+ (allowed_module_names and
+ module_name.split('.')[0] not in allowed_module_names)):
+ # These aren't the modules you're looking for.
+ return None
+
+ # Grab the name of the source file.
+ filename = module_name.replace('.', '/') + '/' + info['fullname'] + '.m'
+
+ # Grab the module referenced in the docs.
+ submod = sys.modules.get(module_name)
+
+ if submod is None:
+ return None
+
+ # Split that, trying to find the module at the very tail of the module
+ # path.
+ obj = submod
+
+ for part in info['fullname'].split('.'):
+ try:
+ obj = getattr(obj, part)
+ except:
+ return None
+
+ # Find the line number of the thing being documented.
+ try:
+ linenum = inspect.findsource(obj)[1]
+ except:
+ linenum = None
+
+ # Build a reference for the line number in GitHub.
+ if linenum:
+ linespec = '#L%d' % (linenum + 1)
+ else:
+ linespec = ''
+
+ # Get the branch/tag/commit to link to.
+ ref = _get_git_doc_ref(branch) or branch
+ # print "branch: ", branch
+ # print ('https://github.com/%s/%s/blob/%s/%s%s%s'
+ # % (github_org_id, github_repo_id, ref, source_prefix,
+ # filename, linespec))
+ return ('https://github.com/%s/%s/blob/%s/%s%s%s'
+ % (github_org_id, github_repo_id, ref, source_prefix,
+ filename, linespec))
diff --git a/docs/source/troubleshooting.rst b/docs/source/troubleshooting.rst
new file mode 100644
index 0000000..17eb424
--- /dev/null
+++ b/docs/source/troubleshooting.rst
@@ -0,0 +1,7 @@
+.. _troubleshooting:
+
+Troubleshooting
+===============
+
+.. include:: troubleshooting/cobratoolbox.rst
+.. include:: troubleshooting/cobratutorials.rst
diff --git a/docs/source/troubleshooting/cobratoolbox.rst b/docs/source/troubleshooting/cobratoolbox.rst
new file mode 100644
index 0000000..ff51612
--- /dev/null
+++ b/docs/source/troubleshooting/cobratoolbox.rst
@@ -0,0 +1,224 @@
+The COBRA Toolbox
+^^^^^^^^^^^^^^^^^
+
+|warning| This section is tailored to users who feel comfortable using
+the terminal (or shell). It is recommended for other users
+to follow :ref:`these instructions `.
+
+|warning| A Github account is required and `git` must be installed. You also
+must already have forked the `opencobra/cobratoolbox
+`__ repository by clicking on
+the fork button on the main `opencobra/cobratoolbox
+`__ repository page.
+
+Development scheme
+------------------
+
+The repository of the COBRA Toolbox is version controlled with the open-source
+standard ``git`` on the public code development site `github.com
+`__. Any incremental change to the code is wrapped in a
+commit, tagged with a specific tag (called SHA1), a commit message, and author
+information, such as the email address and the user name. Contributions to the
+COBRA Toolbox are consequently commits that are made on branches.
+
+The development scheme adopted in the repository of the COBRA Toolbox has two
+branches: a `master` and a `develop` branch. The stable branch is the `master`
+branch, while it is the `develop` branch that includes all new features and to
+which new contributions are merged. Contributions are submitted for review and
+testing through pull requests, the `git` standard. The `develop` branch is
+regularly merged into the `master` branch once testing is concluded.
+
+The development scheme has been adopted for obvious reasons: the COBRA Toolbox
+is heavily used on a daily basis, while the development community is active.
+The key advantage of this setup is that developers can work on the next stable
+release, while users can enjoy a stable version. Developers and users are
+consequently working on the same code base without interfering. Understanding
+the concept of branches is key to submitting hassle-free pull requests and
+starting to contribute using `git`.
+
+Clone the fork and update the submodules
+----------------------------------------
+
+|warning| Please note the following:
+
+ - The following commands should only be run from the terminal (or the shell).
+ - An SSH key must be set in your Github account settings.
+
+ In order to get started, clone the forked repository:
+
+.. code:: console
+
+ $ git clone git@github.com:/cobratoolbox.git fork-cobratoolbox
+
+This will create a folder called fork-cobratoolbox. Make sure to replace
+`` with your Github username. Any of the following commands are meant
+to be run from within the folder of the fork called `fork-cobratoolbox`.
+
+.. code:: console
+
+ $ cd fork-cobratoolbox
+
+In order to complete the cloned repository with external code, it is
+recommended to clone all submodules:
+
+.. code:: console
+
+ $ git submodule update --init
+
+Configure the remotes
+---------------------
+
+Note that your fork is a copy of the `opencobra/cobratoolbox
+`__ repository and is not
+automatically updated. As such, you have to configure the address of the
+`opencobra/cobratoolbox `__
+repository:
+
+.. code:: console
+
+ $ git remote add upstream git@github.com:opencobra/cobratoolbox.git
+
+Now, there are two addresses (also called remotes) configured: `origin` and
+`upstream`. You can verify this by typing:
+
+.. code:: console
+
+ $ git remote -v
+
+In order to update your fork, run the following commands:
+
+.. code:: console
+
+ $ git fetch upstream
+
+First, update the `master` branch:
+
+.. code:: console
+
+ $ git checkout master # checkout the branch locally
+ $ git merge upstream/master # merge the changes from the upstream repository
+ $ git push origin master # push the changes to the branch of the fork
+
+Then, update the `develop` branch:
+
+.. code:: console
+
+ $ git checkout develop # checkout the branch
+ $ git merge upstream/develop # merge the changes on the branch from the upstream repository
+ $ git push origin develop # push the changes to the branch of the fork
+
+|warning| Should the step fail to checkout the develop branch, you should
+create the develop branch first based on the `develop` branch of the upstream
+repository:
+
+.. code:: console
+
+ $ git checkout -b develop upstream/develop
+
+Then, you can proceed normally.
+
+Create a contribution and submit a pull request
+-----------------------------------------------
+
+Now, as the fork is up-to-date with the upstream repository, start a new
+contribution. A new contribution must be made on a new branch, that originates
+from the `develop` branch. Create the new branch:
+
+.. code:: console
+
+ $ git checkout -b develop
+
+Now, you can make changes in the folder `fork-cobratoolbox`. Once you are done
+making changes, you can contribute the files. An important command that lists
+all changes is to retrieve the repository status:
+
+.. code:: console
+
+ $ git status
+
+A list is displayed with new, modified, and deleted files. You can add the changes (even deletions) by
+adding the file:
+
+.. code:: console
+
+ $ git add .
+
+|warning| Contrary to what is sometimes provided as a shortcut, it is not
+advised to add all files all at once using as this command will add all files,
+even hidden files and binaries.
+
+.. code:: console
+
+ $ git add . # bad practice
+
+Then, commit the changes by setting a commit message :
+
+.. code:: console
+
+ $ git commit -m ""
+
+Finally, push your commit to Github:
+
+.. code:: console
+
+ $ git push origin
+
+You should then see your commit online, and if ready, you can open a
+pull request. You can select your branch in the dropdown menu and list all
+commits by clicking on `commits`.
+
+Continue working on your branch after a while (rebase)
+------------------------------------------------------
+
+If there have been major changes or if you want to continue working on a branch
+after a while, it is recommended to do a rebase. In simple terms, rebasing your
+branch shifts your commits to the top of the branch and includes all changes
+from the upstream repository. Before doing so, make sure that you do not have
+any uncommitted or local changes (git status).
+
+.. code:: console
+
+ $ git checkout develop
+ $ git fetch upstream
+ $ git merge upstream/develop
+ $ git submodule update
+ $ git checkout
+ $ git rebase develop
+
+If you do not have any conflicts, you should see messages showing that your
+changes have been applied. If however there are conflicts, it is advised to
+use a merge tool such as `kdiff3`. In order to install a merge tool or abort
+the rebase process, type:
+
+.. code:: console
+
+ $ git rebase --abort
+
+In order to have the changes on `` reflected in the online
+repository, push the changes with force. Pushing with force is required as the
+history of the branch has been rewritten during rebase.
+
+.. code:: console
+
+ $ git push --force
+
+Selectively use a commit on your branch (cherry-pick)
+-----------------------------------------------------
+
+Imagine having two branches called `` and ``. On branch
+`` is a commit with a SHA1 that you need on ``. You can
+cherry-pick the commit from `` to `` by typing:
+
+.. code:: console
+
+ $ git checkout myBranch-2
+ $ git cherry-pick SHA1
+
+If there are no conflicts, the displayed message should contain the commit
+message and author information. In order to have the commit listed online,
+conclude the cherry-pick by pushing the commit to the remote repository:
+
+.. code:: console
+
+ $ git push myBranch-2
+
diff --git a/docs/source/troubleshooting/cobratutorials.rst b/docs/source/troubleshooting/cobratutorials.rst
new file mode 100644
index 0000000..5228e45
--- /dev/null
+++ b/docs/source/troubleshooting/cobratutorials.rst
@@ -0,0 +1,78 @@
+COBRA.tutorials
+^^^^^^^^^^^^^^^
+
+.. |warning| raw:: html
+
+
+
+|warning| This section is tailored to users who feel comfortable using
+the terminal (or shell). It is recommended for other users
+to follow :ref:`these instructions `.
+
+|warning| A Github account is required and `git` must be installed. An SSH key
+must be set as explained in :ref:`prerequisites`.
+
+Fork and checkout your branch
+-----------------------------
+
+1. Fork the `COBRA.tutorials repository `__ on Github.
+
+2. Clone the forked repository to ``fork-COBRA.tutorials`` located in a directory of your choice:
+
+ .. code-block:: console
+
+ $ git clone git@github.com:/COBRA.tutorials.git fork-COBRA.tutorials.git
+
+3. Change to the directory ``fork-COBRA.tutorials``:
+
+ .. code-block:: console
+
+ $ cd fork-COBRA.tutorials.git/
+
+4. Set the upstream to the ``opencobra/COBRA.tutorials`` repository:
+
+ .. code-block:: console
+
+ $ git remote add upstream git@github.com:opencobra/COBRA.tutorials.git
+
+5. Fetch from the upstream repository
+
+ .. code-block:: console
+
+ $ git fetch upstream
+
+6. Checkout a new branch from ``develop``:
+
+ .. code-block:: console
+
+ $ git checkout -b upstream/develop
+
+7. Now, make your changes in the tutorial in MATLAB.
+
+
+Submit your changes and open a pull request
+-------------------------------------------
+
+8. Once you are done making changes, add the files to your branch, where ``tutorial_`` is the name of the tutorial. Make sure to add the ``.m`` and the ``.mlx`` files.
+
+ .. code-block:: console
+
+ $ git add tutorial_.m
+ $ git add tutorial_.mlx
+ $ git commit -m "Changes to tutorial_"
+
+9. Push your commits on ```` to your fork:
+
+ .. code-block:: console
+
+ $ git push origin
+
+10. Browse to your fork on ``https://www.github.com//COBRA.tutorials``, where ```` is your Github username.
+
+11. Click on ``Compare & Pull Request``.
+
+12. Change the target branch ``develop``.
+
+13. Submit your pull request.
+
+14. Wait until your pull request is accepted.
diff --git a/runtests.sh b/runtests.sh
deleted file mode 100644
index 5f2dff0..0000000
--- a/runtests.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-cd ./test
-/mnt/data/MATLAB/$MATLAB_VER/bin/./matlab -nodesktop -nosplash -r "launchTests;" < inputCI.txt;
-CODE=$?
-exit $CODE
diff --git a/src/addKeyToKnownHosts.m b/src/addKeyToKnownHosts.m
new file mode 100644
index 0000000..79f0862
--- /dev/null
+++ b/src/addKeyToKnownHosts.m
@@ -0,0 +1,65 @@
+function keyAdded = addKeyToKnownHosts(callerName)
+% Checks if the public key to `site.ext` exists
+% If the public key of the `site.ext` does not exist,
+% adds the public key to the known hosts
+%
+% USAGE:
+%
+% keyAdded = addKeyToKnownHosts(callerName)
+%
+% INPUT:
+% callerName: Name of the function calling (default: empty string)
+%
+% OUTPUT:
+% keyAdded: Boolean (true if key has been added successfully or exists)
+%
+% .. Author:
+% - Laurent Heirendt
+
+ global gitCmd
+
+ % set default arguments
+ if ~exist('callerName', 'var')
+ callerName = '';
+ end
+
+ % add github.com as a known host
+ [status_keyscan, result_keyscan] = system('ssh-keyscan');
+
+ % user directory
+ if ispc
+ homeDir = getenv('userprofile');
+ else
+ homeDir = getenv('HOME');
+ end
+
+ if status_keyscan == 1 && ~isempty(strfind(result_keyscan, 'usage:'))
+
+ % try to create the directory
+ [status_createDir, ~, ~] = mkdir([homeDir filesep '.ssh']);
+
+ % touch the file first
+ system(['touch ', homeDir, filesep, '.ssh', filesep, 'known_hosts']);
+
+ % read the known hosts file
+ [~, result_grep] = system(['grep "^github.com " ', homeDir, filesep, '.ssh', filesep, 'known_hosts']);
+
+ if strcmp(result_grep, '')
+ [status_kh, result_kh] = system(['ssh-keyscan github.com >> ', homeDir, filesep, '.ssh', filesep, 'known_hosts']);
+
+ if status_kh == 0 && ~isempty(strfind(result_kh, '# github.com'))
+ printMsg(mfilename, [callerName, ' github.com has been added to the known hosts']);
+ keyAdded = true;
+ else
+ fprintf(result_kh);
+ error([gitCmd.lead, ' [', mfilename, ']', callerName, ' github.com could not be added to the known hosts file in ~/.ssh/known_hosts']);
+ end
+ else
+ printMsg(mfilename, [callerName, ' github.com is already a known host.']);
+ keyAdded = true;
+ end
+ else
+ fprintf(result_keyscan);
+ error([gitCmd.lead, ' [', mfilename, ']', callerName, ' ssh-keyscan is not installed.']);
+ end
+end
diff --git a/src/checkBranchExistence.m b/src/checkBranchExistence.m
index f779b7e..fbb53f4 100644
--- a/src/checkBranchExistence.m
+++ b/src/checkBranchExistence.m
@@ -1,8 +1,18 @@
function branchExists = checkBranchExistence(branchName)
-% devTools
+% Checks if a branch exists locally
%
-% PURPOSE: checks if a branch exists locally
+% USAGE:
%
+% branchExists = checkBranchExistence(branchName)
+%
+% INPUT:
+% branchName: Name of the local branch to be checked for existence
+%
+% OUTPUT:
+% branchExists: Boolean (true if `branchName` esists)
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
diff --git a/src/checkDevTools.m b/src/checkDevTools.m
index c7ac627..79c97e3 100644
--- a/src/checkDevTools.m
+++ b/src/checkDevTools.m
@@ -1,8 +1,12 @@
function checkDevTools()
-% devTools
+% Checks the configuration of the development tools
%
-% PURPOSE: checks the configuration of the development tools
+% USAGE:
%
+% checkDevTools()
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
diff --git a/src/checkLocalFork.m b/src/checkLocalFork.m
index caa2cbe..db636fe 100644
--- a/src/checkLocalFork.m
+++ b/src/checkLocalFork.m
@@ -1,8 +1,13 @@
function checkLocalFork()
-% devTools
+% Checks the configuration of remotes in the local copy of the fork
%
-% PURPOSE: checks the configuration of remotes in the local copy of the fork
+% USAGE:
%
+% checkLocalFork()
+%
+% .. Author:
+% - Laurent Heirendt
+
global gitConf
global gitCmd
diff --git a/src/checkRemoteBranchExistence.m b/src/checkRemoteBranchExistence.m
new file mode 100644
index 0000000..08ad916
--- /dev/null
+++ b/src/checkRemoteBranchExistence.m
@@ -0,0 +1,36 @@
+function branchExists = checkRemoteBranchExistence(branchName)
+% Checks if a branch exists locally
+%
+% USAGE:
+%
+% branchExists = checkRemoteBranchExistence(branchName)
+%
+% INPUT:
+% branchName: Name of the remote branch to be checked for existence
+%
+% OUTPUT:
+% branchExists: Boolean (true if `branchName` esists)
+%
+% .. Author:
+% - Laurent Heirendt
+
+ global gitConf
+
+ % remove .git from the remoteRepoURL
+ if strcmpi(gitConf.remoteRepoURL(end-3:end), '.git')
+ tmpRepoName = gitConf.remoteRepoURL(1:end-4);
+ else
+ tmpRepoName = gitConf.remoteRepoURL;
+ end
+
+ % retrieve a list of all the branches
+ [status_curl, result_curl] = system(['curl -s -k --head ' tmpRepoName '/tree/' branchName]);
+
+ if status_curl == 0 && ~isempty(strfind(result_curl, '200 OK'))
+ printMsg(mfilename, ['The branch <' branchName '> exists remotely.']);
+ branchExists = true;
+ else
+ printMsg(mfilename, ['The remote <' branchName '> does not exist remotely.']);
+ branchExists = false;
+ end
+end
diff --git a/src/checkRemoteFork.m b/src/checkRemoteFork.m
index 6f33c4a..3c395aa 100644
--- a/src/checkRemoteFork.m
+++ b/src/checkRemoteFork.m
@@ -1,8 +1,14 @@
function checkRemoteFork()
-% devTools
+% Checks whether the fork exists remotely
%
-% PURPOSE: checks whether the fork exists remotely
+% USAGE:
%
+% checkRemoteFork()
+%
+% .. Author:
+% - Laurent Heirendt
+
+
global gitConf
global gitCmd
diff --git a/src/checkStatus.m b/src/checkStatus.m
index 36592c0..6e728bc 100644
--- a/src/checkStatus.m
+++ b/src/checkStatus.m
@@ -1,8 +1,12 @@
function checkStatus()
-% devTools
+% Checks the status of the repository
%
-% PURPOSE: checks the status of the repository
+% USAGE:
%
+% checkStatus()
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
diff --git a/src/checkSystem.m b/src/checkSystem.m
index 85c576f..828fcc8 100644
--- a/src/checkSystem.m
+++ b/src/checkSystem.m
@@ -1,53 +1,82 @@
-function checkSystem(callerName)
-% devTools
+function checkSystem(callerName, repoName, printLevel)
+% Checks the configuration of the system (installation of git and curl)
%
-% PURPOSE: checks the configuration of the system (installation of git and curl)
+% USAGE:
%
+% checkSystem(callerName, repoName)
+%
+% INPUT:
+% callerName: Name of the function calling `checkSystem()`
+% repoName: Name of the repository for which the devTools shall
+% be configured (default: `opencobra/cobratoolbox`)
+% printLevel: Level of verbose
+%
+% .. Author:
+% - Laurent Heirendt
+
global gitConf
global gitCmd
- % if a configuration has already been set, configure the devTools accordingly
- if isempty(gitConf)
- confDevTools();
- else
- confDevTools(gitConf.launcher, gitConf.remoteRepoURL, gitConf.nickName, gitConf.verbose);
- end
-
% set the callerName
- if nargin < 1
+ if ~exist('printLevel', 'var')
callerName = '';
- verbose = true;
else
- verbose = false;
callerName = ['(caller: ', callerName, ')'];
end
- if verbose
- gitConfVerbose = gitConf.verbose;
- gitConf.verbose = true;
+ % set the repoName if not given
+ if nargin < 2 || ~exist('repoName', 'var')
+ repoName = 'opencobra/cobratoolbox';
end
- % check if git is properly installed
- [status_gitVersion, result_gitVersion] = system('git --version');
+ if ~exist('printLevel', 'var') && isempty(gitConf)
+ printLevel = 0;
+ end
- if status_gitVersion == 0 && ~isempty(strfind(result_gitVersion, 'git version'))
- printMsg(mfilename, [callerName, ' git is properly installed.']);
+ % if a configuration has already been set, configure the devTools accordingly
+ if isempty(gitConf)
+ % default configuration of the devTools is the DEFAULTREPONAME repository
+ confDevTools(repoName, 'printLevel', printLevel);
else
- fprintf(result_gitVersion);
- error([gitCmd.lead, ' [', mfilename, ']', callerName, ' git is not installed. Please follow the guidelines how to install git.']);
+ % write instructions how to reset the devTools when they already configured
+ if strcmpi(callerName, 'contribute')
+ fprintf('\n');
+ tmpPrintLevel = gitConf.printLevel;
+ gitConf.printLevel = 1;
+ printMsg(mfilename, [gitCmd.lead, ' The devTools are configured for the repository <', gitConf.nickName, '>']);
+ printMsg(mfilename, [gitCmd.lead, ' Please use >> resetDevTools() if you want to change the current configuration.']);
+ gitConf.printLevel = tmpPrintLevel;
+
+ confDevTools(gitConf.nickName, 'remoteRepoURL', gitConf.remoteRepoURL, ...
+ 'launcher', gitConf.launcher, ...
+ 'printLevel', gitConf.printLevel);
+ end
end
- % check if curl is properly installed
- [status_curl, result_curl] = system('curl --version');
+ % only check whether git and curl are installed if the gitConf object is empty
+ if isempty(gitConf)
+ % add the public key from github.com to the known hosts
+ addKeyToKnownHosts();
+
+ % check if git is properly installed
+ [status_gitVersion, result_gitVersion] = system('git --version');
- if status_curl == 0 && ~isempty(strfind(result_curl, 'curl')) && ~isempty(strfind(result_curl, 'http'))
- printMsg(mfilename, [callerName, ' curl is properly installed.']);
- else
- error([gitCmd.lead, ' [', mfilename, ']', callerName, ' curl is not installed. Please follow the guidelines how to install curl.']);
- end
+ if status_gitVersion == 0 && ~isempty(strfind(result_gitVersion, 'git version'))
+ printMsg(mfilename, [callerName, ' git is properly installed.']);
+ else
+ fprintf(result_gitVersion);
+ error([gitCmd.lead, ' [', mfilename, ']', callerName, ' git is not installed. Please follow the guidelines how to install git.']);
+ end
+
+ % check if curl is properly installed
+ [status_curl, result_curl] = system('curl --version');
- if verbose
- gitConf.verbose = gitConfVerbose;
+ if status_curl == 0 && ~isempty(strfind(result_curl, 'curl')) && ~isempty(strfind(result_curl, 'http'))
+ printMsg(mfilename, [callerName, ' curl is properly installed.']);
+ else
+ fprintf(result_curl);
+ error([gitCmd.lead, ' [', mfilename, ']', callerName, ' curl is not installed. Please follow the guidelines how to install curl.']);
+ end
end
end
diff --git a/src/checkoutBranch.m b/src/checkoutBranch.m
index 39b3de6..18cab37 100644
--- a/src/checkoutBranch.m
+++ b/src/checkoutBranch.m
@@ -1,14 +1,22 @@
-function checkoutBranch(branchName, update_fork)
-% devTools
+function checkoutBranch(branchName, updateForkFlag)
+% checks out a branch named locally and remotely
%
-% PURPOSE: checks out a branch named locally and remotely
+% USAGE:
%
+% checkoutBranch(branchName, updateForkFlag)
+%
+% INPUT:
+% branchName: Name of the local branch to be checked out
+% updateForkFlag: Boolean to update the fork before checking out the branch
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
if nargin < 2
- update_fork = true;
+ updateForkFlag = true;
end
% save the currentDir
@@ -31,50 +39,57 @@ function checkoutBranch(branchName, update_fork)
% retrieve the status
[status_gitStatus, result_gitStatus] = system('git status -s');
- if status_gitBranch == 0 && ~strcmpi('develop', currentBranch) && isempty(result_gitStatus) && status_gitStatus == 0
+ % check if the develop branch exists remotely
+ if checkRemoteBranchExistence('develop')
+ mainBranch = 'develop';
+ else
+ mainBranch = 'master'; % fall back to master, which always exists
+ end
+
+ if status_gitBranch == 0 && ~strcmpi(mainBranch, currentBranch) && isempty(result_gitStatus) && status_gitStatus == 0
- printMsg(mfilename, ['The current feature (branch) ', currentBranch, ' is not the feature (branch).'], [gitCmd.fail, gitCmd.trail]);
+ printMsg(mfilename, ['The current feature (branch) ', currentBranch, ' is not the <' mainBranch '> feature (branch).'], [gitCmd.fail, gitCmd.trail]);
% update the fork locally
- if update_fork
+ if updateForkFlag
updateFork(true);
end
% checkout the develop branch (after update of the fork)
- [status_gitCheckout, result_gitCheckout] = system('git checkout develop');
+ [status_gitCheckout, result_gitCheckout] = system(['git checkout ' mainBranch]);
% retrieve the name of the current branch
currentBranch = getCurrentBranchName();
- if status_gitCheckout == 0 && strcmpi('develop', currentBranch)
- printMsg(mfilename, 'The current feature (branch) is .');
+ if status_gitCheckout == 0 && strcmpi(mainBranch, currentBranch)
+ printMsg(mfilename, ['The current feature (branch) is <' mainBranch '>.']);
else
fprintf(result_gitCheckout);
- error([gitCmd.lead, 'An error occurred and the feature (branch) cannot be checked out']);
+ error([gitCmd.lead, 'An error occurred and the <' mainBranch '> feature (branch) cannot be checked out']);
end
% reset the develop branch
- [status_gitReset, result_gitReset] = system('git reset --hard upstream/develop');
+ [status_gitReset, result_gitReset] = system(['git reset --hard upstream/' mainBranch]);
if status_gitReset == 0
- if gitConf.verbose
- fprintf([gitCmd.lead, ' [', mfilename, '] The current feature (branch) is .', gitCmd.success, gitCmd.trail]);
+ if gitConf.printLevel > 0
+ fprintf([gitCmd.lead, ' [', mfilename, '] The current feature (branch) is <' mainBranch '>.', gitCmd.success, gitCmd.trail]);
end
else
fprintf(result_gitReset);
- error([gitCmd.lead, 'The feature (branch) cannot be checked out']);
+ error([gitCmd.lead, 'The <' mainBranch '> feature (branch) cannot be checked out']);
end
% update all submodules
updateSubmodules();
% make sure that the develop branch is up to date
- [status_gitPull, result_gitPull] = system('git pull origin develop');
+ [status_gitPull, result_gitPull] = system(['git pull origin ' mainBranch]);
if status_gitPull == 0
- printMsg(mfilename, 'The changes on the feature (branch) of your fork have been pulled.');
+ printMsg(mfilename, ['The changes on the <' mainBranch '> feature (branch) of your fork have been pulled.']);
else
fprintf(result_gitPull);
- error([gitCmd.lead, 'The changes on the feature (branch) could not be pulled.', gitCmd.fail]);
+ error([gitCmd.lead, 'The changes on the <' mainBranch '> feature (branch) could not be pulled.', gitCmd.fail]);
end
end
@@ -87,7 +102,7 @@ function checkoutBranch(branchName, update_fork)
% retrieve the status
[status_gitStatus, result_gitStatus] = system('git status -s');
- if (status_gitStatus == 0 && isempty(result_gitStatus)) || ~update_fork
+ if (status_gitStatus == 0 && isempty(result_gitStatus)) || ~updateForkFlag
% properly checkout the branch
[status_gitCheckout, result_gitCheckout] = system(['git checkout ', checkoutFlag, ' ', branchName]);
@@ -102,11 +117,11 @@ function checkoutBranch(branchName, update_fork)
if status_gitStatus == 0 && isempty(result_gitStatus)
% perform a rebase
- [status_gitRebase, result_gitRebase] = system('git rebase develop');
+ [status_gitRebase, result_gitRebase] = system(['git rebase ' mainBranch]);
% if the message after rebase does not contain up to data and not cannot rebase
if status_gitRebase == 0 && isempty(strfind(result_gitRebase, 'up to date')) && isempty(strfind(result_gitRebase, 'Cannot rebase'))
- printMsg(mfilename, ['The <', branchName, '> feature (branch) has been rebased with .']);
+ printMsg(mfilename, ['The <', branchName, '> feature (branch) has been rebased with <' mainBranch '>.']);
% push by force the rebased branch
[status_gitPush, result_gitPush] = system(['git push origin ', branchName, ' --force']);
@@ -120,7 +135,7 @@ function checkoutBranch(branchName, update_fork)
[status_gitRebaseAbort, ~] = system('git rebase --abort');
if status_gitRebaseAbort == 0
- printMsg(mfilename, ['The rebase process of <', branchName,'> with has been aborted.'], [gitCmd.fail, gitCmd.trail]);
+ printMsg(mfilename, ['The rebase process of <', branchName, '> with <' mainBranch '> has been aborted.'], [gitCmd.fail, gitCmd.trail]);
end
% if the message after rebase contains : cannot rebase
@@ -129,13 +144,14 @@ function checkoutBranch(branchName, update_fork)
reply = input([gitCmd.lead, ' -> Do you want to reset your feature (branch) <', branchName, '>. Y/N [N]: '], 's');
if ~isempty(reply) || strcmpi(reply, 'y') || strcmpi(reply, 'yes')
- [status_curl, result_curl] = system(['curl -s -k --head ', gitConf.remoteServerName, gitConf.userName, '/', gitConf.remoteRepoName, '/tree/', branchName]);
- if status_curl == 0 && ~isempty(strfind(result_curl, '200 OK'))
+ branchNameExistsRemotely = checkRemoteBranchExistence(branchName);
+
+ if branchNameExistsRemotely
% hard reset of an existing branch
[status_gitReset, result_gitReset] = system(['git reset --hard origin/', branchName]);
if status_gitReset == 0
- printMsg(mfilename, ['The <', branchName, '> feature (branch) has not been rebased with and is up to date.']);
+ printMsg(mfilename, ['The <', branchName, '> feature (branch) has not been rebased with <' mainBranch '> and is up to date.']);
else
fprintf(result_gitReset);
error([gitCmd.lead, ' [', mfilename, '] The <', branchName, '> could not be reset.', gitCmd.fail]);
@@ -161,45 +177,45 @@ function checkoutBranch(branchName, update_fork)
end
end
else
- if gitConf.verbose
+ if gitConf.printLevel > 0
fprintf(result_gitCheckout);
fprintf([gitCmd.lead, ' [', mfilename, '] The feature (branch) <', branchName, '> could not be checked out.', gitCmd.fail, gitCmd.trail]);
end
end
else
- if gitConf.verbose && ~strcmp(branchName, currentBranch)
+ if gitConf.printLevel > 0 && ~strcmp(branchName, currentBranch)
fprintf(result_gitStatus);
fprintf([gitCmd.lead, ' [', mfilename, '] Uncommited changes of the current feature (branch) <', currentBranch, '> have been migrated to the new feature <', branchName, '>.', gitCmd.success, gitCmd.trail]);
end
if ~strcmp(branchName, currentBranch)
% checkout the develop branch (soft checkout without merg)
- [status_gitCheckout, result_gitCheckout] = system('git checkout develop');
+ [status_gitCheckout, result_gitCheckout] = system(['git checkout ' mainBranch]);
% retrieve the name of the current branch
currentBranch = getCurrentBranchName();
- if status_gitCheckout == 0 && strcmpi('develop', currentBranch)
- printMsg(mfilename, 'The current feature (branch) is .');
+ if status_gitCheckout == 0 && strcmpi(mainBranch, currentBranch)
+ printMsg(mfilename, ['The current feature (branch) is <' mainBranch '>.']);
% update all submodules
updateSubmodules();
% make sure that the develop branch is up to date
- [status_gitPull, result_gitPull] = system('git pull origin develop');
+ [status_gitPull, result_gitPull] = system(['git pull origin ' mainBranch]);
if status_gitPull == 0
- printMsg(mfilename, 'The changes on the feature (branch) of your fork have been pulled.');
+ printMsg(mfilename, ['The changes on the <' mainBranch '> feature (branch) of your fork have been pulled.']);
else
fprintf(result_gitPull);
- error([gitCmd.lead, 'The changes on the feature (branch) could not be pulled.', gitCmd.fail]);
+ error([gitCmd.lead, 'The changes on the <' mainBranch '> feature (branch) could not be pulled.', gitCmd.fail]);
end
% checkout the branch but do not update the fork
checkoutBranch(branchName, false);
else
fprintf(result_gitCheckout);
- fprintf([gitCmd.lead, 'The feature (branch) cannot be checked out']);
+ fprintf([gitCmd.lead 'The <' mainBranch '> feature (branch) cannot be checked out']);
end
end
end
@@ -207,11 +223,12 @@ function checkoutBranch(branchName, update_fork)
% check the system
checkSystem(mfilename);
- % if a branch does not exist remotely but exists locally, push it after confirmation from the user
- [status_curl, result_curl] = system(['curl -s -k --head ', gitConf.remoteServerName, gitConf.userName, '/', gitConf.remoteRepoName, '/tree/', branchName]);
+ % check of the branch exists locally and remotely
+ branchExistsLocally = checkBranchExistence(branchName);
+ branchExistsRemotely = checkRemoteBranchExistence(branchName);
% check if the branch exists remotely
- if status_curl == 0 && ~isempty(strfind(result_curl, '200 OK')) && checkBranchExistence(branchName)
+ if branchExistsRemotely && branchExistsLocally
printMsg(mfilename, ['The <', branchName, '> feature (branch) exists locally and remotely on <', gitConf.forkURL, '>.']);
else % the branch exists locally but not remotely!
diff --git a/src/cloneFork.m b/src/cloneFork.m
index 4f5cda0..4897e35 100644
--- a/src/cloneFork.m
+++ b/src/cloneFork.m
@@ -1,8 +1,16 @@
function freshClone = cloneFork()
-% devTools
+% Clone the fork and update the submodules of the repository
%
-% PURPOSE: clones the fork and updates the submodules of the repository
+% USAGE:
%
+% freshClone = cloneFork()
+%
+% OUTPUT:
+% freshClone: Boolean (`true` if a new clone has been made)
+%
+% .. Author:
+% - Laurent Heirendt
+
global gitConf
global gitCmd
diff --git a/src/confDevTools.m b/src/confDevTools.m
new file mode 100644
index 0000000..dd7811f
--- /dev/null
+++ b/src/confDevTools.m
@@ -0,0 +1,107 @@
+function confDevTools(repoName, varargin)
+% Configure the devTools by defining the `gitConf` object
+%
+% USAGE:
+%
+% confDevTools(repoName, remoteRepoURL, varargin)
+%
+% INPUTS:
+% repoName: Name of the repository (default: `'cobratoolbox'`)
+%
+% OPTIONAL INPUTS:
+% remoteRepoURL: URL of the repository
+% launcher: String with a header to be displayed when starting
+% nickName: Short name of the repository
+% printLevel: Verbose level (default: 1)
+%
+% Note:
+% Currently, only 2 projects are defined:
+% `The COBRA Toolbox `__
+% and `COBRA.tutorials `__
+%
+% .. Author:
+% - Laurent Heirendt, January 2018
+%
+
+ global gitConf
+ global gitCmd
+
+ % define default values
+ defaultPrintLevel = 0;
+
+ % setup the parser
+ parser = inputParser();
+ parser.addRequired('repoName', @ischar);
+ parser.addParamValue('remoteRepoURL', ['https://github.com/' repoName '.git'], @ischar);
+
+ % set the defaultLauncher
+ if strcmpi(repoName, 'opencobra/cobratoolbox')
+ c = clock;
+ defaultLauncher = ['\n\n _____ _____ _____ _____ _____ |\n / ___| / _ \\ | _ \\ | _ \\ / ___ \\ | COnstraint-Based Reconstruction and Analysis\n | | | | | | | |_| | | |_| | | |___| | | The COBRA Toolbox - ', num2str(c(1)) , '\n | | | | | | | _ { | _ / | ___ | |\n | |___ | |_| | | |_| | | | \\ \\ | | | | | Documentation:\n \\_____| \\_____/ |_____/ |_| \\_\\ |_| |_| | http://opencobra.github.io/cobratoolbox\n | \n\n'];
+ defaultNickName = 'cobratoolbox';
+ elseif strcmpi(repoName, 'opencobra/COBRA.tutorials')
+ defaultLauncher = '\n\n ~~~ COBRA.tutorials ~~~\n\n';
+ defaultNickName = 'COBRA.tutorials';
+ else
+ defaultLauncher = ['\n\n ~~~ ' repoName ' ~~~\n\n'];
+ defaultNickName = repoName;
+ end
+ parser.addParamValue('launcher', defaultLauncher, @ischar);
+ parser.addParamValue('nickName', defaultNickName, @ischar);
+ parser.addParamValue('printLevel', defaultPrintLevel, @(x) isnumeric(x));
+
+ % parse the input arguments
+ if ~isempty(varargin)
+ parser.parse(repoName, varargin{:});
+ else
+ parser.parse(repoName);
+ end
+
+ % retrieve the variables
+ repoName = parser.Results.repoName;
+ remoteRepoURL = parser.Results.remoteRepoURL;
+ printLevel = parser.Results.printLevel;
+
+ % strip the .git at the end
+ tmpRemoteRepoURL = remoteRepoURL(1:end-4);
+
+ % check if the remoteRepoURL exists before proceeding
+ [status_curl, result_curl] = system(['curl -s -k --head ', tmpRemoteRepoURL]);
+ if ~(status_curl == 0 && ~isempty(strfind(result_curl, '200 OK')))
+ error([' [', mfilename, '] The URL (' remoteRepoURL ') is not reachable or does not exist.']);
+ end
+
+ % set the default nickName
+ urlSplit = strsplit(remoteRepoURL, '/');
+ tmpNickName = strsplit(urlSplit{end}, '.git');
+ nickName = tmpNickName{1};
+
+ % define the configuration of other projects here
+ if printLevel > 0
+ fprintf([' -- Assuming the default configuration (', nickName, ' repository)\n']);
+ end
+
+ % definition of parameters
+ gitConf.leadForkDirName = 'fork-';
+ gitConf.exampleBranch = 'add-constraints';
+
+ % define the printLevel
+ gitConf.printLevel = printLevel;
+ gitConf.launcher = parser.Results.launcher;
+ gitConf.remoteRepoURL = remoteRepoURL;
+ gitConf.nickName = nickName;
+
+ % define the URL of the devTools
+ gitConf.devToolsURL_SSH = 'git@github.com:opencobra/MATLAB.devTools.git';
+ gitConf.devToolsURL_HTTPS = 'https://github.com/opencobra/MATLAB.devTools.git';
+ gitConf.devTools_name = 'MATLAB.devTools';
+
+ % definition of commands
+ gitCmd.lead = 'dev> ';
+ gitCmd.success = ' (Success) ';
+ gitCmd.fail = ' (Error) ';
+ gitCmd.trail = '\n';
+
+ % print out a success message
+ printMsg(mfilename, [' The devTools have been configured (', nickName, ').']);
+end
diff --git a/src/configureFork.m b/src/configureFork.m
index 3eae67b..2071f95 100644
--- a/src/configureFork.m
+++ b/src/configureFork.m
@@ -1,8 +1,12 @@
function configureFork()
-% devTools
+% Configures the remotes of the local fork (upstream)
%
-% PURPOSE: configures the remotes of the local fork (upstream)
+% USAGE:
%
+% configureFork()
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
diff --git a/src/deleteContribution.m b/src/deleteContribution.m
index bd18996..f60c390 100644
--- a/src/deleteContribution.m
+++ b/src/deleteContribution.m
@@ -1,8 +1,15 @@
function deleteContribution(branchName)
-% devTools
+% Delete an existing feature (branch) named `branchName`
%
-% PURPOSE: deletes and existing feature (branch) named
+% USAGE:
%
+% deleteContribution(branchName)
+%
+% INPUT:
+% branchName: Name of the local branch to be deleted
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
@@ -10,67 +17,76 @@ function deleteContribution(branchName)
% change the directory to the local directory of the fork
cd(gitConf.fullForkDir);
- if gitConf.verbose
+ if gitConf.printLevel > 0
originCall = [' [', mfilename, '] '];
else
originCall = '';
end
if isempty(strfind(branchName, 'develop')) && isempty(strfind(branchName, 'master'))
- reply = input([gitCmd.lead, originCall, 'Are you sure that you want to delete the feature (branch) <', branchName, '>? YES/NO [NO]: '], 's');
+ reply = '';
- if ~isempty(reply) && strcmpi(reply, 'yes') % users MUST enter 'yes', not only 'y'
+ while isempty(reply) || ~strcmpi(reply, 'yes')
- % checkout the develop branch
- checkoutBranch('develop');
+ reply = input([gitCmd.lead, originCall, 'Are you sure that you want to delete the feature (branch) <', branchName, '>? YES/NO [NO]: '], 's');
- % retrieve a list of all the branches
- if ispc
- filterColor = '';
- else
- filterColor = '| tr -s "[:cntrl:]" "\n"';
- end
+ if strcmpi(reply, 'yes') % users MUST enter 'yes', not only 'y'
+
+ % check if the develop branch exists remotely
+ if checkRemoteBranchExistence('develop')
+ mainBranch = 'develop';
+ else
+ mainBranch = 'master'; % fall back to master, which always exists
+ end
+
+ % checkout the develop branch
+ checkoutBranch(mainBranch);
- [status_gitBranch, resultList] = system(['git branch --list ', filterColor]);
+ % retrieve a list of all the branches
+ if ispc
+ filterColor = '';
+ else
+ filterColor = '| tr -s "[:cntrl:]" "\n"';
+ end
- % delete the local branch
- if status_gitBranch == 0
- arrResult = strsplit(resultList, '\n');
- arrResult(~cellfun(@isempty, arrResult));
+ [status_gitBranch, resultList] = system(['git branch --list ', filterColor]);
- if checkBranchExistence(branchName)
- % delete the branch locally
- [status_gitBranchDelete, result_gitBranchDelete] = system(['git branch -D ', branchName]);
+ % delete the local branch
+ if status_gitBranch == 0
+ arrResult = strsplit(resultList, '\n');
+ arrResult(~cellfun(@isempty, arrResult));
- if status_gitBranchDelete == 0
- fprintf([gitCmd.lead, originCall, 'The local <', branchName, '> feature (branch) has been deleted.', gitCmd.success, gitCmd.trail]);
+ if checkBranchExistence(branchName)
+ % delete the branch locally
+ [status_gitBranchDelete, result_gitBranchDelete] = system(['git branch -D ', branchName]);
+
+ if status_gitBranchDelete == 0
+ fprintf([gitCmd.lead, originCall, 'The local <', branchName, '> feature (branch) has been deleted.', gitCmd.success, gitCmd.trail]);
+ else
+ fprintf(result_gitBranchDelete);
+ error([gitCmd.lead, ' [', mfilename,'] The local <', branchName,'> feature (branch) could not be deleted. You might have unpublished/uncommitted changes.', gitCmd.fail]);
+ end
else
- fprintf(result_gitBranchDelete);
- error([gitCmd.lead, ' [', mfilename,'] The local <', branchName,'> feature (branch) could not be deleted. You might have unpublished/uncommitted changes.', gitCmd.fail]);
+ fprintf([gitCmd.lead, originCall, 'The local <', branchName,'> feature (branch) does not exist.', gitCmd.fail, gitCmd.trail]);
end
else
- fprintf([gitCmd.lead, originCall, 'The local <', branchName,'> feature (branch) does not exist.', gitCmd.fail, gitCmd.trail]);
+ error([gitCmd.lead, ' [', mfilename,'] The list of features (branches) could not be retrieved.', gitCmd.fail]);
end
- else
- error([gitCmd.lead, ' [', mfilename,'] The list of features (branches) could not be retrieved.', gitCmd.fail]);
- end
- % check if branch exists remotely
- [status_curl, result_curl] = system(['curl -s -k --head ', gitConf.remoteServerName, gitConf.userName, '/', gitConf.remoteRepoName, '/tree/', branchName]);
+ % delete the remote branch
+ if checkRemoteBranchExistence(branchName)
- % delete the remote branch
- if status_curl == 0 && ~isempty(strfind(result_curl, '200 OK'))
+ [status_gitPush, result_gitPush] = system(['git push origin --delete ', branchName]);
- [status_gitPush, result_gitPush] = system(['git push origin --delete ', branchName]);
-
- if status_gitPush == 0
- fprintf([gitCmd.lead, originCall, 'The remote <', branchName, '> feature (branch) has been deleted.', gitCmd.success, gitCmd.trail]);
+ if status_gitPush == 0
+ fprintf([gitCmd.lead, originCall, 'The remote <', branchName, '> feature (branch) has been deleted.', gitCmd.success, gitCmd.trail]);
+ else
+ fprintf(result_gitPush);
+ error([gitCmd.lead, ' [', mfilename,'] The remote <', branchName,'> feature (branch) could not be deleted.', gitCmd.fail]);
+ end
else
- fprintf(result_gitPush);
- error([gitCmd.lead, ' [', mfilename,'] The remote <', branchName,'> feature (branch) could not be deleted.', gitCmd.fail]);
+ fprintf([gitCmd.lead, originCall, 'The remote <', branchName,'> feature (branch) does not exist.', gitCmd.fail, gitCmd.trail]);
end
- else
- fprintf([gitCmd.lead, originCall, 'The remote <', branchName,'> feature (branch) does not exist.', gitCmd.fail, gitCmd.trail]);
end
end
else
diff --git a/src/getCurrentBranchName.m b/src/getCurrentBranchName.m
index a0f5bf0..39023ec 100644
--- a/src/getCurrentBranchName.m
+++ b/src/getCurrentBranchName.m
@@ -1,8 +1,17 @@
function currentBranch = getCurrentBranchName()
-% devTools
+% Retrieve the name of the current branch
%
-% PURPOSE: retrieve the name of the current branch
+% USAGE:
%
+% currentBranch = getCurrentBranchName()
+%
+% OUTPUT:
+% currentBranch: Name of the current branch
+%
+% .. Author:
+% - Laurent Heirendt
+
+
global gitConf
global gitCmd
diff --git a/src/history.m b/src/history.m
index 4cbc936..e64e723 100644
--- a/src/history.m
+++ b/src/history.m
@@ -1,8 +1,17 @@
function history(fileName)
-% devTools
+% Displays the history of a file
%
-% PURPOSE: displays the history of a file
+% USAGE:
%
+% history(fileName)
+%
+% INPUT:
+% fileName: Name of the file for which the history shall be displayed
+%
+% .. Author:
+% - Laurent Heirendt
+
+
global gitConf
fullPath = which(fileName);
diff --git a/src/initContribution.m b/src/initContribution.m
index f54a276..3c009a7 100644
--- a/src/initContribution.m
+++ b/src/initContribution.m
@@ -1,8 +1,15 @@
function initContribution(branchName)
-% devTools
+% Initializes a new feature (branch) named `branchName`
%
-% PURPOSE: initializes a new feature (branch) named
+% USAGE:
%
+% initContribution(branchName)
+%
+% INPUT:
+% branchName: Name of the local branch to be initialized
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
@@ -10,7 +17,7 @@ function initContribution(branchName)
% initialize the development tools
initDevTools();
- if gitConf.verbose
+ if gitConf.printLevel > 0
originCall = [' [', mfilename, '] '];
else
originCall = '';
@@ -27,8 +34,10 @@ function initContribution(branchName)
if ~isempty(strfind(branchName, 'develop')) || ~isempty(strfind(branchName, 'master'))
branchName = '';
fprintf([gitCmd.lead, ' -> Please use a different name that does not contain or .', gitCmd.fail, gitCmd.trail]);
- else
+ elseif ~isempty(branchName)
checkoutFlag = true;
+ else
+ branchName = '';
end
end
end
diff --git a/src/initDevTools.m b/src/initDevTools.m
index 8fc14d0..03f8a22 100644
--- a/src/initDevTools.m
+++ b/src/initDevTools.m
@@ -1,14 +1,32 @@
-function initDevTools()
-% devTools
+function initDevTools(repoName)
+% Initializes the development tools (username and email are requested if not configured)
%
-% PURPOSE: initializes the development tools (username and email are requested if not configured)
+% USAGE:
%
+% initDevTools(repoName)
+%
+% INPUT:
+% repoName: Name of the repository for which the devTools shall
+% be configured (default: `opencobra/cobratoolbox`)
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
+ global resetDevToolsFlag
+ global DEFAULTREPONAME
+
+ % set the repoName if not given
+ if ~exist('repoName', 'var')
+ repoName = DEFAULTREPONAME;
+ end
+
+ resetDevToolsFlag = true;
+
+ finishup = onCleanup(@() resetDevTools());
% check the system and set the configuration
- checkSystem(mfilename);
+ checkSystem(mfilename, repoName);
if ~isfield(gitConf, 'userName'), gitConf.userName = []; end
if ~isfield(gitConf, 'localDir'), gitConf.localDir = []; end
@@ -19,10 +37,14 @@ function initDevTools()
gitConf.remoteRepoName = gitConf.remoteRepoURL(sepIndices(4)+1:end-4);
gitConf.remoteUserName = gitConf.remoteRepoURL(sepIndices(3)+1:sepIndices(4)-1);
+ % ignore case for the current fork (avoids problems for untracked files with case conflicts)
+ [status_gitIgnoreCase, result_gitIgnoreCase] = system('git config core.ignorecase true');
+
+ % retrieve the user name
[status_gitConfUserGet, result_gitConfUserGet] = system('git config --get user.github-username');
gitConf.userName = strtrim(result_gitConfUserGet);
- if gitConf.verbose
+ if gitConf.printLevel > 0
originCall = [' [', mfilename, '] '];
else
originCall = '';
@@ -69,17 +91,26 @@ function initDevTools()
end
end
+ % define the name of the local fork directory
+ gitConf.forkDirName = strrep([gitConf.leadForkDirName, gitConf.remoteRepoName], '\', '\\');
+
+ % retrieve the directory of the fork from the local git configuration
+ [~, result_gitConfForkDirGet] = system(['git config --get user.', gitConf.leadForkDirName, gitConf.nickName, '.path']);
+ gitConf.fullForkDir = strtrim(result_gitConfForkDirGet);
+ gitConf.localDir = gitConf.fullForkDir;
+
% check if the fork exists remotely
checkRemoteFork();
- % request the local directory
- if isempty(gitConf.localDir)
+ % request the local directory if the fullForkDir is not yet known
+ if isempty(gitConf.localDir) && isempty(gitConf.fullForkDir)
createDir = false;
while ~createDir
- reply = input([gitCmd.lead, originCall, ' -> Please define the local path to your fork\n current: ', strrep(pwd,'\','\\'),'\n Enter the path (press ENTER to use the current path): '], 's');
+ reply = input([gitCmd.lead, originCall, ' -> Please define the location of your fork\n current: ', strrep(pwd,'\','\\'),'\n Enter the path (press ENTER to use the current path): '], 's');
+ % define the local directory as the current directory if the reply is empty
if isempty(reply)
gitConf.localDir = strrep(pwd, '\', '\\');
else
@@ -91,21 +122,30 @@ function initDevTools()
gitConf.localDir = strrep([gitConf.localDir, filesep], '\', '\\');
end
- % warn the user of not using a fork-cobratoolbox or cobratoolbox directory as it will be cloned
- if ~isempty(strfind(gitConf.localDir, gitConf.nickName)) || exist([gitConf.localDir, '/.git'], 'dir') == 7 % contains the nickname or a .git folder
- reply = input([gitCmd.trail, gitCmd.lead, originCall, ' -> The specified directory already contains a ', gitConf.nickName, ' copy (clone) or is a git directory.', ...
- gitCmd.trail, gitCmd.lead, originCall, ' -> Please provide the directory into which your fork should be cloned. Do you want to continue? Y/N [Y]:'], 's');
-
- if isempty(reply) || strcmpi(reply, 'y') || strcmpi(reply, 'yes')
- createDir = true;
- else
- createDir = false;
+ % strip the fork-nickName folder from the localDir if present
+ if ~isempty(gitConf.localDir) && length(gitConf.forkDirName) <= length(gitConf.localDir)
+ if strcmp(gitConf.localDir(end-length(gitConf.forkDirName)+1:end), gitConf.forkDirName)
+ gitConf.localDir = gitConf.localDir(1:end-length(gitConf.forkDirName));
end
+ end
+
+ % warn the user of not using a fork-nickName directory or a git cloned directory as it will be cloned
+ if ~isempty(strfind(gitConf.localDir, gitConf.nickName)) % contains the nickname
+ printMsg(mfilename, ['The specified directory already contains a ', gitConf.nickName, ' copy (clone).'], gitCmd.trail);
+ createDir = true;
+ gitConf.localDir = gitConf.localDir(1:end-length(gitConf.nickName)-1-length(gitConf.leadForkDirName));
+
+ elseif exist([gitConf.localDir, '/.git'], 'dir') == 7 % contains a .git folder
+ printMsg(mfilename, ['The specified directory already is a git repository (git-tracked).'], gitCmd.trail);
+
else
createDir = true;
end
end
+ % define the fork directory name
+ gitConf.fullForkDir = strrep([gitConf.localDir, gitConf.forkDirName], '\', '\\');
+
if exist(gitConf.localDir, 'dir') ~= 7
reply = input([gitCmd.lead, originCall, ' -> The specified directory (', gitConf.localDir, ') does not exist. Do you want to create it? Y/N [Y]:'], 's');
@@ -119,9 +159,16 @@ function initDevTools()
end
end
- % define the fork directory name
- gitConf.forkDirName = strrep([gitConf.leadForkDirName, gitConf.remoteRepoName], '\', '\\');
- gitConf.fullForkDir = strrep([gitConf.localDir, gitConf.forkDirName], '\', '\\');
+ resetDevToolsFlag = false;
+
+ % permanently store the fork directory in the git configuration (ask the user explicitly)
+ [status_gitConfForkDirSet, result_gitConfForkDirSet] = system(['git config --global user.', gitConf.leadForkDirName, gitConf.nickName, '.path "', gitConf.fullForkDir, '"']);
+ if status_gitConfForkDirSet == 0
+ fprintf([gitCmd.lead, originCall, 'Your fork directory has been set to: ', gitConf.fullForkDir, '. ', gitCmd.success, gitCmd.trail]);
+ else
+ fprintf(result_gitConfForkDirSet);
+ error([gitCmd.lead, ' [', mfilename,'] Your fork directory could not be set.', gitCmd.fail]);
+ end
% clone the fork
freshClone = cloneFork();
@@ -149,7 +196,9 @@ function initDevTools()
% print the current configuration
fprintf([gitCmd.lead, originCall, ' -- Configuration -------- ', gitCmd.trail])
fprintf([gitCmd.lead, originCall, ' GitHub username: ', gitConf.userName, gitCmd.trail]);
+ fprintf([gitCmd.lead, originCall, ' GitHub email: ', gitConf.userEmail, gitCmd.trail]);
fprintf([gitCmd.lead, originCall, ' Local directory : ', gitConf.fullForkDir, gitCmd.trail])
fprintf([gitCmd.lead, originCall, ' Remote fork URL: ', gitConf.forkURL, gitCmd.trail]);
fprintf([gitCmd.lead, originCall, ' Remote repository URL: ', gitConf.remoteRepoURL, gitCmd.trail]);
+
end
diff --git a/src/listFeatures.m b/src/listFeatures.m
index 64b1a85..dca884f 100644
--- a/src/listFeatures.m
+++ b/src/listFeatures.m
@@ -1,8 +1,20 @@
function [exitFlag, currentBranch, arrResult, exampleBranch] = listFeatures()
-% devTools
+% Lists all available branches/features
%
-% PURPOSE: lists all available branches/features
+% USAGE:
%
+% [exitFlag, currentBranch, arrResult, exampleBranch] = listFeatures()
+%
+% OUTPUT:
+% exitFlag: Boolean (true if proper exit of function)
+% currentBranch: Name of current branch
+% arrResult: Cell with all names of branches
+% exampleBranch: Name of a branch given as an example
+%
+% .. Author:
+% - Laurent Heirendt
+
+
global gitConf
@@ -24,12 +36,19 @@
% give an example name
exampleBranch = gitConf.exampleBranch;
+ % check if the develop branch exists remotely
+ if checkRemoteBranchExistence('develop')
+ nbBranches = 3;
+ else
+ nbBranches = 2;
+ end
+
if status == 0
arrResult = regexp(result,'\s+','split'); %strsplit is not compatible with older versions of MATLAB
arrResult = strtrim(arrResult);
arrResult = arrResult(~cellfun(@isempty, arrResult));
- if length(arrResult) > 2
+ if length(arrResult) > nbBranches
fprintf('\n Available features are:\n');
% list the number of available features
@@ -46,15 +65,22 @@
fprintf('\n');
else
- reply = input(' -> You do not have any features (branches). Do you want to start a new feature (branch)? Y/N [Y]: ', 's');
-
- % decide whether to start a new feature (branch) or not
- if ~isempty(reply) && (strcmpi(reply, 'y') || strcmpi(reply, 'yes'))
- initContribution;
- exitFlag = true;
- else
- fprintf(' -> Please start again. Goodbye.\n')
- exitFlag = true;
+ reply = '';
+ while isempty(reply)
+
+ reply = input(' -> You do not have any features (branches). Do you want to start a new feature (branch)? Y/N [Y]: ', 's');
+
+ % decide whether to start a new feature (branch) or not
+ if strcmpi(reply, 'y') || strcmpi(reply, 'yes')
+ initContribution;
+ exitFlag = true;
+ break;
+ elseif strcmpi(reply, 'n') || strcmpi(reply, 'no')
+ fprintf(' -> Please start again. Goodbye.\n')
+ exitFlag = true;
+ else
+ reply = '';
+ end
end
end
end
diff --git a/src/openPR.m b/src/openPR.m
index d71381b..cb6111a 100644
--- a/src/openPR.m
+++ b/src/openPR.m
@@ -1,8 +1,15 @@
function openPR(branchName)
-% devTools
+% Provides a pull request URL from to on the upstream
%
-% PURPOSE: provides a pull request URL from to on the upstream
+% USAGE:
%
+% openPR(branchName)
+%
+% INPUT:
+% branchName: Name of the branch for which a pull request (PR) shall be opened
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
@@ -10,14 +17,21 @@ function openPR(branchName)
% change the directory to the local directory of the fork
cd(gitConf.fullForkDir);
- if gitConf.verbose
+ if gitConf.printLevel > 0
originCall = [' [', mfilename, '] '];
else
originCall = '';
end
+ % check if the develop branch exists remotely
+ if checkRemoteBranchExistence('develop')
+ mainBranch = 'develop';
+ else
+ mainBranch = 'master'; % fall back to master, which always exists
+ end
+
% define the URL of the pull request
- prURL = [gitConf.remoteRepoURL(1:end-4), '/compare/develop...', gitConf.userName, ':', branchName];
+ prURL = [gitConf.remoteRepoURL(1:end-4), '/compare/' mainBranch '...', gitConf.userName, ':', branchName];
% check if this URL exists
[status_curl, result_curl] = system(['curl -s -k --head ', prURL]);
diff --git a/src/printMsg.m b/src/printMsg.m
index 8e790a1..fa02796 100644
--- a/src/printMsg.m
+++ b/src/printMsg.m
@@ -1,17 +1,31 @@
function printMsg(fileName, msg, endMsg)
-% devTools
+% Print a message
%
-% PURPOSE: print a message
+% USAGE:
%
+% printMsg(fileName, msg, endMsg)
+%
+% INPUT:
+% fileName: Name of the file from which the message is issued
+% msg: Message as string
+% endMsg: End of message, generally a new line character
+%
+% .. Author:
global gitConf
global gitCmd
- if nargin < 3
- endMsg = [gitCmd.success, gitCmd.trail];
- end
+ % define the message
+ if ~isempty(gitConf) && ~isempty(gitCmd)
+ % define the end of the message
+ if nargin < 3
+ endMsg = [gitCmd.success, gitCmd.trail];
+ end
- if gitConf.verbose
- fprintf([gitCmd.lead, ' [', fileName, '] ', msg, endMsg]);
+ if gitConf.printLevel > 0
+ fprintf([gitCmd.lead, ' [', fileName, '] ', msg, endMsg]);
+ end
+ else
+ fprintf([' [', fileName, '] ', msg]);
end
end
diff --git a/src/resetDevTools.m b/src/resetDevTools.m
index ced660f..d1cd136 100644
--- a/src/resetDevTools.m
+++ b/src/resetDevTools.m
@@ -1,27 +1,64 @@
-function resetDevTools()
-% devTools
+function resetDevTools(hardReset)
+% Reset the configuration of the development tools
%
-% PURPOSE: reset the configuration of the development tools
+% USAGE:
%
+% resetDevTools()
+%
+% INPUTS:
+% hardReset: Boolean to hard reset the devTools
+% (changes the local `git` configuration) (default: `false`)
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
+ global resetDevToolsFlag
+
+ if ~exist('hardReset', 'var')
+ hardReset = false;
+ end
% call checkSystem to set default values for gitConf and gitCmd
checkSystem(mfilename);
- % unset the user name
- [status_gitConfUserGet, result_gitConfUserGet] = system('git config --global --unset-all user.github-username');
+ if resetDevToolsFlag
+ if hardReset
+ % unset the path to the local fork
+ [status_gitConfForkDirGet, result_gitConfForkDirGet] = system(['git config --global --unset user.', gitConf.leadForkDirName, gitConf.nickName, '.path']);
- if status_gitConfUserGet == 0
- printMsg(mfilename, 'Your Github username has been removed.');
- else
- fprintf(result_gitConfUserGet);
- fprintf([gitCmd.lead, ' [', mfilename,'] Your Github username could not be removed.', gitCmd.fail, gitCmd.trail]);
- end
+ if status_gitConfForkDirGet == 0
+ printMsg(mfilename, 'Your fork directory has been removed from your local git configuration.');
+ else
+ fprintf(result_gitConfForkDirGet);
+ fprintf([gitCmd.lead, ' [', mfilename,'] Your fork directory could not be removed from your local git configuration.', gitCmd.fail, gitCmd.trail]);
+ end
- clear global gitConf;
- clear global gitCmd;
+ % unset the user name
+ [status_gitConfUserGet, result_gitConfUserGet] = system('git config --global --unset-all user.github-username');
- fprintf([' [', mfilename, '] The development tools have been reset.\n']);
+ if status_gitConfUserGet == 0
+ printMsg(mfilename, 'Your Github username has been removed from your local git configuration.');
+ else
+ fprintf(result_gitConfUserGet);
+ fprintf([gitCmd.lead, ' [', mfilename,'] Your Github username could not be removed from your local git configuration.', gitCmd.fail, gitCmd.trail]);
+ end
+ end
+
+ clear global gitConf;
+ clear global gitCmd;
+ clear global resetDevToolsFlag;
+
+ % define an error message
+ if hardReset
+ resetMode = 'hard';
+ else
+ resetMode = 'soft';
+ end
+
+ fprintf([' [', mfilename, '] The development tools have been reset (' resetMode ' reset).\n']);
+ else
+ resetDevToolsFlag = true;
+ end
end
diff --git a/src/resetLocalFork.m b/src/resetLocalFork.m
index 13a5931..b28b41d 100644
--- a/src/resetLocalFork.m
+++ b/src/resetLocalFork.m
@@ -1,8 +1,13 @@
function resetLocalFork()
-% devTools
+% Clean all files in the working directory and reset the fork
%
-% PURPOSE: clean all files in the working directory and reset the fork
+% USAGE:
%
+% resetLocalFork()
+%
+% .. Author:
+% - Laurent Heirendt
+
global gitConf
global gitCmd
diff --git a/src/submitContribution.m b/src/submitContribution.m
index 4a7612c..9267fd8 100644
--- a/src/submitContribution.m
+++ b/src/submitContribution.m
@@ -1,8 +1,15 @@
function submitContribution(branchName)
-% devTools
+% Submit an existing feature (branch) named `branchName`
%
-% PURPOSE: submit an existing feature (branch) named
+% USAGE:
%
+% submitContribution(branchName)
+%
+% INPUT:
+% branchName: Name of the local branch to be pushed to the git server
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
@@ -13,7 +20,7 @@ function submitContribution(branchName)
% check if branch exists
checkoutBranch(branchName);
- if gitConf.verbose
+ if gitConf.printLevel > 0
originCall = [' [', mfilename, '] '];
else
originCall = '';
@@ -150,14 +157,57 @@ function submitContribution(branchName)
if countAddFiles > 0
fprintf([gitCmd.lead, originCall, 'You have selected ', num2str(countAddFiles), ' files to be added in one commit.', gitCmd.trail]);
- commitMsg = input([gitCmd.lead, originCall, ' -> Please enter a commit message (example: "Fixing bug with input arguments"): '], 's');
+ % define prohibited sequences
+ dictFlags = {'yy', 'nn', 'commit', 'abc'};
+
+ % initialize loop flag
+ incorrectCommitMsg = true;
+
+ loopCounter = 0;
+
+ % loop as long as the commit message is not correct
+ while incorrectCommitMsg && loopCounter < 10
+ % ask the user for a commit message
+ commitMsg = input([gitCmd.lead, originCall, ' -> Please enter a commit message (example: "Fixing bug with input arguments"): '], 's');
- if ~isempty(commitMsg)
+ % omit non literal characters
+ commitMsg = regexprep(commitMsg, '[^a-zA-Z0-9_-?! ]', '');
- if ~strcmp(commitMsg(1), '"') || ~strcmp(commitMsg(end), '"')
- commitMsg = ['"', commitMsg, '"'];
+ % trim the commitMsg
+ commitMsg = strtrim(commitMsg);
+
+ % add double quotes to the commit message if not set
+ if isempty(commitMsg)
+ incorrectCommitMsg = true;
+ else
+ if ~strcmp(commitMsg(1), '"') || ~strcmp(commitMsg(end), '"')
+ commitMsg = ['"', commitMsg, '"'];
+ end
end
+ % NOTE: anything below assumes "commitMsg"
+
+ % if the commit message is not empty and minimum 5 characters (+2 quotes)
+ for k = 1:length(dictFlags)
+ if length(commitMsg) >= 4+2 && isempty(strfind(commitMsg, dictFlags{k}))
+ incorrectCommitMsg = false;
+ continue;
+ else
+ incorrectCommitMsg = true;
+ break;
+ end
+ end
+
+ if incorrectCommitMsg
+ warning([gitCmd.lead, 'The commit message must be at least 5 characters long and not contain the word `commit`.']);
+ end
+
+ % increment the loop counter
+ loopCounter = loopCounter + 1;
+ end
+
+ % set the commit message
+ if ~incorrectCommitMsg
[status_gitCommit, result_gitCommit] = system(['git commit -m', commitMsg]);
fprintf([gitCmd.lead, originCall, 'Your commit message has been set.', gitCmd.success, gitCmd.trail]);
if status_gitCommit == 0
@@ -167,7 +217,7 @@ function submitContribution(branchName)
error([gitCmd.lead, ' [', mfilename,'] Your commit message cannot be set.', gitCmd.fail]);
end
else
- error([gitCmd.lead, ' [', mfilename,'] Please enter a commit message that has more than 10 characters.', gitCmd.fail]);
+ error([gitCmd.lead, ' [', mfilename,'] Your commit message was not accepted.', gitCmd.fail]);
end
end
diff --git a/src/updateDevTools.m b/src/updateDevTools.m
index 15902ac..6a94d30 100644
--- a/src/updateDevTools.m
+++ b/src/updateDevTools.m
@@ -1,8 +1,12 @@
function updateDevTools()
-% devTools
+% Update the devTools and set the SSH origin if necessary
%
-% PURPOSE: update the devTools and set the SSH origin if necessary
+% USAGE:
%
+% updateDevTools()
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
diff --git a/src/updateFork.m b/src/updateFork.m
index ee8b31e..f66b36d 100644
--- a/src/updateFork.m
+++ b/src/updateFork.m
@@ -1,8 +1,15 @@
function updateFork(force)
-% devTools
+% Updates the fork and the submodules of the repository
%
-% PURPOSE: updates the fork and the submodules of the repository
+% USAGE:
%
+% updateFork(force)
+%
+% INPUT:
+% force: Boolean flag to use force for updating the fork
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
@@ -18,7 +25,11 @@ function updateFork(force)
currentDir = strrep(pwd, '\', '\\');
% list the branches that should be updated
- branches = {'master', 'develop'};
+ if checkRemoteBranchExistence('develop')
+ branches = {'master', 'develop'};
+ else
+ branches = {'master'}; % fall back to master, which always exists
+ end
% change to the directory of the fork
cd(gitConf.fullForkDir)
@@ -46,7 +57,7 @@ function updateFork(force)
if status_curl == 0 && ~isempty(strfind(result_curl, '200 OK'))
% pull eventual changes from other contributors or administrators
- [status_gitFetchOrigin, result_gitFetchOrigin] = system('git fetch origin '); % no pull
+ [status_gitFetchOrigin, result_gitFetchOrigin] = system('git fetch origin'); % no pull
if status_gitFetchOrigin == 0
printMsg(mfilename, 'Changes of fork (origin) fetched.');
else
@@ -78,6 +89,7 @@ function updateFork(force)
fprintf(result_gitCheckout);
printMsg(mfilename, ['The feature (branch) <', branches{k}, '> could not be checked out.']);
end
+
else
[status_gitCheckoutCreate, result_gitCheckoutCreate] = system(['git checkout -b ', branches{k}]);
@@ -90,12 +102,23 @@ function updateFork(force)
end
% determine the number of commits that the local master branch is behind
- [status_gitCount, result_gitCount] = system(['git rev-list --left-right --count ', branches{k}, '...upstream/', branches{k}]);
+ [status_gitCountUpstream, result_gitCountUpstream] = system(['git rev-list --left-right --count ', branches{k}, '...upstream/', branches{k}]);
- if status_gitCount == 0
- commitsAheadBehind = str2num(char(strsplit(result_gitCount)));
+ [status_gitCountOrigin, result_gitCountOrigin] = system(['git rev-list --left-right --count ', branches{k}, '...origin/', branches{k}]);
- if length(commitsAheadBehind) > 0 && commitsAheadBehind(2) > 0
+ if status_gitCountUpstream == 0 && status_gitCountOrigin == 0
+ commitsAheadBehindUpstream = str2num(char(strsplit(result_gitCountUpstream)));
+ commitsAheadBehindOrigin = str2num(char(strsplit(result_gitCountOrigin)));
+
+ if (length(commitsAheadBehindUpstream) > 0 && commitsAheadBehindUpstream(2) > 0) || (length(commitsAheadBehindOrigin) > 0 && commitsAheadBehindOrigin(1) > 0)
+
+ [status_gitPull, result_gitPull] = system(['git pull origin ', branches{k}]);
+ if status_gitPull == 0
+ printMsg(mfilename, ['The <', branches{k}, '> feature (branch) of the fork could not be pulled.']);
+ else
+ fprintf(result_gitPull);
+ error([gitCmd.lead, ' [', mfilename,'] Impossible to pull changes from the <', branches{k}, '> feature (branch) of the fork.', gitCmd.fail]);
+ end
if ~force
% merge the changes from upstream to the branch
@@ -141,11 +164,15 @@ function updateFork(force)
end
end
end
+
+ % initialize and update the submodules
+ updateSubmodules();
else
fprintf(resultList);
error([gitCmd.lead, ' [', mfilename,'] Impossible to retrieve the features (branches) of your local fork.', gitCmd.fail]);
end
else
+ fprintf(result_gitStatus);
printMsg(mfilename, ['The local fork cannot be updated as you have uncommitted changes. Please submit/publish them first.']);
end
diff --git a/src/updateSubmodules.m b/src/updateSubmodules.m
index c1ddddf..8ce009b 100644
--- a/src/updateSubmodules.m
+++ b/src/updateSubmodules.m
@@ -1,12 +1,21 @@
function updateSubmodules()
-% devTools
+% Clones the submodules and updates the repository
%
-% PURPOSE: clones the submodules and updates the repository
+% USAGE:
%
+% updateSubmodules()
+%
+% .. Author:
+% - Laurent Heirendt
global gitConf
global gitCmd
+ currentDir = strrep(pwd, '\', '\\');
+
+ % change to the directory of the fork
+ cd(gitConf.fullForkDir)
+
% temporary disable ssl verification
[status_setSSLVerify, result_setSSLVerify] = system('git config --global http.sslVerify false');
@@ -17,8 +26,8 @@ function updateSubmodules()
error([gitCmd.lead, ' [', mfilename,'] Your global git configuration could not be changed.', gitCmd.fail]);
end
- % Update/initialize submodules
- [status_gitSubmodule, result_gitSubmodule] = system('git submodule update --init');
+ % initialize submodules
+ [status_gitSubmodule, result_gitSubmodule] = system('git submodule init');
if status_gitSubmodule == 0
printMsg(mfilename, 'The submodules have been initialized.');
@@ -27,13 +36,43 @@ function updateSubmodules()
error([gitCmd.lead, ' [', mfilename,'] The submodules could not be initialized.', gitCmd.fail]);
end
- % reset each submodule
- [status_gitReset result_gitReset] = system('git submodule foreach --recursive git reset --hard');
- if status_gitReset == 0
- printMsg(mfilename, 'The submodules have been reset.');
+ % retrieve the count for each submodule
+ [status_gitSubmoduleCount, result_gitSubmoduleCount] = system('git submodule foreach --recursive git rev-list --count origin/master...HEAD');
+
+ % split the array at line breaks
+ arrResult = regexp(result_gitSubmoduleCount,'\n+','split'); %strsplit is not compatible with older versions of MATLAB
+ arrResult = strtrim(arrResult);
+
+ % filter out the empty ones
+ arrResult = arrResult(~cellfun(@isempty, arrResult));
+
+ % calculate the total number of changes
+ sumChanges = 0;
+ nSubmodules = length(arrResult)/2;
+ for k = 1:nSubmodules
+ sumChanges = sumChanges + str2num(arrResult{2*k});
+ end
+
+ % update submodules
+ [status_gitSubmodule, result_gitSubmodule] = system('git submodule update');
+
+ if status_gitSubmodule == 0
+ printMsg(mfilename, 'The submodules have been initialized.');
else
- fprintf(result_gitReset);
- error([gitCmd.lead, ' [', mfilename,'] The submodules could not be reset.', gitCmd.fail]);
+ fprintf(result_gitSubmodule);
+ error([gitCmd.lead, ' [', mfilename,'] The submodules could not be initialized.', gitCmd.fail]);
+ end
+
+ % update the submodules
+ if sumChanges > 0
+ % reset each submodule
+ [status_gitReset result_gitReset] = system('git submodule foreach --recursive git reset --hard');
+ if status_gitReset == 0
+ printMsg(mfilename, 'The submodules have been reset.');
+ else
+ fprintf(result_gitReset);
+ error([gitCmd.lead, ' [', mfilename,'] The submodules could not be reset.', gitCmd.fail]);
+ end
end
% restore global configuration by unsetting http.sslVerify
@@ -45,4 +84,7 @@ function updateSubmodules()
fprintf(result_setSSLVerify);
error([gitCmd.lead, ' [', mfilename,'] Your global git configuration could not be restored.', gitCmd.fail]);
end
+
+ % change back to the original directory
+ cd(currentDir);
end
diff --git a/test/inputCI.txt b/test/inputCI.txt
index 686e50c..33f354e 100644
--- a/test/inputCI.txt
+++ b/test/inputCI.txt
@@ -1,10 +1,9 @@
cobrabot
-~/
+/home/sbg-jenkins/
y
n
testFile1
n
y
testFile2
-n
-n
+message-test
diff --git a/test/launchTests.m b/test/launchTests.m
index 0a3b884..d3e059a 100644
--- a/test/launchTests.m
+++ b/test/launchTests.m
@@ -1,7 +1,7 @@
if ~isempty(strfind(getenv('HOME'), 'jenkins'))
% do not change the paths below
- addpath(genpath('/var/lib/jenkins/MOcov'));
- addpath(genpath('/var/lib/jenkins/jsonlab'));
+ addpath(genpath('/home/sbg-jenkins/MOcov'));
+ addpath(genpath('/home/sbg-jenkins/jsonlab'));
% change the directory on the CI server
cd([pwd, '/../'])
@@ -69,11 +69,12 @@
end
end
- % remove the old badge
- system('rm /var/lib/jenkins/userContent/codegrade-MATLABdevTools.svg');
-
% set the new badge
- system(['cp /var/lib/jenkins/userContent/codegrade-', grade, '.svg /var/lib/jenkins/userContent/codegrade-MATLABdevTools.svg']);
+ system(['cp /mnt/prince-data/jenkins/userContent/codegrade-', grade, '.svg /mnt/prince-data/jenkins/userContent/codegrade-MATLABdevTools.svg']);
+
+ % secure copy the badge from the slave
+ system('scp -P 8022 /mnt/prince-data/jenkins/userContent/codegrade-MATLABdevTools.svg jenkins@prince-server.lcsb.uni.lux:/var/lib/jenkins/userContent');
+
end
try
diff --git a/test/testCheckSystem.m b/test/testCheckSystem.m
index 0ffec65..b31931e 100644
--- a/test/testCheckSystem.m
+++ b/test/testCheckSystem.m
@@ -5,13 +5,14 @@
launcher = '\n\n ~~~ MATLAB.devTools ~~~\n\n';
remoteRepoURL = 'https://github.com/uni-lu/MATLAB.devTools.CI.git';
nickName = 'MATLAB.devTools.CI';
-verbose = true;
+printLevel = 1;
% reset the development tools
resetDevTools();
% set the configuration
-confDevTools(launcher, remoteRepoURL, nickName, verbose);
+confDevTools(nickName, 'remoteRepoURL', remoteRepoURL, 'launcher', launcher, ...
+ 'nickName', nickName, 'printLevel', printLevel);
% check the system
checkSystem();