<commit_before># -*- python -*-
# ex: set syntax=python:

# This is a sample buildmaster config file. It must be installed as
# 'master.cfg' in your buildmaster's base directory.

# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}

####### BUILDSLAVES

# The 'slaves' list defines the set of recognized buildslaves. Each element is
# a BuildSlave object, specifying a unique slave name and password.  The same
# slave name and password must be configured on the slave.
from buildbot.buildslave import BuildSlave
from buildbot_private import pass_dict
c['slaves'] = [BuildSlave("linux-slave", pass_dict["linux-slave"], max_builds = 1),
               BuildSlave("OSX-slave", pass_dict["OSX-slave"], max_builds = 1),
               BuildSlave("windows-slave", pass_dict["windows-slave"], max_builds = 1),
               BuildSlave("linux32-slave", pass_dict["linux32-slave"], max_builds = 1),
               BuildSlave("windows-DTU-slave", pass_dict["windows-DTU-slave"], max_builds = 1)
               ]

# 'slavePortnum' defines the TCP port to listen on for connections from slaves.
# This must match the value configured into the buildslaves (with their
# --master option)
c['slavePortnum'] = 9989

####### CHANGESOURCES

# the 'change_source' setting tells the buildmaster how it should find out
# about source code changes.  Here we point to the CoolProp source code.

from buildbot.changes.gitpoller import GitPoller
c['change_source'] = []
c['change_source'].append(GitPoller(
        'https://github.com/CoolProp/CoolProp',
        workdir='gitpoller-workdir', branch='master',
        pollinterval=300)) # Interval between triggering a build

####### BUILDERS

# The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
# what steps, and which slaves can execute them.  Note that any particular build will
# only take place on one slave.

from buildbot.process.factory import BuildFactory
from buildbot.steps.source.git import Git
from buildbot.steps.shell import ShellCommand
from buildbot.steps.slave import MakeDirectory, RemoveDirectory, CopyDirectory
from buildbot.steps.transfer import DirectoryUpload, FileDownload
from buildbot.process import properties

"""
from http://ss64.com/nt/del.html
deltree.cmd script, save it somewhere on the system PATH on windows
:: DelTree.cmd
:: Remove all files and subfolders but NOT the root folder
:: From tip 617 at JsiFAQ.com
@echo off
if "%1"=="" goto:eof
pushd %1
del /q *.*
for /f "Tokens=*" %%G in ('dir /B') do rd /s /q "%%G"
popd
"""

@properties.renderer
def cleanCommand(props):

    fullclean = props.getProperty('fullclean', default = False)
    is_windows = props.getProperty('slavename').find('windows') >= 0

    if fullclean:
        if is_windows:
            command = ' '.join(['deltree','.','&&','echo','fully cleaned'])
        else:
            command = ' '.join(['rm','-rfv','*','&&','echo','fully cleaned'])
    else:
        command = ['echo','no clean requested;', 'fullclean:', props.getProperty('fullclean')]
    return command

# A custom platform and Python identifiers
platformID = {
    "windows" : 1,
    "osx"     : 2,
    "linux"   : 3
    }

bitnessID = {
    "32bit" : 1,
    "64bit" : 2
    }

pythonID = {
    "py27" : 1,
    "py32" : 2,
    "py33" : 3,
    "py34" : 4
    }

# A couple of functions to make it simpler to use the shorthand notation for the
# different platform, bitness, python combinations. These functions are candidates
# for the most inefficient code written in 2014, but they make the rest of this
# config file so much nicer and shorter.
def getIDtuple(testID):
    platformTEST = None
    bitnessTEST  = None
    pythonTEST   = None
    #
    TEST = str(testID)
    i    = len(TEST)
    if i <  1: raise ValueError("The given testID \"{0}\" is too short.".format(TEST))
    if i >= 1: platformTEST = TEST[0]
    if i >= 2: bitnessTEST  = TEST[1]
    if i >= 3: pythonTEST   = TEST[2]
    if i > 3: raise ValueError("The given testID \"{0}\" is too long.".format(TEST))
    #
    return platformTEST, bitnessTEST, pythonTEST

def getIDstr(platform=None, bitness=None, python=None):
    if platform is None and bitness is None and python is None:
        raise ValueError("All given parameters are None, this does not work.")
    #
    def getIDstr_helper(input, alt):
        if input is None: return str(0)
        if str(input) == "0": return str(0)
        if input in alt: return str(alt[input])
        return str(int(input))
    #
    platform = getIDstr_helper(platform,platformID)
    bitness  = getIDstr_helper(bitness,bitnessID)
    python   = getIDstr_helper(python,pythonID)
    #
    return platform+bitness+python

def compareID(in1, in2):
    """Takes int or str data and compares it to the other input.
    0 can be used ad a joker, which always compares to True.
    """
    if   in1 is None or   in2 is None : return True
    if int(in1) == 0 or int(in2) == 0 : return True
    return int(in1) == int(in2)

def checkID(inID, teID=None, strict=True):
    platformIN, bitnessIN, pythonIN = getIDtuple(testID=inID)
    platformTE, bitnessTE, pythonTE = getIDtuple(testID=teID)
    #
    result = compareID(platformTE, platformIN)
    if not result and strict: raise ValueError("The given input for the platform \"{0}\" did not match \"{1}\"".format(platformIN,platformTE))
    result =  compareID(bitnessTE, bitnessIN) and result
    if not result and strict: raise ValueError("The given input for the bitness \"{0}\" did not match \"{1}\"".format(bitnessIN,bitnessTE))
    result =   compareID(pythonTE, pythonIN) and result
    if not result and strict: raise ValueError("The given input for the Python version \"{0}\" did not match \"{1}\"".format(pythonIN,pythonTE))
    return result

def getFromDict(inDict, inID):
    res = inDict.get(inID)
    if res is None: # Try some more
        for key in inDict:
            if checkID(inID, key, strict=False):
                if res is not None:
                    raise ValueError("Already found a matching entry \"{0}\" for \"{1}\", please specify more parameters.".format(res,inID))
                else:
                    res = inDict[key]
    if res is None:
        raise ValueError("Could not find a matching entry for \"{0}\".".format(inID))
    else:
        return res

def getKeyFromVal(dic,val):
    for key in dic:
        if str(dic[key])==str(val):
            return key
    return None

def getJobName(inID):
    platform, bitness, python = getIDtuple(inID)
    platform = getKeyFromVal(platformID, platform)
    bitness  = getKeyFromVal( bitnessID, bitness )
    python   = getKeyFromVal(  pythonID, python  )
    res = []
    if platform is not None: res.append(platform)
    if  bitness is not None: res.append(bitness)
    if   python is not None: res.append(python)
    return "-".join(res)


class PythonSlaveConfig(object):
    def __init__(self,name):
        self.name = name
        self.pyact = {}
        self.pyenv = {}
        self.pyins = {}

    def getPyact(self, inID):
        return getFromDict(self.pyact, inID)

    def getPyenv(self, inID):
        return getFromDict(self.pyenv, inID)

    def getPyins(self, inID):
        return getFromDict(self.pyins, inID)

    def getIDs(self):
        IDs = []
        for pl in platformID:
            for bi in bitnessID:
                for py in pythonID:
                    tmpID = getIDstr(pl, bi, py)
                    try:
                        #print "Testing for {0} in act".format(tmpID)
                        self.getPyact(tmpID)
                        #print "Testing for {0} in env".format(tmpID)
                        self.getPyenv(tmpID)
                        #print "Testing for {0} in ins".format(tmpID)
                        self.getPyins(tmpID)
                        #print "Appending {0}".format(tmpID)
                        IDs.append(tmpID)
                    except:
                        pass
        return IDs


# A centralised method to provide the objects with some presets
def getBaseFactory(gitMode = 'incremental'):
    factory = BuildFactory()
    factory.addStep(ShellCommand(command=cleanCommand, description='fullclean?', workdir=""))
    factory.addStep(Git(repourl='git://github.com/CoolProp/CoolProp', mode=gitMode, submodules = True, progress=True, haltOnFailure = True))
    return factory


# All what is needed to create the website, it makes sense to run the
# nightly builds on the same machine. This avoids extra data transfer.
def websiteFactory(platform, gitMode='incremental', fullBuild=False):
    if 'win' in platform.lower():
        raise ValueError("The docs cannot be build on a Windows machine, we rely on rsync...")
    # Some basic preparations
    server_uri = '<EMAIL>.dream<EMAIL>'
    server_dir = '/home/coolprop/buildbot/server-master'
    server_des = "{0}:{1}".format(server_uri,server_dir)
    #
    local_build_dir = 'Web/_build/html'
    server_target_dir = '{0}/public_html/sphinx'.format(server_des)
    #
    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    # Install the latest CoolProp
    factory.addStep(ShellCommand(command=["python", "setup.py", "install"], workdir= 'build/wrappers/Python', haltOnFailure = True))
    # Create plots and fluid tables
    if fullBuild:
        factory.addStep(ShellCommand(command=["python", "__init__.py", "True"], workdir= 'build/Web/scripts', haltOnFailure = True))
    else:
        factory.addStep(ShellCommand(command=["python", "__init__.py", "False"], workdir= 'build/Web/scripts', haltOnFailure = True))
    # Run sphinx build
    factory.addStep(ShellCommand(command=["python", "-c", "\"import CoolProp; print(CoolProp.__file___)\""], workdir= 'build/wrappers/Python', haltOnFailure = True))
    # Run doxygen build
    factory.addStep(ShellCommand(command=' '.join(["doxygen","Doxyfile"]), workdir= 'build', haltOnFailure = True))
    # Run sphinx apidoc
    #factory.addStep(ShellCommand(command=["sphinx-apidoc","-T","-f","-o","apidoc","../CoolProp"],workdir= 'build/Web', haltOnFailure = True))
    # Run sphinx website builder
    factory.addStep(ShellCommand(command=["make", "html"], workdir= 'build/Web', haltOnFailure = True))
    # Upload the generated files
    factory.addStep(ShellCommand(command = 'rsync -a --stats {0}/ {1}'.format(local_build_dir,server_target_dir), haltOnFailure = True))
    return factory


