Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | """ |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 4 | Static Analyzer qualification infrastructure: adding a new project to |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 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. |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 9 | The project directory should be added inside the Repository Directory and |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 10 | have the same name as the project ID |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 11 | |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 12 | The project should use the following files for set up: |
Devin Coughlin | 2cb767d | 2015-11-07 18:27:35 +0000 | [diff] [blame] | 13 | - cleanup_run_static_analyzer.sh - prepare the build environment. |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 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. |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 17 | Choose from: configure, make, xcodebuild |
Devin Coughlin | 2cb767d | 2015-11-07 18:27:35 +0000 | [diff] [blame] | 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. |
George Karpenkov | a807660 | 2017-10-02 17:59:12 +0000 | [diff] [blame] | 30 | - changes_for_analyzer.patch - An optional patch file for any local |
| 31 | changes |
Devin Coughlin | 2cb767d | 2015-11-07 18:27:35 +0000 | [diff] [blame] | 32 | (e.g., to adapt to newer version of clang) |
| 33 | that should be applied to CachedSource |
| 34 | before analysis. To construct this patch, |
Hiroshi Inoue | 56939f7 | 2018-01-22 07:44:38 +0000 | [diff] [blame^] | 35 | run the download script to download |
Devin Coughlin | 2cb767d | 2015-11-07 18:27:35 +0000 | [diff] [blame] | 36 | the project to CachedSource, copy the |
| 37 | CachedSource to another directory (for |
George Karpenkov | a807660 | 2017-10-02 17:59:12 +0000 | [diff] [blame] | 38 | example, PatchedSource) and make any |
Hiroshi Inoue | 56939f7 | 2018-01-22 07:44:38 +0000 | [diff] [blame^] | 39 | needed modifications to the copied |
George Karpenkov | a807660 | 2017-10-02 17:59:12 +0000 | [diff] [blame] | 40 | source. |
Devin Coughlin | 2cb767d | 2015-11-07 18:27:35 +0000 | [diff] [blame] | 41 | Then run: |
| 42 | diff -ur CachedSource PatchedSource \ |
| 43 | > changes_for_analyzer.patch |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 44 | """ |
| 45 | import SATestBuild |
| 46 | |
| 47 | import os |
| 48 | import csv |
| 49 | import sys |
| 50 | |
George Karpenkov | a807660 | 2017-10-02 17:59:12 +0000 | [diff] [blame] | 51 | |
| 52 | def isExistingProject(PMapFile, projectID): |
Anna Zaks | a1b56e2 | 2011-11-08 22:41:22 +0000 | [diff] [blame] | 53 | PMapReader = csv.reader(PMapFile) |
| 54 | for I in PMapReader: |
| 55 | if projectID == I[0]: |
| 56 | return True |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 57 | return False |
Anna Zaks | a1b56e2 | 2011-11-08 22:41:22 +0000 | [diff] [blame] | 58 | |
George Karpenkov | a807660 | 2017-10-02 17:59:12 +0000 | [diff] [blame] | 59 | |
| 60 | def addNewProject(ID, BuildMode): |
| 61 | """ |
| 62 | Add a new project for testing: build it and add to the Project Map file. |
| 63 | :param ID: is a short string used to identify a project. |
| 64 | """ |
| 65 | |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 66 | CurDir = os.path.abspath(os.curdir) |
| 67 | Dir = SATestBuild.getProjectDir(ID) |
| 68 | if not os.path.exists(Dir): |
| 69 | print "Error: Project directory is missing: %s" % Dir |
| 70 | sys.exit(-1) |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 71 | |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 72 | # Build the project. |
George Karpenkov | 3abfc3b | 2017-09-22 01:41:16 +0000 | [diff] [blame] | 73 | SATestBuild.testProject(ID, BuildMode, IsReferenceBuild=True) |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 74 | |
| 75 | # Add the project ID to the project map. |
| 76 | ProjectMapPath = os.path.join(CurDir, SATestBuild.ProjectMapFile) |
George Karpenkov | a807660 | 2017-10-02 17:59:12 +0000 | [diff] [blame] | 77 | |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 78 | if os.path.exists(ProjectMapPath): |
George Karpenkov | a807660 | 2017-10-02 17:59:12 +0000 | [diff] [blame] | 79 | FileMode = "r+b" |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 80 | else: |
| 81 | print "Warning: Creating the Project Map file!!" |
George Karpenkov | a807660 | 2017-10-02 17:59:12 +0000 | [diff] [blame] | 82 | FileMode = "w+b" |
| 83 | |
| 84 | with open(ProjectMapPath, FileMode) as PMapFile: |
| 85 | if (isExistingProject(PMapFile, ID)): |
Anna Zaks | a1b56e2 | 2011-11-08 22:41:22 +0000 | [diff] [blame] | 86 | print >> sys.stdout, 'Warning: Project with ID \'', ID, \ |
| 87 | '\' already exists.' |
| 88 | print >> sys.stdout, "Reference output has been regenerated." |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 89 | else: |
Anna Zaks | a1b56e2 | 2011-11-08 22:41:22 +0000 | [diff] [blame] | 90 | PMapWriter = csv.writer(PMapFile) |
George Karpenkov | a807660 | 2017-10-02 17:59:12 +0000 | [diff] [blame] | 91 | PMapWriter.writerow((ID, int(BuildMode))) |
Anna Zaks | a1b56e2 | 2011-11-08 22:41:22 +0000 | [diff] [blame] | 92 | print "The project map is updated: ", ProjectMapPath |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 93 | |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 94 | |
| 95 | # TODO: Add an option not to build. |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 96 | # TODO: Set the path to the Repository directory. |
| 97 | if __name__ == '__main__': |
George Karpenkov | 2d15509 | 2017-09-21 21:47:33 +0000 | [diff] [blame] | 98 | if len(sys.argv) < 2 or sys.argv[1] in ('-h', '--help'): |
George Karpenkov | a807660 | 2017-10-02 17:59:12 +0000 | [diff] [blame] | 99 | print >> sys.stderr, 'Add a new project for testing to the analyzer'\ |
George Karpenkov | 2d15509 | 2017-09-21 21:47:33 +0000 | [diff] [blame] | 100 | '\nUsage: ', sys.argv[0],\ |
| 101 | 'project_ID <mode>\n' \ |
| 102 | 'mode: 0 for single file project, ' \ |
| 103 | '1 for scan_build, ' \ |
Anna Zaks | a2f970b | 2012-09-06 23:30:27 +0000 | [diff] [blame] | 104 | '2 for single file c++11 project' |
Anna Zaks | f0c4116 | 2011-10-06 23:26:27 +0000 | [diff] [blame] | 105 | sys.exit(-1) |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 106 | |
| 107 | BuildMode = 1 |
Anna Zaks | 4720a73 | 2011-11-05 05:20:48 +0000 | [diff] [blame] | 108 | if (len(sys.argv) >= 3): |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 109 | BuildMode = int(sys.argv[2]) |
Anna Zaks | a2f970b | 2012-09-06 23:30:27 +0000 | [diff] [blame] | 110 | assert((BuildMode == 0) | (BuildMode == 1) | (BuildMode == 2)) |
Ted Kremenek | 3a0678e | 2015-09-08 03:50:52 +0000 | [diff] [blame] | 111 | |
Anna Zaks | a2f970b | 2012-09-06 23:30:27 +0000 | [diff] [blame] | 112 | addNewProject(sys.argv[1], BuildMode) |