1 | #!/usr/bin/env python |
2 | |
3 | """ |
4 | Static Analyzer qualification infrastructure: adding a new project to |
5 | the Repository Directory. |
6 | |
7 | Add a new project for testing: build it and add to the Project Map file. |
8 | Assumes it's being run from the Repository Directory. |
9 | The project directory should be added inside the Repository Directory and |
10 | have the same name as the project ID |
11 | |
12 | The project should use the following files for set up: |
13 | - cleanup_run_static_analyzer.sh - prepare the build environment. |
14 | Ex: make clean can be a part of it. |
15 | - run_static_analyzer.cmd - a list of commands to run through scan-build. |
16 | Each command should be on a separate line. |
17 | Choose from: configure, make, xcodebuild |
18 | - download_project.sh - download the project into the CachedSource/ |
19 | directory. For example, download a zip of |
20 | the project source from GitHub, unzip it, |
21 | and rename the unzipped directory to |
22 | 'CachedSource'. This script is not called |
23 | when 'CachedSource' is already present, |
24 | so an alternative is to check the |
25 | 'CachedSource' directory into the |
26 | repository directly. |
27 | - CachedSource/ - An optional directory containing the source of the |
28 | project being analyzed. If present, |
29 | download_project.sh will not be called. |
30 | - changes_for_analyzer.patch - An optional patch file for any local |
31 | changes |
32 | (e.g., to adapt to newer version of clang) |
33 | that should be applied to CachedSource |
34 | before analysis. To construct this patch, |
35 | run the download script to download |
36 | the project to CachedSource, copy the |
37 | CachedSource to another directory (for |
38 | example, PatchedSource) and make any |
39 | needed modifications to the copied |
40 | source. |
41 | Then run: |
42 | diff -ur CachedSource PatchedSource \ |
43 | > changes_for_analyzer.patch |
44 | """ |
45 | from __future__ import absolute_import, division, print_function |
46 | import SATestBuild |
47 | |
48 | import os |
49 | import csv |
50 | import sys |
51 | |
52 | |
53 | def isExistingProject(PMapFile, projectID): |
54 | PMapReader = csv.reader(PMapFile) |
55 | for I in PMapReader: |
56 | if projectID == I[0]: |
57 | return True |
58 | return False |
59 | |
60 | |
61 | def addNewProject(ID, BuildMode): |
62 | """ |
63 | Add a new project for testing: build it and add to the Project Map file. |
64 | :param ID: is a short string used to identify a project. |
65 | """ |
66 | |
67 | CurDir = os.path.abspath(os.curdir) |
68 | Dir = SATestBuild.getProjectDir(ID) |
69 | if not os.path.exists(Dir): |
70 | print("Error: Project directory is missing: %s" % Dir) |
71 | sys.exit(-1) |
72 | |
73 | # Build the project. |
74 | SATestBuild.testProject(ID, BuildMode, IsReferenceBuild=True) |
75 | |
76 | # Add the project ID to the project map. |
77 | ProjectMapPath = os.path.join(CurDir, SATestBuild.ProjectMapFile) |
78 | |
79 | if os.path.exists(ProjectMapPath): |
80 | FileMode = "r+b" |
81 | else: |
82 | print("Warning: Creating the Project Map file!!") |
83 | FileMode = "w+b" |
84 | |
85 | with open(ProjectMapPath, FileMode) as PMapFile: |
86 | if (isExistingProject(PMapFile, ID)): |
87 | print('Warning: Project with ID \'', ID, \ |
88 | '\' already exists.', file=sys.stdout) |
89 | print("Reference output has been regenerated.", file=sys.stdout) |
90 | else: |
91 | PMapWriter = csv.writer(PMapFile) |
92 | PMapWriter.writerow((ID, int(BuildMode))) |
93 | print("The project map is updated: ", ProjectMapPath) |
94 | |
95 | |
96 | # TODO: Add an option not to build. |
97 | # TODO: Set the path to the Repository directory. |
98 | if __name__ == '__main__': |
99 | if len(sys.argv) < 2 or sys.argv[1] in ('-h', '--help'): |
100 | print('Add a new project for testing to the analyzer'\ |
101 | '\nUsage: ', sys.argv[0],\ |
102 | 'project_ID <mode>\n' \ |
103 | 'mode: 0 for single file project, ' \ |
104 | '1 for scan_build, ' \ |
105 | '2 for single file c++11 project', file=sys.stderr) |
106 | sys.exit(-1) |
107 | |
108 | BuildMode = 1 |
109 | if (len(sys.argv) >= 3): |
110 | BuildMode = int(sys.argv[2]) |
111 | assert((BuildMode == 0) | (BuildMode == 1) | (BuildMode == 2)) |
112 | |
113 | addNewProject(sys.argv[1], BuildMode) |
114 | |