# The reworked Python builder factory. It relies on Miniconda and can handle both 32bit and 64bit builds
# Currently, it only supports Windows, but the plan is to integrate MacOS and Linux builds here as well.
# You have to have both CMake and Git available on your standard command line, pay attention when installing
# these two tools on your Windows machine.
def pythonFactory(pyID, pyCFG=PythonSlaveConfig("name"), gitMode='incremental'):
    #
    # Some basic settings for all builders
    workingFolder = "build/wrappers/Python"
    installFolder = "build/install_root"
    relinstFolder = "../../install_root" # relative path
    uploadFolder  = "install_root" # relative to build
    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    # Remove the temporary folder for installs
    factory.addStep(RemoveDirectory(dir=installFolder, haltOnFailure = True))
    #
    # Setting the appropriate virtual environment activator
    pyact = pyCFG.getPyact(pyID)
    # Setting the appropriate virtual environment
    pyenv = pyCFG.getPyenv(pyID)
    # Setting the appropriate installer options
    pyins = pyCFG.getPyins(pyID)
    # Getting the appropriate virtual environment activator
    if pyact is None:
        raise ValueError("Your selected Python installation \"{0}\" is not supported by this builder factory".format(pyID))
    # Getting the appropriate virtual environment
    if pyenv is None:
        raise ValueError("Your selected Python environment \"{0}\" is not supported by this builder factory".format(pyID))
    # Getting the appropriate installer options
    if pyins is None:
        raise ValueError("Your selected Python environment \"{0}\" does not have installer options in this builder factory".format(pyID))
    #
    activateCMD =  " ".join([pyact, pyenv]) # We always activate an environment, regardless of the host
    installCMD  =  " ".join(["python", "setup.py"] + pyins)
    combinedCMD = " && ".join([activateCMD, installCMD])
    factory.addStep(ShellCommand(command = combinedCMD, workdir = workingFolder, haltOnFailure = True))
    #
    factory.addStep(DirectoryUpload(slavesrc=uploadFolder, masterdest="public_html/binaries", url="binaries", compress="bz2"))
    return factory


def cmakeFactory(mod_name = None, gitMode = 'incremental', install = True, pre_cmd = [], cmake_args = [], build_args = [], ctest_args = [], cmake_env={}, test = True):
    """
    Parameters
    ----------
    mod_name: string
        The module to be built, one of 'Octave','python','Csharp', etc. - turns on the macro -DCOOLPROP_OCTAVE_MODULE=ON for instance if you pass octave
    gitMode: string
        What mode to use, one of 'incremental' or 'full'
    install: bool
        True for install, False for just build
    pre_cmd: list of strings
        List of strings of commands to be executed before the cmake command, gets merged with &&
    cmake_args: list of strings
        List of strings of arguments to be passed to cmake (Makefile generating) step
    cmake_env: dictionary (string->string)
        A dictionary including keys that can be set in the build environment
    build_args: list of strings
        List of strings of arguments to be passed to cmake install or build command depending on value of install
    ctest_args: list of strings
        List of strings of arguments to be passed to ctest
    """
    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    #
    factory.addStep(MakeDirectory(dir=working_folder, haltOnFailure = True))
    factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))
    #
    if len(pre_cmd)>0 and not pre_cmd[-1]=="&&": pre_cmd.append("&&")
    if mod_name is not None:
        cmake_args = ["-DCOOLPROP_"+mod_name.upper()+"_MODULE=ON","-DBUILD_TESTING=ON"]+cmake_args

    cmakeCMD = pre_cmd + ["cmake", ".."]+cmake_args
    factory.addStep(ShellCommand(
      command=' '.join(cmakeCMD),
      env = cmake_env,
      workdir= working_folder,
      haltOnFailure = True))
    #
    if install: installCMD = ["--target", "install"]
    else: installCMD = []
    factory.addStep(ShellCommand(
      command=' '.join(pre_cmd+["cmake", "--build", "."]+installCMD+build_args),
      workdir = working_folder,
      haltOnFailure = True))
    #
    if test:
        factory.addStep(ShellCommand(
          command=["ctest", "--extra-verbose"] + ctest_args,
          workdir = working_folder,
          haltOnFailure = True))
    #
    if install:
        factory.addStep(DirectoryUpload(
          slavesrc="install_root",
          masterdest="public_html/binaries",
          url="binaries",
          compress="bz2"))
    return factory


def fortranFactory(platform=1):
    working_folder = "build/build" # Same as in cmakeFactory
    fortran_folder = "build/wrappers/Fortran/detailed_example" #
    #
    if platform==platformID["windows"]:
        cmake_args = ["-DCOOLPROP_EXTERNC_STATIC_LIBRARY=ON","-G", "\"MinGW Makefiles\""]
        cp_cmd     = "copy /Y *.f90 ..\\..\\..\\build"
        build_cmd  = "gfortran -c -Wall cpinterface.f90 cool_fortran_bind.f90"
        link_cmd   = "gfortran -o main *.o libCoolProp.a -lstdc++"
        exec_cmd   = "main"
    elif platform==platformID["linux"]:
        cmake_args = ["-DCOOLPROP_EXTERNC_STATIC_LIBRARY=ON"]
        cp_cmd     = "cp *.f90 ../../../build/"
        build_cmd  = "gfortran -c -Wall cpinterface.f90 cool_fortran_bind.f90"
        link_cmd   = "gfortran -o main *.o libCoolProp.a -lstdc++ -ldl"
        exec_cmd   = "./main"
    else:
        raise ValueError("Unknown Fortran platform: {0}".format(platform))

    # Create the factory to add the actions to
    factory = cmakeFactory(cmake_args=cmake_args,install=False,test=False)
    #
    #factory.addStep(CopyDirectory(src=fortran_folder, dest=working_folder))
    factory.addStep(ShellCommand(command=cp_cmd,  workdir = fortran_folder, haltOnFailure = True))
    for cmd in [build_cmd,link_cmd,exec_cmd]:
        factory.addStep(ShellCommand(command=cmd, workdir = working_folder, haltOnFailure = True))
    return factory


def javascript_slave(platform, cmake_args = [], cmake_env = {}, build_args = [], gitMode = 'incremental'):

    working_folder = "build/Javascript"
    from buildbot.process.properties import WithProperties

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)

    # Remove the temporary folder for installs
    factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))

    factory.addStep(ShellCommand(command="cmake .. -DCOOLPROP_JAVASCRIPT_MODULE=ON -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Platform/Emscripten.cmake",
                                 workdir= working_folder,
                                 haltOnFailure = True))
    factory.addStep(ShellCommand(command=["cmake", "--build", ".", "--target", "install"]+build_args, workdir = working_folder, haltOnFailure = True))
    factory.addStep(DirectoryUpload(slavesrc="install_root", masterdest="public_html/binaries", url="binaries", compress="bz2"))

    return factory

def python_source_slave(key, platform, conda_env, cmake_args = [], cmake_env = {}, build_args = [], gitMode = 'incremental'):
    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)

    # Remove the temporary folder for installs
    factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))
    factory.addStep(MakeDirectory(dir=working_folder, haltOnFailure = True))

    factory.addStep(ShellCommand(command = ' '.join(['source',"activate",conda_env,"&&","cmake", "..", "-DCOOLPROP_PYTHON_PYPI=ON","&&","cmake","--build",".","--target","CoolProp"]+cmake_args),
                                 env = cmake_env,
                                 workdir= working_folder,
                                 haltOnFailure = True))
    factory.addStep(DirectoryUpload(slavesrc="install_root", masterdest="public_html/binaries", url="binaries", compress="bz2"))
    return factory

def deb_slave(gitMode = 'incremental'):

    working_folder = "build/wrappers/DEB"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)

    factory.addStep(ShellCommand(command = ' '.join(["chmod","+x","package.bsh","&&", "./package.bsh"]),
                                 workdir= working_folder,
                                 haltOnFailure = True))
    factory.addStep(MakeDirectory(dir=working_folder+'/DEB/DEB', haltOnFailure = True))
    factory.addStep(ShellCommand(command = ' '.join(["mv","*.deb","DEB/DEB"]),
                                 workdir= working_folder,
                                 haltOnFailure = True))
    factory.addStep(DirectoryUpload(slavesrc="wrappers/DEB/DEB", masterdest="public_html/binaries", url="binaries/DEB", compress="bz2"))

    return factory

def excel_slave(gitMode = 'incremental'):
    """
    """
    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    #
    factory.addStep(MakeDirectory(dir=working_folder+'/32bitDLL', haltOnFailure = True))
    factory.addStep(MakeDirectory(dir=working_folder+'/64bitDLL', haltOnFailure = True))
    factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))
    # Make 32-bit __stdcall DLL
    factory.addStep(ShellCommand(command=["cmake", "../..", "-DCOOLPROP_32BIT_STDCALL_SHARED_LIBRARY=ON","-G", "Visual Studio 10"],
                                 workdir= working_folder+'/32bitDLL',
                                 haltOnFailure = True))
    factory.addStep(ShellCommand(command=["cmake", "--build", ".", "--target", "install"], workdir = working_folder+'/32bitDLL', haltOnFailure = True))
    # Make 64-bit DLL
    factory.addStep(ShellCommand(command=["cmake", "../..", "-DCOOLPROP_64BIT_SHARED_LIBRARY=ON","-G", "Visual Studio 10 Win64"],
                                 workdir= working_folder+'/64bitDLL',
                                 haltOnFailure = True))
    factory.addStep(ShellCommand(command=["cmake", "--build", ".", "--target", "install"], workdir = working_folder+'/64bitDLL', haltOnFailure = True))

    factory.addStep(MakeDirectory(dir='build\\bin\\MicrosoftExcel', haltOnFailure = True))
    # Copy the created DLL
    factory.addStep(ShellCommand(command=' '.join(["copy", "/Y", "install_root\\shared_library\\Windows\\32bit__stdcall_calling_convention\\*.dll", "bin\\MicrosoftExcel"]), workdir = 'build', haltOnFailure = True))
    factory.addStep(ShellCommand(command=' '.join(["move", "CoolProp.dll", "CoolProp_x64.dll"]), workdir = 'build/install_root/shared_library/Windows/64bit', haltOnFailure = True))
    factory.addStep(ShellCommand(command=' '.join(["copy", "/Y", "install_root\\shared_library\\Windows\\64bit\\*.dll", "bin\\MicrosoftExcel"]), workdir = 'build', haltOnFailure = True))
    # Copy other files
    factory.addStep(ShellCommand(command=["copy", "wrappers\Excel\CoolProp.xlam", "bin\MicrosoftExcel"], workdir = 'build', haltOnFailure = True))
    factory.addStep(ShellCommand(command=["copy", "wrappers\Excel\CoolProp.xla", "bin\MicrosoftExcel"], workdir = 'build', haltOnFailure = True))
    factory.addStep(ShellCommand(command=["copy", "wrappers\Excel\TestExcel.xlsx", "bin\MicrosoftExcel"], workdir = 'build', haltOnFailure = True))
    # Upload the files
    factory.addStep(DirectoryUpload(slavesrc="bin",masterdest="public_html/binaries",url="MicrosoftExcel",compress="bz2"))
    return factory

