Newer
Older
Janik Zikovsky
committed
#!/usr/bin/env python
""" Utility for generating a class file, header, and test file """
import sys
import os
import argparse
import datetime
Janik Zikovsky
committed
import re
import cmakelists_utils
from cmakelists_utils import *
Janik Zikovsky
committed
#======================================================================
def write_header(subproject, classname, filename, args):
Janik Zikovsky
committed
"""Write a class header file"""
print "Writing header file to %s" % filename
f = open(filename, 'w')
guard = "MANTID_%s_%s_H_" % (subproject.upper(), classname.upper())
# Create an Algorithm header; will not use it if
algorithm_header = """
/// Algorithm's name for identification
virtual const std::string name() const { return "%s";};
/// Algorithm's version for identification
virtual int version() const { return 1;};
/// Algorithm's category for identification
virtual const std::string category() const { return "General";}
private:
/// Sets documentation strings for this algorithm
virtual void initDocs();
/// Initialise the properties
void init();
void exec();
""" % classname
alg_class_declare = " : public API::Algorithm"
alg_include = """#include "MantidAPI/Algorithm.h" """
algorithm_header = ""
alg_class_declare = ""
alg_include = ""
# The full text
Janik Zikovsky
committed
s = """#ifndef %s
#define %s
Janik Zikovsky
committed
/*WIKI*
TODO: Enter wiki description here.
*WIKI*/
Janik Zikovsky
committed
#include "MantidKernel/System.h"
Janik Zikovsky
committed
namespace Mantid
{
namespace %s
{
/** %s : TODO: DESCRIPTION
Gigg, Martyn Anthony
committed
@author
@date %s
Copyright © %s ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport %s %s
Janik Zikovsky
committed
{
public:
%s();
~%s();
Janik Zikovsky
committed
};
} // namespace %s
Gigg, Martyn Anthony
committed
} // namespace Mantid
Janik Zikovsky
committed
#endif /* %s */
Gigg, Martyn Anthony
committed
""" % (guard, guard, alg_include, subproject, classname, datetime.datetime.now().date(), datetime.datetime.now().date().year, classname, alg_class_declare, classname, classname, algorithm_header, subproject, guard)
Janik Zikovsky
committed
f.write(s)
f.close()
Janik Zikovsky
committed
#======================================================================
def write_source(subproject, classname, filename, args):
Janik Zikovsky
committed
"""Write a class source file"""
print "Writing source file to %s" % filename
f = open(filename, 'w')
algorithm_top = """
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(%s)
""" % (classname)
algorithm_source = """
//----------------------------------------------------------------------------------------------
/// Sets documentation strings for this algorithm
void %s::initDocs()
{
this->setWikiSummary("TODO: Enter a quick description of your algorithm.");
this->setOptionalMessage("TODO: Enter a quick description of your algorithm.");
}
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void %s::init()
{
declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input), "An input workspace.");
declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output), "An output workspace.");
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void %s::exec()
{
// TODO Auto-generated execute stub
}
Janik Zikovsky
committed
""" % (classname, classname, classname)
algorithm_top = ""
algorithm_source = ""
s = """#include "Mantid%s/%s%s.h"
Janik Zikovsky
committed
#include "MantidKernel/System.h"
using namespace Mantid::Kernel;
using namespace Mantid::API;
Janik Zikovsky
committed
namespace Mantid
{
namespace %s
{
Janik Zikovsky
committed
//----------------------------------------------------------------------------------------------
/** Constructor
*/
%s::%s()
{
// TODO Auto-generated constructor stub
}
//----------------------------------------------------------------------------------------------
/** Destructor
*/
%s::~%s()
{
// TODO Auto-generated destructor stub
}
Janik Zikovsky
committed
} // namespace Mantid
} // namespace %s
""" % (subproject, args.subfolder, classname, subproject, algorithm_top, classname, classname, classname, classname, algorithm_source, subproject)
Janik Zikovsky
committed
f.write(s)
f.close()
#======================================================================
def write_test(subproject, classname, filename, args):
Janik Zikovsky
committed
"""Write a class test file"""
print "Writing test file to %s" % filename
f = open(filename, 'w')
guard = "MANTID_%s_%sTEST_H_" % (subproject.upper(), classname.upper())
algorithm_test = """
void test_Init()
{
%s alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
}
Janik Zikovsky
committed
void test_exec()
{
// Name of the output workspace.
std::string outWSName("%sTest_OutputWS");
%s alg;
TS_ASSERT_THROWS_NOTHING( alg.initialize() )
TS_ASSERT( alg.isInitialized() )
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("REPLACE_PROPERTY_NAME_HERE!!!!", "value") );
TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) );
Janik Zikovsky
committed
TS_ASSERT_THROWS_NOTHING( alg.execute(); );
TS_ASSERT( alg.isExecuted() );
Janik Zikovsky
committed
// Retrieve the workspace from data service. TODO: Change to your desired type
Workspace_sptr ws;
TS_ASSERT_THROWS_NOTHING( ws = boost::dynamic_pointer_cast<Workspace>(AnalysisDataService::Instance().retrieve(outWSName)) );
TS_ASSERT(ws);
if (!ws) return;
// TODO: Check the results
// Remove workspace from the data service.
AnalysisDataService::Instance().remove(outWSName);
}
""" % (classname,classname,classname);
algorithm_test = ""
Janik Zikovsky
committed
s = """#ifndef %s
#define %s
#include <cxxtest/TestSuite.h>
Janik Zikovsky
committed
#include "MantidKernel/Timer.h"
#include "MantidKernel/System.h"
Janik Zikovsky
committed
#include <iostream>
#include <iomanip>
#include "Mantid%s/%s%s.h"
Janik Zikovsky
committed
Janik Zikovsky
committed
using namespace Mantid::%s;
Janik Zikovsky
committed
using namespace Mantid::API;
Janik Zikovsky
committed
class %sTest : public CxxTest::TestSuite
{
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static %sTest *createSuite() { return new %sTest(); }
static void destroySuite( %sTest *suite ) { delete suite; }
%s
void test_Something()
Janik Zikovsky
committed
{
}
};
#endif /* %s */
""" % (guard, guard, subproject, args.subfolder, classname, subproject, classname, classname, classname, classname, algorithm_test, guard)
Janik Zikovsky
committed
f.write(s)
f.close()
Janik Zikovsky
committed
Janik Zikovsky
committed
#======================================================================
def generate(subproject, classname, overwrite, args):
Janik Zikovsky
committed
# Directory at base of subproject
basedir, header_folder = find_basedir(args.project, subproject)
Janik Zikovsky
committed
headerfile = os.path.join(basedir, "inc", header_folder, args.subfolder + classname + ".h")
Gigg, Martyn Anthony
committed
sourcefile = os.path.join(basedir, "src", args.subfolder + classname + ".cpp")
testfile = os.path.join(basedir, "test", classname + "Test.h")
Janik Zikovsky
committed
if args.header and not overwrite and os.path.exists(headerfile):
print "\nError! Header file %s already exists. Use --force to overwrite.\n" % headerfile
return
if args.cpp and not overwrite and os.path.exists(sourcefile):
print "\nError! Source file %s already exists. Use --force to overwrite.\n" % sourcefile
return
if args.test and not overwrite and os.path.exists(testfile):
print "\nError! Test file %s already exists. Use --force to overwrite.\n" % testfile
Janik Zikovsky
committed
if args.header:
write_header(subproject, classname, headerfile, args)
if args.cpp:
write_source(subproject, classname, sourcefile, args)
if args.test:
write_test(subproject, classname, testfile, args)
Janik Zikovsky
committed
# Insert into the cmake list
add_to_cmake(subproject, classname, args, args.subfolder)
print "\n Files were added to Framework/%s/CMakeLists.txt !" % (subproject)
Janik Zikovsky
committed
print
# if not test_only:
# print "\tsrc/%s.cpp" % (classname)
# print "\tinc/Mantid%s/%s.h" % (subproject, classname)
# print "\ttest/%sTest.h" % (classname)
# print
Janik Zikovsky
committed
Janik Zikovsky
committed
Janik Zikovsky
committed
#======================================================================
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Utility to create Mantid class files: header, source and test.')
Janik Zikovsky
committed
parser.add_argument('subproject', metavar='SUBPROJECT', type=str,
help='The subproject under Framework/; e.g. Kernel')
Janik Zikovsky
committed
parser.add_argument('classname', metavar='CLASSNAME', type=str,
help='Name of the class to create')
parser.add_argument('--force', dest='force', action='store_const',
const=True, default=False,
help='Force overwriting existing files. Use with caution!')
parser.add_argument('--no-header', dest='header', action='store_const',
const=False, default=True,
help="Don't create the header file")
parser.add_argument('--no-test', dest='test', action='store_const',
const=False, default=True,
help="Don't create the test file")
parser.add_argument('--no-cpp', dest='cpp', action='store_const',
const=False, default=True,
help="Don't create the cpp file")
parser.add_argument('--alg', dest='alg', action='store_const',
const=True, default=False,
help='Create an Algorithm stub. This adds some methods common to algorithms.')
parser.add_argument('--subfolder', dest='subfolder',
default="",
help='Put the source under a subfolder below the main part of the project, e.g. Geometry/Instrument.')
parser.add_argument('--project', dest='project',
default="Framework",
help='The project in which this goes. Default: Framework. Can be MantidQt, Vates')
args = parser.parse_args()
subproject = args.subproject
classname = args.classname
overwrite = args.force
# Make sure the subfolders end with a /
if args.subfolder != "":
if args.subfolder[-1:] != "/":
args.subfolder += "/"
generate(subproject, classname, overwrite, args)