Add some comments.
[bertos.git] / wizard / create_preset.py
1 import pickle
2 import sys
3 import os
4 import shutil
5 import pprint
6 import glob
7 import re
8
9 def remove(path):
10     if os.path.isdir(path):
11         shutil.rmtree(path, ignore_errors=True)
12     else:
13         try:
14             os.remove(path)
15         except OSError:
16             pass
17
18 def findPath(start, target):
19     pa = start
20     while pa != "/":
21         pa = os.path.abspath(pa + "/..")
22         if os.path.exists(pa + "/" + target):
23             return os.path.relpath(pa, start)
24
25 if len(sys.argv) < 3:
26     print "Usage: %s <project_dir> <preset_dir>" % sys.argv[0]
27     exit(0)
28
29 prj_dir = sys.argv[1]
30 preset_dir = sys.argv[2]
31
32 if not os.path.exists(prj_dir + "/project.bertos"):
33     print "%s does not seem a Wizard created project." % prj_dir
34     exit(1)
35
36 p = open(prj_dir + "/project.bertos")
37 s = pickle.load(p)
38 if s["WIZARD_VERSION"] < 3:
39     print "Project version too old."
40     exit(1)
41 pname = s["PROJECT_NAME"] 
42 preset_dir += pname
43
44 #find hw/ path for the board
45 hw_path = findPath(preset_dir, "hw")
46 if not hw_path:
47     print "hw/ path not found in parent directories of %s" % preset_dir
48     exit(1)
49
50 #find bertos/ path
51 bertos_path = findPath(preset_dir, "bertos")
52 if not bertos_path:
53     print "bertos/ path not found in parent directories of %s" % preset_dir
54     exit(1)
55
56 #Copy the project and remove unneeded files.
57 shutil.copytree(prj_dir, preset_dir)
58 remove(preset_dir + "/bertos")
59 remove(preset_dir + "/images")
60 remove(preset_dir + "/obj")
61 remove(preset_dir + "/Makefile")
62 remove(preset_dir + "/buildrev.h")
63 remove(preset_dir + "/VERSION")
64 remove(preset_dir + "/" + pname + ".project")
65 remove(preset_dir + "/" + pname + ".workspace")
66
67 #Flatten project sources.
68 #A wizard created project called pname
69 #usually has the following structure:
70 #
71 #pname
72 #  |
73 #  +-<project files>
74 #  |
75 #  +-bertos
76 #  |
77 #  +-pname
78 #      |   
79 #      +<pname sources>
80 #
81 #This has been done in order to have the chance to
82 #add multiple projects sharing the same bertos version.
83 #After the copy and after removing the bertos tree inside the 
84 #project, the double pname directory is redundant, so we move
85 #all pname sources into the parent directory
86 l = glob.glob(preset_dir + "/" + pname + "/*")
87 for f in l:
88     shutil.move(f, preset_dir)
89
90 #Remove the now empty project src dir and the hw/ dir.
91 #hw files are located in parent directories and are common
92 #for all projects on the same board. 
93 remove(preset_dir + "/" + pname)
94 remove(preset_dir + "/hw")
95
96 assert(os.path.exists(preset_dir + "/" + hw_path     + "/hw"))
97 assert(os.path.exists(preset_dir + "/" + bertos_path + "/bertos"))
98
99 #Update wizard project info.
100 #A preset is still a Wizard-editable project
101 #but has its bertos/ and hw/ dirs shared with 
102 #others.
103 s["BERTOS_PATH"] = bertos_path
104 s["PROJECT_HW_PATH"] = hw_path
105 s["PROJECT_SRC_PATH"] = "."
106 s["PRESET"] = True
107 pprint.pprint(s)
108 p = open(preset_dir + "/project.bertos", "w")
109 pickle.dump(s, p)
110
111 #Create a .spec file in order to make this preset visible in the Wizard
112 open(preset_dir + "/.spec", "w").write("name = '%s preset'" % pname)
113
114 bertos_path = os.path.abspath(preset_dir + "/" + bertos_path)
115 hw_path = os.path.abspath(preset_dir + "/" + hw_path)
116
117 src_path = os.path.relpath(preset_dir, bertos_path)
118 hw_path  = os.path.relpath(hw_path, bertos_path)
119
120 #Update project makefiles adapting them to the new directory layout
121 mk = open(preset_dir + "/" + pname + ".mk").read()
122 mk = re.sub(r"(%s_SRC_PATH\s*=\s*).*" % pname, r"\1%s" % src_path, mk)
123 mk = re.sub(r"(%s_HW_PATH\s*=\s*).*" % pname, r"\1%s" % hw_path, mk)
124
125 #remove absolute path from toolchain
126 mk = re.sub(r'(%s_PREFIX\s*=\s*").*?([^/]*")' % pname, r'\1\2', mk)
127 open(preset_dir + "/" + pname + ".mk", "w").write(mk)