def cmake_slave(mod_name, platform, gitMode = 'incremental', install = True, cmake_args = [], build_args = [], ctest_args = [], cmake_env={}, test = True):
    """
    Parameters
    ----------
    mod_name: string
        The module to be built, one of 'Octave','python','Csharp', etc. - turns on the macro -DCOOLPROP_OCTAVE_MODULE=ON for instance if you pass octave
    gitMode: string
        What mode to use, one of 'incremental' or 'full'
    install: bool
        True for install, False for just build
    cmake_args: list of strings
        List of strings of arguments to be passed to cmake (Makefile generating) step
    cmake_env: dictionary (string->string)
        A dictionary including keys that can be set in the build environment
    build_args: list of strings
        List of strings of arguments to be passed to cmake install or build command depending on value of install
    ctest_args: list of strings
        List of strings of arguments to be passed to ctest
    """
    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    #
    factory.addStep(MakeDirectory(dir=working_folder, haltOnFailure = True))
    factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))
    if mod_name.lower() == 'octave' and platform.lower() == 'windows':
        pre = ['set','"PATH=%OCTAVE_ROOT%/bin;%PATH%"','&&']
    else:
        pre = []
    factory.addStep(ShellCommand(command=' '.join(pre+["cmake", "..", "-DCOOLPROP_"+mod_name.upper()+"_MODULE=ON","-DBUILD_TESTING=ON"]+cmake_args),
                                 env = cmake_env,
                                 workdir= working_folder,
                                 haltOnFailure = True))
    if install:
        factory.addStep(ShellCommand(command=' '.join(pre+["cmake", "--build", ".", "--target", "install"]+build_args), workdir = working_folder, haltOnFailure = True))
    else:
        factory.addStep(ShellCommand(command=' '.join(pre+["cmake", "--build", "."]+build_args), workdir = working_folder, haltOnFailure = True))
    if test:
        factory.addStep(ShellCommand(command=["ctest", "--extra-verbose"] + ctest_args, workdir = working_folder, haltOnFailure = True))
    if install:
        factory.addStep(DirectoryUpload(slavesrc="install_root",masterdest="public_html/binaries",url="binaries",compress="bz2"))
    return factory

def swig_matlab_builder(platform, gitMode = 'incremental', cmake_args = [], cmake_env = None):
    """
    Download SWIG+MATLAB version, use it to build _wrap file for MATLAB builder, upload generated file back to master.

    These generated files are needed for the other swig builders and are cross-platform
    """

    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    #
    # Download files from nightly build for swig
    factory.addStep(FileDownload(mastersrc = 'public_html/nightly/swig+MATLAB/'+platform+'/swig_MATLAB.7z', slavedest = 'swig_MATLAB.7z', haltOnFailure = True))
    # Directory for build
    factory.addStep(MakeDirectory(dir='build/build', haltOnFailure = True))
    # Unzip
    if platform == 'windows':
        factory.addStep(ShellCommand(command = 'set PATH=C:\\Program Files\\7-Zip\\;%PATH% && 7z -y -obuild x swig_MATLAB.7z', workdir = 'build', haltOnFailure = True))
    else:
        factory.addStep(ShellCommand(command =                                               '7z -y -obuild x swig_MATLAB.7z', workdir = 'build', haltOnFailure = True))

    if platform == 'windows':
        command = ["set", '"PATH=swig-matlab-bin\\bin;%PATH%"', "&&", "cmake", "..", "-DCOOLPROP_MATLAB_SWIG_MODULE=ON","-DSWIG_DIR=swig-matlab-bin/bin"] + cmake_args
    else:
        command = ["PATH=swig-matlab-bin/bin:${PATH}",                "cmake", "..", "-DCOOLPROP_MATLAB_SWIG_MODULE=ON","-DSWIG_DIR=swig-matlab-bin/bin"] + cmake_args

    factory.addStep(ShellCommand(command=' '.join(command),
                                 workdir= "build/build",
                                 env = cmake_env,
                                 haltOnFailure = True))
    if platform == 'windows':
        command = ["set", '"SWIG_LIB=swig-matlab-bin\\share\\swig\\3.0.3"', "&&", "cmake", "--build", ".", "--target", "install"]
    else:
        command = ["SWIG_LIB=swig-matlab-bin/share/swig/3.0.3", "cmake", "--build", ".", "--target", "install"]
    factory.addStep(ShellCommand(command=' '.join(command),
                                 workdir= "build/build",
                                 haltOnFailure = True))
    # Upload the files
    factory.addStep(DirectoryUpload(slavesrc="install_root",masterdest="public_html/binaries",url="binaries",compress="bz2"))
    return factory

def swig_scilab_builder(platform, gitMode = 'incremental'):
    """
    Download SWIG+scilab version on linux, use it to build _wrap file for scilab builder, upload generated file(s) back to master.

    These generated files are needed for the other swig builders and are cross-platform
    """

    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    #
    # Download files from nightly build for swig
    factory.addStep(FileDownload(mastersrc = 'public_html/nightly/swig+SCILAB/'+platform+'/swig_SCILAB.7z', slavedest = 'swig_SCILAB.7z', haltOnFailure = True))
    # Directory for build
    factory.addStep(MakeDirectory(dir='build/build', haltOnFailure = True))
    # Unzip
    factory.addStep(ShellCommand(command = '7z -y -obuild x swig_SCILAB.7z', workdir = 'build', haltOnFailure = True))
    if platform == 'windows':
        command = ["set", '"PATH=swig-scilab-bin\\bin;%PATH%"', "&&", "cmake", "..", "-DCOOLPROP_SCILAB_SWIG_MODULE=ON","-DSWIG_DIR=swig-scilab-bin"]
    else:
        command = ["PATH=swig-scilab-bin/bin:${PATH}","cmake", "..", "-DCOOLPROP_SCILAB_SWIG_MODULE=ON","-DSWIG_DIR=swig-scilab-bin"]
    factory.addStep(ShellCommand(command=' '.join(command),
                                 workdir= "build/build",
                                 haltOnFailure = True))
    if platform == 'windows':
        command = ["set", '"SWIG_LIB=swig-scilab-bin\\share\\swig\\3.0.2"', "&&", "cmake", "--build", ".", "--target", "install"]
    else:
        command = ["SWIG_LIB=swig-scilab-bin/share/swig/3.0.2", "cmake", "--build", ".", "--target", "install"]
    factory.addStep(ShellCommand(command=' '.join(command),
                                 workdir= "build/build",
                                 haltOnFailure = True))
    # Upload the files
    factory.addStep(DirectoryUpload(slavesrc="install_root",masterdest="public_html/binaries",url="binaries",compress="bz2"))
    return factory

def SWIG_MATLAB_bin_builder(platform, gitMode = 'incremental', windows = False):

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    # Build SWIG with MATLAB
    args = ["python","build_swig_matlab.py"]
    if windows:
        args += ['--windows']
        platform = 'windows'
    factory.addStep(ShellCommand(command=' '.join(args),
                                 workdir= "build/dev/scripts",
                                 haltOnFailure = True))
    factory.addStep(MakeDirectory(dir='build/dev/scripts/swig-MATLAB-temp', haltOnFailure = True))
    # Zip up the directory that was generated using bzip
    factory.addStep(ShellCommand(command=' '.join(["7z","a","../swig-MATLAB-temp/swig_MATLAB.7z","swig-matlab-bin"]),
                                 workdir= "build/dev/scripts/swig-matlab",
                                 haltOnFailure = True))
    # Upload swig+MATLAB
    factory.addStep(DirectoryUpload(slavesrc="dev/scripts/swig-MATLAB-temp",
                                    masterdest="public_html/nightly/swig+MATLAB/"+platform,
                                    url="nightly/swig+MATLAB/"+platform,
                                    compress="bz2"))
    return factory

def SWIG_scilab_bin_builder(platform, gitMode = 'incremental', windows = False):

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    # Build SWIG with scilab
    args = ["python","build_swig_scilab.py"]
    if windows:
        args += ['--windows']
        platform = 'windows'
    # Build SWIG with scilab
    factory.addStep(ShellCommand(command=' '.join(args),
                                 workdir= "build/dev/scripts",
                                 haltOnFailure = True))
    factory.addStep(MakeDirectory(dir='build/dev/scripts/swig-SCILAB-temp', haltOnFailure = True))
    # Zip up the directory that was generated using bzip
    factory.addStep(ShellCommand(command=' '.join(["7z","a","../swig-SCILAB-temp/swig_SCILAB.7z","swig-scilab-bin"]),
                                 workdir= "build/dev/scripts/swig-scilab",
                                 haltOnFailure = True))
    # Upload swig+scilab
    factory.addStep(DirectoryUpload(slavesrc="dev/scripts/swig-SCILAB-temp",
                                    masterdest="public_html/nightly/swig+SCILAB/"+platform,
                                    url="nightly/swig+SCILAB/"+platform,
                                    compress="bz2"))
    return factory

from buildbot.config import BuilderConfig

c['builders'] = []

# c['builders'].append(
#   BuilderConfig(name="sphinx pages",
#     slavenames=["linux32-slave"],
#     factory = website_factory(platform = 'linux')
#   )
# )

c['builders'].append(
    BuilderConfig(name="Debian package",
                  slavenames=["linux-slave"],
                  factory = deb_slave()
                  )
      )

c['builders'].append(
    BuilderConfig(name="Excel",
                  slavenames=["windows-slave"],
                  factory = excel_slave() ) )


c['builders'].append(
  BuilderConfig(
    name="Sphinx docs",
    slavenames=["linux32-slave"],
    factory = websiteFactory(platform = 'linux')
  )
)

c['builders'].append(
BuilderConfig(name="Javascript-linux",
              slavenames=["linux-slave"],
              factory = javascript_slave(platform = 'linux')
              )
  )
c['builders'].append(
    BuilderConfig(name="Python-sdist",
                  slavenames=["OSX-slave"],
                  factory = python_source_slave("PYPI", platform = 'OSX', conda_env = 'py27')
                  )
      )

