-
Notifications
You must be signed in to change notification settings - Fork 7
/
create_project.py
executable file
·166 lines (145 loc) · 7.92 KB
/
create_project.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/env python3
###############################################################################
# (c) Copyright 2015-2020 CERN #
# #
# This software is distributed under the terms of the GNU General Public #
# Licence version 3 (GPL Version 3), copied verbatim in the file "LICENCE". #
# #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization #
# or submit itself to any jurisdiction. #
###############################################################################
__author__ = "Benedikt Hegner (CERN)"
__copyright__ = "Copyright (C) 2015-2020 CERN"
__license__ = "GPLv3"
__version__ = "0.2"
import datetime, os, shutil, sys
from os.path import join, split, dirname, abspath
class ProjectCreator(object):
def __init__(self,projectname, author, target_dir,license,
verbose=True, subpackage_name="package"):
self.location = dirname(abspath(__file__))
self.template_dir = join(self.location,"project_template")
self.license_dir = join(self.location,"project_licenses")
self.licenses = [f.rstrip(".txt") for f in
os.listdir(self.license_dir)
if f.endswith(".txt")]
self.year = datetime.datetime.now().year
self.name = projectname
self.target_dir = target_dir
self.author = author
self.verbose = verbose
self.subpackage_name = subpackage_name
self.license = license
if self.license not in self.licenses:
self.report(f"ERROR: license {license} unknown")
self.print_licenses()
sys.exit(1)
if os.path.exists(self.target_dir):
self.report(f"ERROR: {self.target_dir} already exists")
sys.exit(1)
def print_licenses(self):
"""Print available licenses"""
self.report("The following licenses are available:")
for license in self.licenses:
self.report(" "*3+license)
def create(self):
""" Create the new project"""
shutil.copytree(self.template_dir,self.target_dir)
self.add_license()
self.replace_templates()
def add_license(self):
""" Add license file and replace year and author"""
shutil.copy(join(self.license_dir,self.license+".txt"),
join(self.target_dir,"LICENSE"))
shutil.copy(join(self.license_dir,self.license+".notice"),
join(self.target_dir,"NOTICE"))
replacements = {"YEAR": str(self.year),
"AUTHOR" : self.author}
self.replace_in_file(join(self.target_dir,"NOTICE"), replacements)
def report(self, message):
"""print messages to screen depending on verbosity level"""
if self.verbose == True:
print(message)
@staticmethod
def replace_in_file(filename, replacements):
"""replace file contents according to given dictionary"""
with open(filename,'r') as f:
newlines = []
for line in f.readlines():
for key, value in replacements.items():
line = line.replace(key, value)
newlines.append(line.replace(key, value))
with open(filename, 'w') as f:
for line in newlines:
f.write(line)
def replace_templates(self):
"""Replace the strings in the project template by the user defined values"""
# add C++ style comment to the copyright notice
copyrightnotice = ""
for line in open(join(self.target_dir,"NOTICE")).readlines():
copyrightnotice += "// %s\n"%line
replacements = {"COPYRIGHTNOTICE" : copyrightnotice,
"PROJECTTEMPLATE" : self.name,
"AUTHOR" : self.author,
"HSFSUBPACKAGE" : self.subpackage_name
}
for subdir, dirs, files in os.walk(self.target_dir):
for file in files:
self.replace_in_file(join(subdir, file),replacements)
os.rename(join(self.target_dir,"cmake/PROJECTTEMPLATECPack.cmake"),join(self.target_dir,"cmake/%sCPack.cmake" %self.name))
os.rename(join(self.target_dir,"cmake/PROJECTTEMPLATEConfig.cmake.in"),join(self.target_dir,"cmake/%sConfig.cmake.in" %self.name))
os.rename(join(self.target_dir,"cmake/PROJECTTEMPLATECreateConfig.cmake"),join(self.target_dir,"cmake/%sCreateConfig.cmake" %self.name))
os.rename(join(self.target_dir,"cmake/PROJECTTEMPLATEDoxygen.cmake"),join(self.target_dir,"cmake/%sDoxygen.cmake" %self.name))
os.rename(join(self.target_dir,"cmake/PROJECTTEMPLATEUninstall.cmake"),join(self.target_dir,"cmake/%sUninstall.cmake" %self.name))
os.rename(join(self.target_dir,"cmake/PROJECTTEMPLATE_uninstall.cmake.in"),join(self.target_dir,"cmake/%s_uninstall.cmake.in" %self.name))
os.rename(join(self.target_dir,"cmake/PROJECTTEMPLATE.pc.in"),join(self.target_dir,"cmake/%s.pc.in" %self.name))
os.rename(join(self.target_dir,"PROJECTTEMPLATEVersion.h"),join(self.target_dir,"%sVersion.h" %self.name))
os.rename(join(self.target_dir,"package/include/example"),join(self.target_dir,"package/include/%s" %self.name))
os.rename(join(self.target_dir,"package"),join(self.target_dir,"%s" %self.subpackage_name))
def print_summary(self):
"""Print summary and help message"""
summary = "Finished creating project '%s'\n" %self.name
summary += " directory: %s\n" % self.target_dir
summary += " author : %s\n" % self.author
summary += " license : %s\n" % self.license
summary += " package : %s\n" %self.subpackage_name
howto = "To build and install it, please do:\n"
howto += " cd %s\n mkdir build\n cd build\n" %self.target_dir
howto += " cmake -DCMAKE_INSTALL_PREFIX=../install ../\n"
howto += " make\n make install\n"
howto += "To build the doxygen documentation:\n"
howto += " make doc\n"
howto += "To run the unit tests:\n"
howto += " make test\n"
howto += "To trigger the package creation with CPack:\n"
howto += " make package\n"
howto += "\nPlease do not forget to add a project description to README.md !"
self.report(summary)
self.report(howto)
##########################
if __name__ == "__main__":
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("-q", "--quiet",
action="store_false", dest="verbose", default=True,
help="Don't write a report to screen")
parser.add_argument("-p", "--package",
action="store", dest="subpackage_name", default="package",
help="Name of the created example-subpackage")
parser.add_argument("project_name", help="Name for new project")
parser.add_argument("author", help="Author of new project (format of 'Any Body <any.body@domain.edu>' recommended")
parser.add_argument("target_dir", help="Directory name for new project template")
# Parse available licenses for the argument definition
license_dir = join(dirname(abspath(__file__)),"project_licenses")
licenses = [f.rstrip(".txt") for f in
os.listdir(license_dir)
if f.endswith(".txt")]
parser.add_argument("license", help="License to apply to the new project ",
choices=licenses)
args = parser.parse_args()
creator = ProjectCreator(args.project_name, args.author, args.target_dir,
args.license, verbose=args.verbose,
subpackage_name=args.subpackage_name)
creator.create()
creator.print_summary()