# We centralise the Python builder configuration here
#
# Setting the appropriate installer options
relinstFolder = "../../install_root" # relative path
baseins = ['bdist_wheel', '--dist-dir', relinstFolder+'/Python']

windowsDTUslave = PythonSlaveConfig("windows-DTU-slave")
windowsDTUslave.pyact[getIDstr("windows", "32bit", 0     )] = "\"C:\\Program Files (x86)\\Miniconda32_27\\Scripts\\activate.bat\""
windowsDTUslave.pyact[getIDstr("windows", "64bit", 0     )] = "\"C:\\Program Files\\Miniconda64_27\\Scripts\\activate.bat\""
windowsDTUslave.pyenv[getIDstr("windows", 0      , "py27")] = "CoolProp27"
windowsDTUslave.pyenv[getIDstr("windows", 0      , "py33")] = "CoolProp33"
windowsDTUslave.pyenv[getIDstr("windows", 0      , "py34")] = "CoolProp34"
tmpins = baseins + ['bdist_wininst','--dist-dir', relinstFolder+'/Python']
windowsDTUslave.pyins[getIDstr("windows", "32bit", "py27")] = tmpins + ['--cmake-compiler', 'vc9' , '--cmake-bitness', '32']
windowsDTUslave.pyins[getIDstr("windows", "32bit", "py33")] = tmpins + ['--cmake-compiler', 'vc10', '--cmake-bitness', '32']
windowsDTUslave.pyins[getIDstr("windows", "32bit", "py34")] = tmpins + ['--cmake-compiler', 'vc10', '--cmake-bitness', '32']
windowsDTUslave.pyins[getIDstr("windows", "64bit", "py27")] = tmpins + ['--cmake-compiler', 'vc9' , '--cmake-bitness', '64']
windowsDTUslave.pyins[getIDstr("windows", "64bit", "py33")] = tmpins + ['--cmake-compiler', 'vc10', '--cmake-bitness', '64']
windowsDTUslave.pyins[getIDstr("windows", "64bit", "py34")] = tmpins + ['--cmake-compiler', 'vc10', '--cmake-bitness', '64']

linuxDTUslave = PythonSlaveConfig("linux32-slave")
linuxDTUslave.pyact[getIDstr(  "linux"  , "32bit", 0     )] = "source /home/jowr/miniconda/bin/activate"
linuxDTUslave.pyenv[getIDstr(  "linux"  , 0      , "py27")] = "CoolProp27"
linuxDTUslave.pyenv[getIDstr(  "linux"  , 0      , "py33")] = "CoolProp33"
linuxDTUslave.pyenv[getIDstr(  "linux"  , 0      , "py34")] = "CoolProp34"
linuxDTUslave.pyins[getIDstr(  "linux"  , "32bit", 0     )] = baseins

osxIANslave = PythonSlaveConfig("OSX-slave")
osxIANslave.pyact[getIDstr(  "osx"  , "64bit", 0     )] = "source activate"
osxIANslave.pyenv[getIDstr(  "osx"  , "64bit", "py27")] = "py27"
osxIANslave.pyenv[getIDstr(  "osx"  , "64bit", "py33")] = "py33"
osxIANslave.pyenv[getIDstr(  "osx"  , "64bit", "py34")] = "py34"
osxIANslave.pyins[getIDstr(  "osx"  , 0      , 0     )] = baseins

pythonSlaves = [windowsDTUslave, linuxDTUslave, osxIANslave]

for slave in pythonSlaves:
    for pyID in slave.getIDs():
        c['builders'].append(
          BuilderConfig(
            name="-".join(["Python", "binaries", getJobName(pyID)]),
            slavenames=[slave.name],
            factory = pythonFactory(pyID, pyCFG=slave, gitMode = 'incremental')
          )
        )

# # Enable multiple slaves for one build for load
# # balancing and backup purposes.
# # Note that the configuration has to be the same.
# pythonSlaves = [windowsDTUslave, windowsIANslave, linuxDTUslave]
# enabledIDs = {}
# for slave in pythonSlaves:
#     for pyID in slave.getIDs():
#         if pyID in enabledIDs:
#             enabledIDs[pyID].append(slave.name)
#         else:
#             enabledIDs[pyID] = [slave.name]
#
# for pyID in enabledIDs:
#     c['builders'].append(
#       BuilderConfig(
#         name="-".join(["Python", "binaries", getJobName(pyID)]),
#         slavenames=enabledIDs[pyID],
#         factory = pythonFactory(pyID, pyCFG=slave, gitMode = 'incremental')
#       )
#     )

windowsDTUslave.pyact[getIDstr("windows", "32bit", 0     )] = "\"C:\\Program Files (x86)\\Miniconda32_27\\Scripts\\activate.bat\""
windowsDTUslave.pyact[getIDstr("windows", "64bit", 0     )] = "\"C:\\Program Files\\Miniconda64_27\\Scripts\\activate.bat\""
windowsDTUslave.pyenv[getIDstr("windows", 0      , "py27")] = "CoolProp27"

#c['builders'].append(
#BuilderConfig(name="StaticLibrary-binaries-windows-32bit-MinGW-ExternC",
#			  slavenames=["windows-DTU-slave"],
#			  factory = cmakeFactory(cmake_args=[
#			  "-DCOOLPROP_EXTERNC_STATIC_LIBRARY=ON",
#			  "-G", "\"MinGW Makefiles\""],
#             install = False)
#			  )
#  )
c['builders'].append(
  BuilderConfig(
    name="Fortran-executable-windows-32bit-MinGW-ExternC",
	slavenames=["windows-DTU-slave"],
	factory = fortranFactory(platform=platformID["windows"])
	)
)
c['builders'].append(
  BuilderConfig(
    name="Fortran-executable-linux-32bit-GCC-ExternC",
	slavenames=["linux32-slave"],
	factory = fortranFactory(platform=platformID["linux"])
	)
)

#Common boring 64-bit modules for windows, linux and OSX
### OSX
for platform in ['OSX', 'linux', 'windows']:
    for wrapper in ['Java','Csharp','Octave','PHP','64BIT_SHARED_LIBRARY','STATIC_LIBRARY']:
        if wrapper == 'PHP' and platform != 'linux': continue # only build PHP on linux
        ctest_args, cmake_args = [], []
        if platform.startswith('windows'):
            ctest_args = ['-C', 'Release']
            if wrapper == 'Octave':
                cmake_args = ['-G', '"MinGW Makefiles"']
            else:
                cmake_args = ['-G', '"Visual Studio 10 2010 Win64"']
        c['builders'].append(
            BuilderConfig(name=wrapper + "-" + platform,
                          slavenames=[platform + "-slave"],
                          factory = cmake_slave(wrapper,
                                                platform = platform,
                                                ctest_args = ctest_args,
                                                cmake_args = cmake_args)
                          )
              )
    c['builders'].append(
    BuilderConfig(name="Catch-"+platform,
                  slavenames=[platform + "-slave"],
                  factory = cmake_slave('Catch', platform = platform, install=False)
                  )
      )

c['builders'].append(
  BuilderConfig(name="32bitDLL-OSX",slavenames=["OSX-slave"],
    factory = cmake_slave(
      '32BIT_SHARED_LIBRARY_LINUX',
      test = False,
      platform = 'OSX',
      cmake_args=['-DFORCE_BITNESS_32=ON'])
  )
)

c['builders'].append(
  BuilderConfig(name="32bitDLL-Linux",slavenames=["linux32-slave"],
    factory = cmake_slave(
      '32BIT_SHARED_LIBRARY_LINUX',
      test = False,
      platform = 'linux')
  )
)

c['builders'].append(
    BuilderConfig(name="32bitCdeclDLL-windows",
      slavenames=["windows-slave"],
      factory = cmake_slave('32BIT_CDECL_SHARED_LIBRARY',
                            test = False,
                            platform = 'windows',
                            cmake_args=['-G','"Visual Studio 10 2010"']
      )
      )
      )
c['builders'].append(
    BuilderConfig(name="32bitStdcallDLL-windows",
      slavenames=["windows-slave"],
      factory = cmake_slave('32BIT_STDCALL_SHARED_LIBRARY',
                            test = False,
                            platform = 'windows',
                            cmake_args=['-G','"Visual Studio 10 2010"']
      )
      )
      )
c['builders'].append(
    BuilderConfig(name="EES-windows",
      slavenames=["windows-slave"],
      factory = cmake_slave('EES',
                            platform = 'windows',
                            test = False,
                            cmake_args = ['-G','"Visual Studio 10 2010"'],
                            build_args = ['--config','Release'])
      )
      )

for platform in ['windows', 'linux', 'OSX']:
    cmake_args = []
    if platform == 'windows':
        cmake_args = ['-G', '"Visual Studio 10 2010 Win64"']
    c['builders'].append(BuilderConfig(name="MATLAB-"+platform, slavenames=[platform+"-slave"], factory = swig_matlab_builder(platform, cmake_args = cmake_args)))
    if platform == 'linux':
        c['builders'].append(BuilderConfig(name="Scilab-"+platform, slavenames=[platform+"-slave"], factory = swig_scilab_builder(platform)))
c['builders'].append(BuilderConfig(name="MATLAB-windows32",
                                   slavenames=["windows-slave"],
                                   factory = swig_matlab_builder('windows',
                                                                 cmake_env={'MATLAB_ROOT':'c:\Program Files (x86)\MATLAB\R2014a'},
                                                                 cmake_args = ['-G', '"Visual Studio 10 2010"'])))
cmake_env={
  'MATLAB_ROOT':'c:\Program Files\MatLabab R2014a',
  'MATLAB_INCLUDE_DIR':'',
  'MATLAB_MEX_LIBRARY':'',
  'MATLAB_MX_LIBRARY':''
  }

c['builders'].append(BuilderConfig(name="Matlab-binaries-windows-64bit-VS10", slavenames=["windows-DTU-slave"], factory = swig_matlab_builder("windows", cmake_env=cmake_env, cmake_args = ['-G', '"Visual Studio 10 2010 Win64"'])))
#c['builders'].append(BuilderConfig(name="Matlab-binaries-windows-32bit-VS10", slavenames=["windows-DTU-slave"], factory = swig_matlab_builder("windows", cmake_args = ['-G', '"Visual Studio 10 2010"'])))<commit_msg>Typo in master.cfg<commit_after># -*- python -*-
# ex: set syntax=python:

# This is a sample buildmaster config file. It must be installed as
# 'master.cfg' in your buildmaster's base directory.

# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}

####### BUILDSLAVES

# The 'slaves' list defines the set of recognized buildslaves. Each element is
# a BuildSlave object, specifying a unique slave name and password.  The same
# slave name and password must be configured on the slave.
from buildbot.buildslave import BuildSlave
from buildbot_private import pass_dict
c['slaves'] = [BuildSlave("linux-slave", pass_dict["linux-slave"], max_builds = 1),
               BuildSlave("OSX-slave", pass_dict["OSX-slave"], max_builds = 1),
               BuildSlave("windows-slave", pass_dict["windows-slave"], max_builds = 1),
               BuildSlave("linux32-slave", pass_dict["linux32-slave"], max_builds = 1),
               BuildSlave("windows-DTU-slave", pass_dict["windows-DTU-slave"], max_builds = 1)
               ]

# 'slavePortnum' defines the TCP port to listen on for connections from slaves.
# This must match the value configured into the buildslaves (with their
# --master option)
c['slavePortnum'] = 9989

####### CHANGESOURCES

# the 'change_source' setting tells the buildmaster how it should find out
# about source code changes.  Here we point to the CoolProp source code.

from buildbot.changes.gitpoller import GitPoller
c['change_source'] = []
c['change_source'].append(GitPoller(
        'https://github.com/CoolProp/CoolProp',
        workdir='gitpoller-workdir', branch='master',
        pollinterval=300)) # Interval between triggering a build

####### BUILDERS

# The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
# what steps, and which slaves can execute them.  Note that any particular build will
# only take place on one slave.

from buildbot.process.factory import BuildFactory
from buildbot.steps.source.git import Git
from buildbot.steps.shell import ShellCommand
from buildbot.steps.slave import MakeDirectory, RemoveDirectory, CopyDirectory
from buildbot.steps.transfer import DirectoryUpload, FileDownload
from buildbot.process import properties

"""
from http://ss64.com/nt/del.html
deltree.cmd script, save it somewhere on the system PATH on windows
:: DelTree.cmd
:: Remove all files and subfolders but NOT the root folder
:: From tip 617 at JsiFAQ.com
@echo off
if "%1"=="" goto:eof
pushd %1
del /q *.*
for /f "Tokens=*" %%G in ('dir /B') do rd /s /q "%%G"
popd
"""

@properties.renderer
def cleanCommand(props):

    fullclean = props.getProperty('fullclean', default = False)
    is_windows = props.getProperty('slavename').find('windows') >= 0

    if fullclean:
        if is_windows:
            command = ' '.join(['deltree','.','&&','echo','fully cleaned'])
        else:
            command = ' '.join(['rm','-rfv','*','&&','echo','fully cleaned'])
    else:
        command = ['echo','no clean requested;', 'fullclean:', props.getProperty('fullclean')]
    return command

# A custom platform and Python identifiers
platformID = {
    "windows" : 1,
    "osx"     : 2,
    "linux"   : 3
    }

bitnessID = {
    "32bit" : 1,
    "64bit" : 2
    }

pythonID = {
    "py27" : 1,
    "py32" : 2,
    "py33" : 3,
    "py34" : 4
    }

# A couple of functions to make it simpler to use the shorthand notation for the
# different platform, bitness, python combinations. These functions are candidates
# for the most inefficient code written in 2014, but they make the rest of this
# config file so much nicer and shorter.
def getIDtuple(testID):
    platformTEST = None
    bitnessTEST  = None
    pythonTEST   = None
    #
    TEST = str(testID)
    i    = len(TEST)
    if i <  1: raise ValueError("The given testID \"{0}\" is too short.".format(TEST))
    if i >= 1: platformTEST = TEST[0]
    if i >= 2: bitnessTEST  = TEST[1]
    if i >= 3: pythonTEST   = TEST[2]
    if i > 3: raise ValueError("The given testID \"{0}\" is too long.".format(TEST))
    #
    return platformTEST, bitnessTEST, pythonTEST

def getIDstr(platform=None, bitness=None, python=None):
    if platform is None and bitness is None and python is None:
        raise ValueError("All given parameters are None, this does not work.")
    #
    def getIDstr_helper(input, alt):
        if input is None: return str(0)
        if str(input) == "0": return str(0)
        if input in alt: return str(alt[input])
        return str(int(input))
    #
    platform = getIDstr_helper(platform,platformID)
    bitness  = getIDstr_helper(bitness,bitnessID)
    python   = getIDstr_helper(python,pythonID)
    #
    return platform+bitness+python

def compareID(in1, in2):
    """Takes int or str data and compares it to the other input.
    0 can be used ad a joker, which always compares to True.
    """
    if   in1 is None or   in2 is None : return True
    if int(in1) == 0 or int(in2) == 0 : return True
    return int(in1) == int(in2)

def checkID(inID, teID=None, strict=True):
    platformIN, bitnessIN, pythonIN = getIDtuple(testID=inID)
    platformTE, bitnessTE, pythonTE = getIDtuple(testID=teID)
    #
    result = compareID(platformTE, platformIN)
    if not result and strict: raise ValueError("The given input for the platform \"{0}\" did not match \"{1}\"".format(platformIN,platformTE))
    result =  compareID(bitnessTE, bitnessIN) and result
    if not result and strict: raise ValueError("The given input for the bitness \"{0}\" did not match \"{1}\"".format(bitnessIN,bitnessTE))
    result =   compareID(pythonTE, pythonIN) and result
    if not result and strict: raise ValueError("The given input for the Python version \"{0}\" did not match \"{1}\"".format(pythonIN,pythonTE))
    return result

def getFromDict(inDict, inID):
    res = inDict.get(inID)
    if res is None: # Try some more
        for key in inDict:
            if checkID(inID, key, strict=False):
                if res is not None:
                    raise ValueError("Already found a matching entry \"{0}\" for \"{1}\", please specify more parameters.".format(res,inID))
                else:
                    res = inDict[key]
    if res is None:
        raise ValueError("Could not find a matching entry for \"{0}\".".format(inID))
    else:
        return res

def getKeyFromVal(dic,val):
    for key in dic:
        if str(dic[key])==str(val):
            return key
    return None

def getJobName(inID):
    platform, bitness, python = getIDtuple(inID)
    platform = getKeyFromVal(platformID, platform)
    bitness  = getKeyFromVal( bitnessID, bitness )
    python   = getKeyFromVal(  pythonID, python  )
    res = []
    if platform is not None: res.append(platform)
    if  bitness is not None: res.append(bitness)
    if   python is not None: res.append(python)
    return "-".join(res)


class PythonSlaveConfig(object):
    def __init__(self,name):
        self.name = name
        self.pyact = {}
        self.pyenv = {}
        self.pyins = {}

    def getPyact(self, inID):
        return getFromDict(self.pyact, inID)

    def getPyenv(self, inID):
        return getFromDict(self.pyenv, inID)

    def getPyins(self, inID):
        return getFromDict(self.pyins, inID)

    def getIDs(self):
        IDs = []
        for pl in platformID:
            for bi in bitnessID:
                for py in pythonID:
                    tmpID = getIDstr(pl, bi, py)
                    try:
                        #print "Testing for {0} in act".format(tmpID)
                        self.getPyact(tmpID)
                        #print "Testing for {0} in env".format(tmpID)
                        self.getPyenv(tmpID)
                        #print "Testing for {0} in ins".format(tmpID)
                        self.getPyins(tmpID)
                        #print "Appending {0}".format(tmpID)
                        IDs.append(tmpID)
                    except:
                        pass
        return IDs


# A centralised method to provide the objects with some presets
def getBaseFactory(gitMode = 'incremental'):
    factory = BuildFactory()
    factory.addStep(ShellCommand(command=cleanCommand, description='fullclean?', workdir=""))
    factory.addStep(Git(repourl='git://github.com/CoolProp/CoolProp', mode=gitMode, submodules = True, progress=True, haltOnFailure = True))
    return factory


# All what is needed to create the website, it makes sense to run the
# nightly builds on the same machine. This avoids extra data transfer.
def websiteFactory(platform, gitMode='incremental', fullBuild=False):
    if 'win' in platform.lower():
        raise ValueError("The docs cannot be build on a Windows machine, we rely on rsync...")
    # Some basic preparations
    server_uri = '<EMAIL>.dreamhosters.com'
    server_dir = '/home/coolprop/buildbot/server-master'
    server_des = "{0}:{1}".format(server_uri,server_dir)
    #
    local_build_dir = 'Web/_build/html'
    server_target_dir = '{0}/public_html/sphinx'.format(server_des)
    #
    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    # Install the latest CoolProp
    factory.addStep(ShellCommand(command=["python", "setup.py", "install"], workdir= 'build/wrappers/Python', haltOnFailure = True))
    # Create plots and fluid tables
    if fullBuild:
        factory.addStep(ShellCommand(command=["python", "__init__.py", "True"], workdir= 'build/Web/scripts', haltOnFailure = True))
    else:
        factory.addStep(ShellCommand(command=["python", "__init__.py", "False"], workdir= 'build/Web/scripts', haltOnFailure = True))
    # Run sphinx build
    factory.addStep(ShellCommand(command=["python", "-c", "\"import CoolProp; print(CoolProp.__file___)\""], workdir= 'build/wrappers/Python', haltOnFailure = True))
    # Run doxygen build
    factory.addStep(ShellCommand(command=' '.join(["doxygen","Doxyfile"]), workdir= 'build', haltOnFailure = True))
    # Run sphinx apidoc
    #factory.addStep(ShellCommand(command=["sphinx-apidoc","-T","-f","-o","apidoc","../CoolProp"],workdir= 'build/Web', haltOnFailure = True))
    # Run sphinx website builder
    factory.addStep(ShellCommand(command=["make", "html"], workdir= 'build/Web', haltOnFailure = True))
    # Upload the generated files
    factory.addStep(ShellCommand(command = 'rsync -a --stats {0}/ {1}'.format(local_build_dir,server_target_dir), haltOnFailure = True))
    return factory


# The reworked Python builder factory. It relies on Miniconda and can handle both 32bit and 64bit builds
# Currently, it only supports Windows, but the plan is to integrate MacOS and Linux builds here as well.
# You have to have both CMake and Git available on your standard command line, pay attention when installing
# these two tools on your Windows machine.
def pythonFactory(pyID, pyCFG=PythonSlaveConfig("name"), gitMode='incremental'):
    #
    # Some basic settings for all builders
    workingFolder = "build/wrappers/Python"
    installFolder = "build/install_root"
    relinstFolder = "../../install_root" # relative path
    uploadFolder  = "install_root" # relative to build
    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    # Remove the temporary folder for installs
    factory.addStep(RemoveDirectory(dir=installFolder, haltOnFailure = True))
    #
    # Setting the appropriate virtual environment activator
    pyact = pyCFG.getPyact(pyID)
    # Setting the appropriate virtual environment
    pyenv = pyCFG.getPyenv(pyID)
    # Setting the appropriate installer options
    pyins = pyCFG.getPyins(pyID)
    # Getting the appropriate virtual environment activator
    if pyact is None:
        raise ValueError("Your selected Python installation \"{0}\" is not supported by this builder factory".format(pyID))
    # Getting the appropriate virtual environment
    if pyenv is None:
        raise ValueError("Your selected Python environment \"{0}\" is not supported by this builder factory".format(pyID))
    # Getting the appropriate installer options
    if pyins is None:
        raise ValueError("Your selected Python environment \"{0}\" does not have installer options in this builder factory".format(pyID))
    #
    activateCMD =  " ".join([pyact, pyenv]) # We always activate an environment, regardless of the host
    installCMD  =  " ".join(["python", "setup.py"] + pyins)
    combinedCMD = " && ".join([activateCMD, installCMD])
    factory.addStep(ShellCommand(command = combinedCMD, workdir = workingFolder, haltOnFailure = True))
    #
    factory.addStep(DirectoryUpload(slavesrc=uploadFolder, masterdest="public_html/binaries", url="binaries", compress="bz2"))
    return factory


def cmakeFactory(mod_name = None, gitMode = 'incremental', install = True, pre_cmd = [], cmake_args = [], build_args = [], ctest_args = [], cmake_env={}, test = True):
    """
    Parameters
    ----------
    mod_name: string
        The module to be built, one of 'Octave','python','Csharp', etc. - turns on the macro -DCOOLPROP_OCTAVE_MODULE=ON for instance if you pass octave
    gitMode: string
        What mode to use, one of 'incremental' or 'full'
    install: bool
        True for install, False for just build
    pre_cmd: list of strings
        List of strings of commands to be executed before the cmake command, gets merged with &&
    cmake_args: list of strings
        List of strings of arguments to be passed to cmake (Makefile generating) step
    cmake_env: dictionary (string->string)
        A dictionary including keys that can be set in the build environment
    build_args: list of strings
        List of strings of arguments to be passed to cmake install or build command depending on value of install
    ctest_args: list of strings
        List of strings of arguments to be passed to ctest
    """
    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    #
    factory.addStep(MakeDirectory(dir=working_folder, haltOnFailure = True))
    factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))
    #
    if len(pre_cmd)>0 and not pre_cmd[-1]=="&&": pre_cmd.append("&&")
    if mod_name is not None:
        cmake_args = ["-DCOOLPROP_"+mod_name.upper()+"_MODULE=ON","-DBUILD_TESTING=ON"]+cmake_args

    cmakeCMD = pre_cmd + ["cmake", ".."]+cmake_args
    factory.addStep(ShellCommand(
      command=' '.join(cmakeCMD),
      env = cmake_env,
      workdir= working_folder,
      haltOnFailure = True))
    #
    if install: installCMD = ["--target", "install"]
    else: installCMD = []
    factory.addStep(ShellCommand(
      command=' '.join(pre_cmd+["cmake", "--build", "."]+installCMD+build_args),
      workdir = working_folder,
      haltOnFailure = True))
    #
    if test:
        factory.addStep(ShellCommand(
          command=["ctest", "--extra-verbose"] + ctest_args,
          workdir = working_folder,
          haltOnFailure = True))
    #
    if install:
        factory.addStep(DirectoryUpload(
          slavesrc="install_root",
          masterdest="public_html/binaries",
          url="binaries",
          compress="bz2"))
    return factory


def fortranFactory(platform=1):
    working_folder = "build/build" # Same as in cmakeFactory
    fortran_folder = "build/wrappers/Fortran/detailed_example" #
    #
    if platform==platformID["windows"]:
        cmake_args = ["-DCOOLPROP_EXTERNC_STATIC_LIBRARY=ON","-G", "\"MinGW Makefiles\""]
        cp_cmd     = "copy /Y *.f90 ..\\..\\..\\build"
        build_cmd  = "gfortran -c -Wall cpinterface.f90 cool_fortran_bind.f90"
        link_cmd   = "gfortran -o main *.o libCoolProp.a -lstdc++"
        exec_cmd   = "main"
    elif platform==platformID["linux"]:
        cmake_args = ["-DCOOLPROP_EXTERNC_STATIC_LIBRARY=ON"]
        cp_cmd     = "cp *.f90 ../../../build/"
        build_cmd  = "gfortran -c -Wall cpinterface.f90 cool_fortran_bind.f90"
        link_cmd   = "gfortran -o main *.o libCoolProp.a -lstdc++ -ldl"
        exec_cmd   = "./main"
    else:
        raise ValueError("Unknown Fortran platform: {0}".format(platform))

    # Create the factory to add the actions to
    factory = cmakeFactory(cmake_args=cmake_args,install=False,test=False)
    #
    #factory.addStep(CopyDirectory(src=fortran_folder, dest=working_folder))
    factory.addStep(ShellCommand(command=cp_cmd,  workdir = fortran_folder, haltOnFailure = True))
    for cmd in [build_cmd,link_cmd,exec_cmd]:
        factory.addStep(ShellCommand(command=cmd, workdir = working_folder, haltOnFailure = True))
    return factory


def javascript_slave(platform, cmake_args = [], cmake_env = {}, build_args = [], gitMode = 'incremental'):

    working_folder = "build/Javascript"
    from buildbot.process.properties import WithProperties

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)

    # Remove the temporary folder for installs
    factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))

    factory.addStep(ShellCommand(command="cmake .. -DCOOLPROP_JAVASCRIPT_MODULE=ON -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Platform/Emscripten.cmake",
                                 workdir= working_folder,
                                 haltOnFailure = True))
    factory.addStep(ShellCommand(command=["cmake", "--build", ".", "--target", "install"]+build_args, workdir = working_folder, haltOnFailure = True))
    factory.addStep(DirectoryUpload(slavesrc="install_root", masterdest="public_html/binaries", url="binaries", compress="bz2"))

    return factory

def python_source_slave(key, platform, conda_env, cmake_args = [], cmake_env = {}, build_args = [], gitMode = 'incremental'):
    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)

    # Remove the temporary folder for installs
    factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))
    factory.addStep(MakeDirectory(dir=working_folder, haltOnFailure = True))

    factory.addStep(ShellCommand(command = ' '.join(['source',"activate",conda_env,"&&","cmake", "..", "-DCOOLPROP_PYTHON_PYPI=ON","&&","cmake","--build",".","--target","CoolProp"]+cmake_args),
                                 env = cmake_env,
                                 workdir= working_folder,
                                 haltOnFailure = True))
    factory.addStep(DirectoryUpload(slavesrc="install_root", masterdest="public_html/binaries", url="binaries", compress="bz2"))
    return factory

def deb_slave(gitMode = 'incremental'):

    working_folder = "build/wrappers/DEB"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)

    factory.addStep(ShellCommand(command = ' '.join(["chmod","+x","package.bsh","&&", "./package.bsh"]),
                                 workdir= working_folder,
                                 haltOnFailure = True))
    factory.addStep(MakeDirectory(dir=working_folder+'/DEB/DEB', haltOnFailure = True))
    factory.addStep(ShellCommand(command = ' '.join(["mv","*.deb","DEB/DEB"]),
                                 workdir= working_folder,
                                 haltOnFailure = True))
    factory.addStep(DirectoryUpload(slavesrc="wrappers/DEB/DEB", masterdest="public_html/binaries", url="binaries/DEB", compress="bz2"))

    return factory

def excel_slave(gitMode = 'incremental'):
    """
    """
    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    #
    factory.addStep(MakeDirectory(dir=working_folder+'/32bitDLL', haltOnFailure = True))
    factory.addStep(MakeDirectory(dir=working_folder+'/64bitDLL', haltOnFailure = True))
    factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))
    # Make 32-bit __stdcall DLL
    factory.addStep(ShellCommand(command=["cmake", "../..", "-DCOOLPROP_32BIT_STDCALL_SHARED_LIBRARY=ON","-G", "Visual Studio 10"],
                                 workdir= working_folder+'/32bitDLL',
                                 haltOnFailure = True))
    factory.addStep(ShellCommand(command=["cmake", "--build", ".", "--target", "install"], workdir = working_folder+'/32bitDLL', haltOnFailure = True))
    # Make 64-bit DLL
    factory.addStep(ShellCommand(command=["cmake", "../..", "-DCOOLPROP_64BIT_SHARED_LIBRARY=ON","-G", "Visual Studio 10 Win64"],
                                 workdir= working_folder+'/64bitDLL',
                                 haltOnFailure = True))
    factory.addStep(ShellCommand(command=["cmake", "--build", ".", "--target", "install"], workdir = working_folder+'/64bitDLL', haltOnFailure = True))

    factory.addStep(MakeDirectory(dir='build\\bin\\MicrosoftExcel', haltOnFailure = True))
    # Copy the created DLL
    factory.addStep(ShellCommand(command=' '.join(["copy", "/Y", "install_root\\shared_library\\Windows\\32bit__stdcall_calling_convention\\*.dll", "bin\\MicrosoftExcel"]), workdir = 'build', haltOnFailure = True))
    factory.addStep(ShellCommand(command=' '.join(["move", "CoolProp.dll", "CoolProp_x64.dll"]), workdir = 'build/install_root/shared_library/Windows/64bit', haltOnFailure = True))
    factory.addStep(ShellCommand(command=' '.join(["copy", "/Y", "install_root\\shared_library\\Windows\\64bit\\*.dll", "bin\\MicrosoftExcel"]), workdir = 'build', haltOnFailure = True))
    # Copy other files
    factory.addStep(ShellCommand(command=["copy", "wrappers\Excel\CoolProp.xlam", "bin\MicrosoftExcel"], workdir = 'build', haltOnFailure = True))
    factory.addStep(ShellCommand(command=["copy", "wrappers\Excel\CoolProp.xla", "bin\MicrosoftExcel"], workdir = 'build', haltOnFailure = True))
    factory.addStep(ShellCommand(command=["copy", "wrappers\Excel\TestExcel.xlsx", "bin\MicrosoftExcel"], workdir = 'build', haltOnFailure = True))
    # Upload the files
    factory.addStep(DirectoryUpload(slavesrc="bin",masterdest="public_html/binaries",url="MicrosoftExcel",compress="bz2"))
    return factory

def cmake_slave(mod_name, platform, gitMode = 'incremental', install = True, cmake_args = [], build_args = [], ctest_args = [], cmake_env={}, test = True):
    """
    Parameters
    ----------
    mod_name: string
        The module to be built, one of 'Octave','python','Csharp', etc. - turns on the macro -DCOOLPROP_OCTAVE_MODULE=ON for instance if you pass octave
    gitMode: string
        What mode to use, one of 'incremental' or 'full'
    install: bool
        True for install, False for just build
    cmake_args: list of strings
        List of strings of arguments to be passed to cmake (Makefile generating) step
    cmake_env: dictionary (string->string)
        A dictionary including keys that can be set in the build environment
    build_args: list of strings
        List of strings of arguments to be passed to cmake install or build command depending on value of install
    ctest_args: list of strings
        List of strings of arguments to be passed to ctest
    """
    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    #
    factory.addStep(MakeDirectory(dir=working_folder, haltOnFailure = True))
    factory.addStep(RemoveDirectory(dir="build/install_root", haltOnFailure = True))
    if mod_name.lower() == 'octave' and platform.lower() == 'windows':
        pre = ['set','"PATH=%OCTAVE_ROOT%/bin;%PATH%"','&&']
    else:
        pre = []
    factory.addStep(ShellCommand(command=' '.join(pre+["cmake", "..", "-DCOOLPROP_"+mod_name.upper()+"_MODULE=ON","-DBUILD_TESTING=ON"]+cmake_args),
                                 env = cmake_env,
                                 workdir= working_folder,
                                 haltOnFailure = True))
    if install:
        factory.addStep(ShellCommand(command=' '.join(pre+["cmake", "--build", ".", "--target", "install"]+build_args), workdir = working_folder, haltOnFailure = True))
    else:
        factory.addStep(ShellCommand(command=' '.join(pre+["cmake", "--build", "."]+build_args), workdir = working_folder, haltOnFailure = True))
    if test:
        factory.addStep(ShellCommand(command=["ctest", "--extra-verbose"] + ctest_args, workdir = working_folder, haltOnFailure = True))
    if install:
        factory.addStep(DirectoryUpload(slavesrc="install_root",masterdest="public_html/binaries",url="binaries",compress="bz2"))
    return factory

def swig_matlab_builder(platform, gitMode = 'incremental', cmake_args = [], cmake_env = None):
    """
    Download SWIG+MATLAB version, use it to build _wrap file for MATLAB builder, upload generated file back to master.

    These generated files are needed for the other swig builders and are cross-platform
    """

    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    #
    # Download files from nightly build for swig
    factory.addStep(FileDownload(mastersrc = 'public_html/nightly/swig+MATLAB/'+platform+'/swig_MATLAB.7z', slavedest = 'swig_MATLAB.7z', haltOnFailure = True))
    # Directory for build
    factory.addStep(MakeDirectory(dir='build/build', haltOnFailure = True))
    # Unzip
    if platform == 'windows':
        factory.addStep(ShellCommand(command = 'set PATH=C:\\Program Files\\7-Zip\\;%PATH% && 7z -y -obuild x swig_MATLAB.7z', workdir = 'build', haltOnFailure = True))
    else:
        factory.addStep(ShellCommand(command =                                               '7z -y -obuild x swig_MATLAB.7z', workdir = 'build', haltOnFailure = True))

    if platform == 'windows':
        command = ["set", '"PATH=swig-matlab-bin\\bin;%PATH%"', "&&", "cmake", "..", "-DCOOLPROP_MATLAB_SWIG_MODULE=ON","-DSWIG_DIR=swig-matlab-bin/bin"] + cmake_args
    else:
        command = ["PATH=swig-matlab-bin/bin:${PATH}",                "cmake", "..", "-DCOOLPROP_MATLAB_SWIG_MODULE=ON","-DSWIG_DIR=swig-matlab-bin/bin"] + cmake_args

    factory.addStep(ShellCommand(command=' '.join(command),
                                 workdir= "build/build",
                                 env = cmake_env,
                                 haltOnFailure = True))
    if platform == 'windows':
        command = ["set", '"SWIG_LIB=swig-matlab-bin\\share\\swig\\3.0.3"', "&&", "cmake", "--build", ".", "--target", "install"]
    else:
        command = ["SWIG_LIB=swig-matlab-bin/share/swig/3.0.3", "cmake", "--build", ".", "--target", "install"]
    factory.addStep(ShellCommand(command=' '.join(command),
                                 workdir= "build/build",
                                 haltOnFailure = True))
    # Upload the files
    factory.addStep(DirectoryUpload(slavesrc="install_root",masterdest="public_html/binaries",url="binaries",compress="bz2"))
    return factory

def swig_scilab_builder(platform, gitMode = 'incremental'):
    """
    Download SWIG+scilab version on linux, use it to build _wrap file for scilab builder, upload generated file(s) back to master.

    These generated files are needed for the other swig builders and are cross-platform
    """

    working_folder = "build/build"

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    #
    # Download files from nightly build for swig
    factory.addStep(FileDownload(mastersrc = 'public_html/nightly/swig+SCILAB/'+platform+'/swig_SCILAB.7z', slavedest = 'swig_SCILAB.7z', haltOnFailure = True))
    # Directory for build
    factory.addStep(MakeDirectory(dir='build/build', haltOnFailure = True))
    # Unzip
    factory.addStep(ShellCommand(command = '7z -y -obuild x swig_SCILAB.7z', workdir = 'build', haltOnFailure = True))
    if platform == 'windows':
        command = ["set", '"PATH=swig-scilab-bin\\bin;%PATH%"', "&&", "cmake", "..", "-DCOOLPROP_SCILAB_SWIG_MODULE=ON","-DSWIG_DIR=swig-scilab-bin"]
    else:
        command = ["PATH=swig-scilab-bin/bin:${PATH}","cmake", "..", "-DCOOLPROP_SCILAB_SWIG_MODULE=ON","-DSWIG_DIR=swig-scilab-bin"]
    factory.addStep(ShellCommand(command=' '.join(command),
                                 workdir= "build/build",
                                 haltOnFailure = True))
    if platform == 'windows':
        command = ["set", '"SWIG_LIB=swig-scilab-bin\\share\\swig\\3.0.2"', "&&", "cmake", "--build", ".", "--target", "install"]
    else:
        command = ["SWIG_LIB=swig-scilab-bin/share/swig/3.0.2", "cmake", "--build", ".", "--target", "install"]
    factory.addStep(ShellCommand(command=' '.join(command),
                                 workdir= "build/build",
                                 haltOnFailure = True))
    # Upload the files
    factory.addStep(DirectoryUpload(slavesrc="install_root",masterdest="public_html/binaries",url="binaries",compress="bz2"))
    return factory

def SWIG_MATLAB_bin_builder(platform, gitMode = 'incremental', windows = False):

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    # Build SWIG with MATLAB
    args = ["python","build_swig_matlab.py"]
    if windows:
        args += ['--windows']
        platform = 'windows'
    factory.addStep(ShellCommand(command=' '.join(args),
                                 workdir= "build/dev/scripts",
                                 haltOnFailure = True))
    factory.addStep(MakeDirectory(dir='build/dev/scripts/swig-MATLAB-temp', haltOnFailure = True))
    # Zip up the directory that was generated using bzip
    factory.addStep(ShellCommand(command=' '.join(["7z","a","../swig-MATLAB-temp/swig_MATLAB.7z","swig-matlab-bin"]),
                                 workdir= "build/dev/scripts/swig-matlab",
                                 haltOnFailure = True))
    # Upload swig+MATLAB
    factory.addStep(DirectoryUpload(slavesrc="dev/scripts/swig-MATLAB-temp",
                                    masterdest="public_html/nightly/swig+MATLAB/"+platform,
                                    url="nightly/swig+MATLAB/"+platform,
                                    compress="bz2"))
    return factory

def SWIG_scilab_bin_builder(platform, gitMode = 'incremental', windows = False):

    # Create the factory to add the actions to
    factory = getBaseFactory(gitMode=gitMode)
    # Build SWIG with scilab
    args = ["python","build_swig_scilab.py"]
    if windows:
        args += ['--windows']
        platform = 'windows'
    # Build SWIG with scilab
    factory.addStep(ShellCommand(command=' '.join(args),
                                 workdir= "build/dev/scripts",
                                 haltOnFailure = True))
    factory.addStep(MakeDirectory(dir='build/dev/scripts/swig-SCILAB-temp', haltOnFailure = True))
    # Zip up the directory that was generated using bzip
    factory.addStep(ShellCommand(command=' '.join(["7z","a","../swig-SCILAB-temp/swig_SCILAB.7z","swig-scilab-bin"]),
                                 workdir= "build/dev/scripts/swig-scilab",
                                 haltOnFailure = True))
    # Upload swig+scilab
    factory.addStep(DirectoryUpload(slavesrc="dev/scripts/swig-SCILAB-temp",
                                    masterdest="public_html/nightly/swig+SCILAB/"+platform,
                                    url="nightly/swig+SCILAB/"+platform,
                                    compress="bz2"))
    return factory

from buildbot.config import BuilderConfig

c['builders'] = []

# c['builders'].append(
#   BuilderConfig(name="sphinx pages",
#     slavenames=["linux32-slave"],
#     factory = website_factory(platform = 'linux')
#   )
# )

c['builders'].append(
    BuilderConfig(name="Debian package",
                  slavenames=["linux-slave"],
                  factory = deb_slave()
                  )
      )

c['builders'].append(
    BuilderConfig(name="Excel",
                  slavenames=["windows-slave"],
                  factory = excel_slave() ) )


c['builders'].append(
  BuilderConfig(
    name="Sphinx docs",
    slavenames=["linux32-slave"],
    factory = websiteFactory(platform = 'linux')
  )
)

c['builders'].append(
BuilderConfig(name="Javascript-linux",
              slavenames=["linux-slave"],
              factory = javascript_slave(platform = 'linux')
              )
  )
c['builders'].append(
    BuilderConfig(name="Python-sdist",
                  slavenames=["OSX-slave"],
                  factory = python_source_slave("PYPI", platform = 'OSX', conda_env = 'py27')
                  )
      )

# We centralise the Python builder configuration here
#
# Setting the appropriate installer options
relinstFolder = "../../install_root" # relative path
baseins = ['bdist_wheel', '--dist-dir', relinstFolder+'/Python']

windowsDTUslave = PythonSlaveConfig("windows-DTU-slave")
windowsDTUslave.pyact[getIDstr("windows", "32bit", 0     )] = "\"C:\\Program Files (x86)\\Miniconda32_27\\Scripts\\activate.bat\""
windowsDTUslave.pyact[getIDstr("windows", "64bit", 0     )] = "\"C:\\Program Files\\Miniconda64_27\\Scripts\\activate.bat\""
windowsDTUslave.pyenv[getIDstr("windows", 0      , "py27")] = "CoolProp27"
windowsDTUslave.pyenv[getIDstr("windows", 0      , "py33")] = "CoolProp33"
windowsDTUslave.pyenv[getIDstr("windows", 0      , "py34")] = "CoolProp34"
tmpins = baseins + ['bdist_wininst','--dist-dir', relinstFolder+'/Python']
windowsDTUslave.pyins[getIDstr("windows", "32bit", "py27")] = tmpins + ['--cmake-compiler', 'vc9' , '--cmake-bitness', '32']
windowsDTUslave.pyins[getIDstr("windows", "32bit", "py33")] = tmpins + ['--cmake-compiler', 'vc10', '--cmake-bitness', '32']
windowsDTUslave.pyins[getIDstr("windows", "32bit", "py34")] = tmpins + ['--cmake-compiler', 'vc10', '--cmake-bitness', '32']
windowsDTUslave.pyins[getIDstr("windows", "64bit", "py27")] = tmpins + ['--cmake-compiler', 'vc9' , '--cmake-bitness', '64']
windowsDTUslave.pyins[getIDstr("windows", "64bit", "py33")] = tmpins + ['--cmake-compiler', 'vc10', '--cmake-bitness', '64']
windowsDTUslave.pyins[getIDstr("windows", "64bit", "py34")] = tmpins + ['--cmake-compiler', 'vc10', '--cmake-bitness', '64']

linuxDTUslave = PythonSlaveConfig("linux32-slave")
linuxDTUslave.pyact[getIDstr(  "linux"  , "32bit", 0     )] = "source /home/jowr/miniconda/bin/activate"
linuxDTUslave.pyenv[getIDstr(  "linux"  , 0      , "py27")] = "CoolProp27"
linuxDTUslave.pyenv[getIDstr(  "linux"  , 0      , "py33")] = "CoolProp33"
linuxDTUslave.pyenv[getIDstr(  "linux"  , 0      , "py34")] = "CoolProp34"
linuxDTUslave.pyins[getIDstr(  "linux"  , "32bit", 0     )] = baseins

osxIANslave = PythonSlaveConfig("OSX-slave")
osxIANslave.pyact[getIDstr(  "osx"  , "64bit", 0     )] = "source activate"
osxIANslave.pyenv[getIDstr(  "osx"  , "64bit", "py27")] = "py27"
osxIANslave.pyenv[getIDstr(  "osx"  , "64bit", "py33")] = "py33"
osxIANslave.pyenv[getIDstr(  "osx"  , "64bit", "py34")] = "py34"
osxIANslave.pyins[getIDstr(  "osx"  , 0      , 0     )] = baseins

pythonSlaves = [windowsDTUslave, linuxDTUslave, osxIANslave]

for slave in pythonSlaves:
    for pyID in slave.getIDs():
        c['builders'].append(
          BuilderConfig(
            name="-".join(["Python", "binaries", getJobName(pyID)]),
            slavenames=[slave.name],
            factory = pythonFactory(pyID, pyCFG=slave, gitMode = 'incremental')
          )
        )

# # Enable multiple slaves for one build for load
# # balancing and backup purposes.
# # Note that the configuration has to be the same.
# pythonSlaves = [windowsDTUslave, windowsIANslave, linuxDTUslave]
# enabledIDs = {}
# for slave in pythonSlaves:
#     for pyID in slave.getIDs():
#         if pyID in enabledIDs:
#             enabledIDs[pyID].append(slave.name)
#         else:
#             enabledIDs[pyID] = [slave.name]
#
# for pyID in enabledIDs:
#     c['builders'].append(
#       BuilderConfig(
#         name="-".join(["Python", "binaries", getJobName(pyID)]),
#         slavenames=enabledIDs[pyID],
#         factory = pythonFactory(pyID, pyCFG=slave, gitMode = 'incremental')
#       )
#     )

windowsDTUslave.pyact[getIDstr("windows", "32bit", 0     )] = "\"C:\\Program Files (x86)\\Miniconda32_27\\Scripts\\activate.bat\""
windowsDTUslave.pyact[getIDstr("windows", "64bit", 0     )] = "\"C:\\Program Files\\Miniconda64_27\\Scripts\\activate.bat\""
windowsDTUslave.pyenv[getIDstr("windows", 0      , "py27")] = "CoolProp27"

#c['builders'].append(
#BuilderConfig(name="StaticLibrary-binaries-windows-32bit-MinGW-ExternC",
#			  slavenames=["windows-DTU-slave"],
#			  factory = cmakeFactory(cmake_args=[
#			  "-DCOOLPROP_EXTERNC_STATIC_LIBRARY=ON",
#			  "-G", "\"MinGW Makefiles\""],
#             install = False)
#			  )
#  )
c['builders'].append(
  BuilderConfig(
    name="Fortran-executable-windows-32bit-MinGW-ExternC",
	slavenames=["windows-DTU-slave"],
	factory = fortranFactory(platform=platformID["windows"])
	)
)
c['builders'].append(
  BuilderConfig(
    name="Fortran-executable-linux-32bit-GCC-ExternC",
	slavenames=["linux32-slave"],
	factory = fortranFactory(platform=platformID["linux"])
	)
)

#Common boring 64-bit modules for windows, linux and OSX
### OSX
for platform in ['OSX', 'linux', 'windows']:
    for wrapper in ['Java','Csharp','Octave','PHP','64BIT_SHARED_LIBRARY','STATIC_LIBRARY']:
        if wrapper == 'PHP' and platform != 'linux': continue # only build PHP on linux
        ctest_args, cmake_args = [], []
        if platform.startswith('windows'):
            ctest_args = ['-C', 'Release']
            if wrapper == 'Octave':
                cmake_args = ['-G', '"MinGW Makefiles"']
            else:
                cmake_args = ['-G', '"Visual Studio 10 2010 Win64"']
        c['builders'].append(
            BuilderConfig(name=wrapper + "-" + platform,
                          slavenames=[platform + "-slave"],
                          factory = cmake_slave(wrapper,
                                                platform = platform,
                                                ctest_args = ctest_args,
                                                cmake_args = cmake_args)
                          )
              )
    c['builders'].append(
    BuilderConfig(name="Catch-"+platform,
                  slavenames=[platform + "-slave"],
                  factory = cmake_slave('Catch', platform = platform, install=False)
                  )
      )

c['builders'].append(
  BuilderConfig(name="32bitDLL-OSX",slavenames=["OSX-slave"],
    factory = cmake_slave(
      '32BIT_SHARED_LIBRARY_LINUX',
      test = False,
      platform = 'OSX',
      cmake_args=['-DFORCE_BITNESS_32=ON'])
  )
)

c['builders'].append(
  BuilderConfig(name="32bitDLL-Linux",slavenames=["linux32-slave"],
    factory = cmake_slave(
      '32BIT_SHARED_LIBRARY_LINUX',
      test = False,
      platform = 'linux')
  )
)

c['builders'].append(
    BuilderConfig(name="32bitCdeclDLL-windows",
      slavenames=["windows-slave"],
      factory = cmake_slave('32BIT_CDECL_SHARED_LIBRARY',
                            test = False,
                            platform = 'windows',
                            cmake_args=['-G','"Visual Studio 10 2010"']
      )
      )
      )
c['builders'].append(
    BuilderConfig(name="32bitStdcallDLL-windows",
      slavenames=["windows-slave"],
      factory = cmake_slave('32BIT_STDCALL_SHARED_LIBRARY',
                            test = False,
                            platform = 'windows',
                            cmake_args=['-G','"Visual Studio 10 2010"']
      )
      )
      )
c['builders'].append(
    BuilderConfig(name="EES-windows",
      slavenames=["windows-slave"],
      factory = cmake_slave('EES',
                            platform = 'windows',
                            test = False,
                            cmake_args = ['-G','"Visual Studio 10 2010"'],
                            build_args = ['--config','Release'])
      )
      )

for platform in ['windows', 'linux', 'OSX']:
    cmake_args = []
    if platform == 'windows':
        cmake_args = ['-G', '"Visual Studio 10 2010 Win64"']
    c['builders'].append(BuilderConfig(name="MATLAB-"+platform, slavenames=[platform+"-slave"], factory = swig_matlab_builder(platform, cmake_args = cmake_args)))
    if platform == 'linux':
        c['builders'].append(BuilderConfig(name="Scilab-"+platform, slavenames=[platform+"-slave"], factory = swig_scilab_builder(platform)))
c['builders'].append(BuilderConfig(name="MATLAB-windows32",
                                   slavenames=["windows-slave"],
                                   factory = swig_matlab_builder('windows',
                                                                 cmake_env={'MATLAB_ROOT':'c:\Program Files (x86)\MATLAB\R2014a'},
                                                                 cmake_args = ['-G', '"Visual Studio 10 2010"'])))
cmake_env={
  'MATLAB_ROOT':'c:\Program Files\MatLab R2014a',
#  'MATLAB_INCLUDE_DIR':'',
#  'MATLAB_MEX_LIBRARY':'',
#  'MATLAB_MX_LIBRARY':''
  }

c['builders'].append(BuilderConfig(name="Matlab-binaries-windows-64bit-VS10", slavenames=["windows-DTU-slave"], factory = swig_matlab_builder("windows", cmake_env=cmake_env, cmake_args = ['-G', '"Visual Studio 10 2010 Win64"'])))
#c['builders'].append(BuilderConfig(name="Matlab-binaries-windows-32bit-VS10", slavenames=["windows-DTU-slave"], factory = swig_matlab_builder("windows", cmake_args = ['-G', '"Visual Studio 10 2010"'])))
{'fraction_non_alphanumeric': 0.13658613040123457, 'fraction_numerical': 0.010657793209876544, 'mean_word_length': 2.988315622445545, 'pattern_counts': {'":': 4, '<': 8, '<?xml version=': 0, '>': 22, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 120, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5976903', 'n_tokens_mistral': 26133, 'n_tokens_neox': 25062, 'n_words': 5845}