@@ -15,7 +15,6 @@ def write_csproj_prefix(ioWrapper):
15
15
' <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\n ' )
16
16
ioWrapper .write (' </PropertyGroup>\n \n ' )
17
17
18
-
19
18
print ('Script to generate stub file from a nuget package' )
20
19
print (' Usage: python3 ' + sys .argv [0 ] +
21
20
' TEMPLATE NUGET_PACKAGE_NAME [VERSION=latest] [WORK_DIR=tempDir]' )
@@ -34,191 +33,207 @@ def write_csproj_prefix(ioWrapper):
34
33
thisDir = os .path .abspath (os .path .dirname (thisScript ))
35
34
template = sys .argv [1 ]
36
35
nuget = sys .argv [2 ]
37
-
38
- # /input contains a dotnet project that's being extracted
39
- workDir = os .path .abspath (helpers .get_argv (4 , "tempDir" ))
40
- projectNameIn = "input"
41
- projectDirIn = os .path .join (workDir , projectNameIn )
42
-
43
- def run_cmd (cmd , msg = "Failed to run command" ):
44
- helpers .run_cmd_cwd (cmd , workDir , msg )
45
-
46
- # /output contains the output of the stub generation
47
- outputDirName = "output"
48
- outputDir = os .path .join (workDir , outputDirName )
49
-
50
- # /output/raw contains the bqrs result from the query, the json equivalent
51
- rawOutputDirName = "raw"
52
- rawOutputDir = os .path .join (outputDir , rawOutputDirName )
53
- os .makedirs (rawOutputDir )
54
-
55
- # /output/output contains a dotnet project with the generated stubs
56
- projectNameOut = "output"
57
- projectDirOut = os .path .join (outputDir , projectNameOut )
58
-
59
- # /db contains the extracted QL DB
60
- dbName = 'db'
61
- dbDir = os .path .join (workDir , dbName )
62
- outputName = "stub"
63
- outputFile = os .path .join (projectDirOut , outputName + '.cs' )
64
- bqrsFile = os .path .join (rawOutputDir , outputName + '.bqrs' )
65
- jsonFile = os .path .join (rawOutputDir , outputName + '.json' )
66
36
version = helpers .get_argv (3 , "latest" )
37
+ relativeWorkDir = helpers .get_argv (4 , "tempDir" )
38
+
39
+ class Generator :
40
+ def __init__ (self , thisScript , relativeWorkDir , template ):
41
+ # /input contains a dotnet project that's being extracted
42
+ self .workDir = os .path .abspath (relativeWorkDir )
43
+ os .makedirs (self .workDir )
44
+ self .thisDir = os .path .abspath (os .path .dirname (thisScript ))
45
+ self .projectNameIn = "input"
46
+ self .projectDirIn = os .path .join (self .workDir , self .projectNameIn )
47
+ self .template = template
48
+ print ("\n * Creating new input project" )
49
+ self .run_cmd (['dotnet' , 'new' , self .template , "-f" , "net8.0" , "--language" , "C#" , '--name' ,
50
+ self .projectNameIn , '--output' , self .projectDirIn ])
51
+ helpers .remove_files (self .projectDirIn , '.cs' )
52
+
53
+ def run_cmd (self , cmd , msg = "Failed to run command" ):
54
+ helpers .run_cmd_cwd (cmd , self .workDir , msg )
55
+
56
+ def add_nuget (self , nuget , version = "latest" ):
57
+ print ("\n * Adding reference to package: " + nuget )
58
+ cmd = ['dotnet' , 'add' , self .projectDirIn , 'package' , nuget ]
59
+ if (version != "latest" ):
60
+ cmd .append ('--version' )
61
+ cmd .append (version )
62
+ self .run_cmd (cmd )
63
+
64
+ def make_stubs (self ):
65
+ # /output contains the output of the stub generation
66
+ outputDirName = "output"
67
+ outputDir = os .path .join (self .workDir , outputDirName )
68
+
69
+ # /output/raw contains the bqrs result from the query, the json equivalent
70
+ rawOutputDirName = "raw"
71
+ rawOutputDir = os .path .join (outputDir , rawOutputDirName )
72
+ os .makedirs (rawOutputDir )
73
+
74
+ # /output/output contains a dotnet project with the generated stubs
75
+ projectNameOut = "output"
76
+ projectDirOut = os .path .join (outputDir , projectNameOut )
77
+
78
+ # /db contains the extracted QL DB
79
+ dbName = 'db'
80
+ dbDir = os .path .join (self .workDir , dbName )
81
+ outputName = "stub"
82
+ outputFile = os .path .join (projectDirOut , outputName + '.cs' )
83
+ bqrsFile = os .path .join (rawOutputDir , outputName + '.bqrs' )
84
+ jsonFile = os .path .join (rawOutputDir , outputName + '.json' )
85
+
86
+ sdk_version = '8.0.100'
87
+ print ("\n * Creating new global.json file and setting SDK to " + sdk_version )
88
+ self .run_cmd (['dotnet' , 'new' , 'globaljson' , '--force' , '--sdk-version' , sdk_version , '--output' , self .workDir ])
89
+
90
+ print ("\n * Running stub generator" )
91
+ helpers .run_cmd_cwd (['dotnet' , 'run' , '--project' , self .thisDir + '/../../extractor/Semmle.Extraction.CSharp.DependencyStubGenerator/Semmle.Extraction.CSharp.DependencyStubGenerator.csproj' ], self .projectDirIn )
92
+
93
+ print ("\n * Creating new raw output project" )
94
+ rawSrcOutputDirName = 'src'
95
+ rawSrcOutputDir = os .path .join (rawOutputDir , rawSrcOutputDirName )
96
+ self .run_cmd (['dotnet' , 'new' , self .template , "--language" , "C#" ,
97
+ '--name' , rawSrcOutputDirName , '--output' , rawSrcOutputDir ])
98
+ helpers .remove_files (rawSrcOutputDir , '.cs' )
99
+
100
+ # copy each file from projectDirIn to rawSrcOutputDir
101
+ pathInfos = {}
102
+ codeqlStubsDir = os .path .join (self .projectDirIn , 'codeql_csharp_stubs' )
103
+ for root , dirs , files in os .walk (codeqlStubsDir ):
104
+ for file in files :
105
+ if file .endswith ('.cs' ):
106
+ path = os .path .join (root , file )
107
+ relPath , _ = os .path .splitext (os .path .relpath (path , codeqlStubsDir ))
108
+ origDllPath = "/" + relPath + ".dll"
109
+ pathInfos [origDllPath ] = os .path .join (rawSrcOutputDir , file )
110
+ shutil .copy2 (path , rawSrcOutputDir )
111
+
112
+ print ("\n --> Generated stub files: " + rawSrcOutputDir )
113
+
114
+ print ("\n * Formatting files" )
115
+ self .run_cmd (['dotnet' , 'format' , 'whitespace' , rawSrcOutputDir ])
116
+
117
+ print ("\n --> Generated (formatted) stub files: " + rawSrcOutputDir )
118
+
119
+ print ("\n * Processing project.assets.json to generate folder structure" )
120
+ stubsDirName = 'stubs'
121
+ stubsDir = os .path .join (outputDir , stubsDirName )
122
+ os .makedirs (stubsDir )
123
+
124
+ frameworksDirName = '_frameworks'
125
+ frameworksDir = os .path .join (stubsDir , frameworksDirName )
126
+
127
+ frameworks = set ()
128
+ copiedFiles = set ()
129
+
130
+ assetsJsonFile = os .path .join (self .projectDirIn , 'obj' , 'project.assets.json' )
131
+ with open (assetsJsonFile ) as json_data :
132
+ data = json .load (json_data )
133
+ if len (data ['targets' ]) > 1 :
134
+ print ("ERROR: More than one target found in " + assetsJsonFile )
135
+ exit (1 )
136
+ target = list (data ['targets' ].keys ())[0 ]
137
+ print ("Found target: " + target )
138
+ for package in data ['targets' ][target ].keys ():
139
+ parts = package .split ('/' )
140
+ name = parts [0 ]
141
+ version = parts [1 ]
142
+ packageDir = os .path .join (stubsDir , name , version )
143
+ if not os .path .exists (packageDir ):
144
+ os .makedirs (packageDir )
145
+ print (' * Processing package: ' + name + '/' + version )
146
+ with open (os .path .join (packageDir , name + '.csproj' ), 'a' ) as pf :
147
+
148
+ write_csproj_prefix (pf )
149
+ pf .write (' <ItemGroup>\n ' )
150
+
151
+ dlls = set ()
152
+ if 'compile' in data ['targets' ][target ][package ]:
153
+ for dll in data ['targets' ][target ][package ]['compile' ]:
154
+ dlls .add (
155
+ (name + '/' + version + '/' + dll ).lower ())
156
+ if 'runtime' in data ['targets' ][target ][package ]:
157
+ for dll in data ['targets' ][target ][package ]['runtime' ]:
158
+ dlls .add ((name + '/' + version + '/' + dll ).lower ())
159
+
160
+ for pathInfo in pathInfos :
161
+ for dll in dlls :
162
+ if pathInfo .lower ().endswith (dll ):
163
+ copiedFiles .add (pathInfo )
164
+ shutil .copy2 (pathInfos [pathInfo ], packageDir )
165
+
166
+ if 'dependencies' in data ['targets' ][target ][package ]:
167
+ for dependency in data ['targets' ][target ][package ]['dependencies' ].keys ():
168
+ depVersion = data ['targets' ][target ][package ]['dependencies' ][dependency ]
169
+ pf .write (' <ProjectReference Include="../../' +
170
+ dependency + '/' + depVersion + '/' + dependency + '.csproj" />\n ' )
171
+
172
+ if 'frameworkReferences' in data ['targets' ][target ][package ]:
173
+ if not os .path .exists (frameworksDir ):
174
+ os .makedirs (frameworksDir )
175
+ for framework in data ['targets' ][target ][package ]['frameworkReferences' ]:
176
+ frameworks .add (framework )
177
+ frameworkDir = os .path .join (
178
+ frameworksDir , framework )
179
+ if not os .path .exists (frameworkDir ):
180
+ os .makedirs (frameworkDir )
181
+ pf .write (' <ProjectReference Include="../../' +
182
+ frameworksDirName + '/' + framework + '/' + framework + '.csproj" />\n ' )
67
183
68
- print ("\n * Creating new input project" )
69
- run_cmd (['dotnet' , 'new' , template , "-f" , "net8.0" , "--language" , "C#" , '--name' ,
70
- projectNameIn , '--output' , projectDirIn ])
71
- helpers .remove_files (projectDirIn , '.cs' )
72
-
73
- print ("\n * Adding reference to package: " + nuget )
74
- cmd = ['dotnet' , 'add' , projectDirIn , 'package' , nuget ]
75
- if (version != "latest" ):
76
- cmd .append ('--version' )
77
- cmd .append (version )
78
- run_cmd (cmd )
79
-
80
- sdk_version = '8.0.100'
81
- print ("\n * Creating new global.json file and setting SDK to " + sdk_version )
82
- run_cmd (['dotnet' , 'new' , 'globaljson' , '--force' , '--sdk-version' , sdk_version , '--output' , workDir ])
83
-
84
- print ("\n * Running stub generator" )
85
- helpers .run_cmd_cwd (['dotnet' , 'run' , '--project' , thisDir + '/../../extractor/Semmle.Extraction.CSharp.DependencyStubGenerator/Semmle.Extraction.CSharp.DependencyStubGenerator.csproj' ], projectDirIn )
86
-
87
- print ("\n * Creating new raw output project" )
88
- rawSrcOutputDirName = 'src'
89
- rawSrcOutputDir = os .path .join (rawOutputDir , rawSrcOutputDirName )
90
- run_cmd (['dotnet' , 'new' , template , "--language" , "C#" ,
91
- '--name' , rawSrcOutputDirName , '--output' , rawSrcOutputDir ])
92
- helpers .remove_files (rawSrcOutputDir , '.cs' )
93
-
94
- # copy each file from projectDirIn to rawSrcOutputDir
95
- pathInfos = {}
96
- codeqlStubsDir = os .path .join (projectDirIn , 'codeql_csharp_stubs' )
97
- for root , dirs , files in os .walk (codeqlStubsDir ):
98
- for file in files :
99
- if file .endswith ('.cs' ):
100
- path = os .path .join (root , file )
101
- relPath , _ = os .path .splitext (os .path .relpath (path , codeqlStubsDir ))
102
- origDllPath = "/" + relPath + ".dll"
103
- pathInfos [origDllPath ] = os .path .join (rawSrcOutputDir , file )
104
- shutil .copy2 (path , rawSrcOutputDir )
105
-
106
- print ("\n --> Generated stub files: " + rawSrcOutputDir )
107
-
108
- print ("\n * Formatting files" )
109
- run_cmd (['dotnet' , 'format' , 'whitespace' , rawSrcOutputDir ])
110
-
111
- print ("\n --> Generated (formatted) stub files: " + rawSrcOutputDir )
112
-
113
- print ("\n * Processing project.assets.json to generate folder structure" )
114
- stubsDirName = 'stubs'
115
- stubsDir = os .path .join (outputDir , stubsDirName )
116
- os .makedirs (stubsDir )
117
-
118
- frameworksDirName = '_frameworks'
119
- frameworksDir = os .path .join (stubsDir , frameworksDirName )
120
-
121
- frameworks = set ()
122
- copiedFiles = set ()
123
-
124
- assetsJsonFile = os .path .join (projectDirIn , 'obj' , 'project.assets.json' )
125
- with open (assetsJsonFile ) as json_data :
126
- data = json .load (json_data )
127
- if len (data ['targets' ]) > 1 :
128
- print ("ERROR: More than one target found in " + assetsJsonFile )
129
- exit (1 )
130
- target = list (data ['targets' ].keys ())[0 ]
131
- print ("Found target: " + target )
132
- for package in data ['targets' ][target ].keys ():
133
- parts = package .split ('/' )
134
- name = parts [0 ]
135
- version = parts [1 ]
136
- packageDir = os .path .join (stubsDir , name , version )
137
- if not os .path .exists (packageDir ):
138
- os .makedirs (packageDir )
139
- print (' * Processing package: ' + name + '/' + version )
140
- with open (os .path .join (packageDir , name + '.csproj' ), 'a' ) as pf :
184
+ pf .write (' <ProjectReference Include="../../' +
185
+ frameworksDirName + '/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj" />\n ' )
141
186
142
- write_csproj_prefix ( pf )
143
- pf .write (' <ItemGroup >\n ' )
187
+ pf . write ( ' </ItemGroup> \n ' )
188
+ pf .write ('</Project >\n ' )
144
189
145
- dlls = set ()
146
- if 'compile' in data ['targets' ][target ][package ]:
147
- for dll in data ['targets' ][target ][package ]['compile' ]:
148
- dlls .add (
149
- (name + '/' + version + '/' + dll ).lower ())
150
- if 'runtime' in data ['targets' ][target ][package ]:
151
- for dll in data ['targets' ][target ][package ]['runtime' ]:
152
- dlls .add ((name + '/' + version + '/' + dll ).lower ())
190
+ # Processing references frameworks
191
+ for framework in frameworks :
192
+ with open (os .path .join (frameworksDir , framework , framework + '.csproj' ), 'a' ) as pf :
153
193
154
- for pathInfo in pathInfos :
155
- for dll in dlls :
156
- if pathInfo .lower ().endswith (dll ):
194
+ write_csproj_prefix (pf )
195
+ pf .write (' <ItemGroup>\n ' )
196
+ pf .write (
197
+ ' <ProjectReference Include="../Microsoft.NETCore.App/Microsoft.NETCore.App.csproj" />\n ' )
198
+ pf .write (' </ItemGroup>\n ' )
199
+ pf .write ('</Project>\n ' )
200
+
201
+ for pathInfo in pathInfos :
202
+ if framework .lower () + '.ref' in pathInfo .lower ():
157
203
copiedFiles .add (pathInfo )
158
- shutil .copy2 (pathInfos [pathInfo ], packageDir )
204
+ shutil .copy2 (pathInfos [pathInfo ], os .path .join (
205
+ frameworksDir , framework ))
206
+
207
+ # Processing assemblies in Microsoft.NETCore.App.Ref
208
+ frameworkDir = os .path .join (frameworksDir , 'Microsoft.NETCore.App' )
209
+ if not os .path .exists (frameworkDir ):
210
+ os .makedirs (frameworkDir )
211
+ with open (os .path .join (frameworksDir , 'Microsoft.NETCore.App' , 'Microsoft.NETCore.App.csproj' ), 'a' ) as pf :
212
+ write_csproj_prefix (pf )
213
+ pf .write ('</Project>\n ' )
159
214
160
- if 'dependencies' in data ['targets' ][target ][package ]:
161
- for dependency in data ['targets' ][target ][package ]['dependencies' ].keys ():
162
- depVersion = data ['targets' ][target ][package ]['dependencies' ][dependency ]
163
- pf .write (' <ProjectReference Include="../../' +
164
- dependency + '/' + depVersion + '/' + dependency + '.csproj" />\n ' )
165
-
166
- if 'frameworkReferences' in data ['targets' ][target ][package ]:
167
- if not os .path .exists (frameworksDir ):
168
- os .makedirs (frameworksDir )
169
- for framework in data ['targets' ][target ][package ]['frameworkReferences' ]:
170
- frameworks .add (framework )
171
- frameworkDir = os .path .join (
172
- frameworksDir , framework )
173
- if not os .path .exists (frameworkDir ):
174
- os .makedirs (frameworkDir )
175
- pf .write (' <ProjectReference Include="../../' +
176
- frameworksDirName + '/' + framework + '/' + framework + '.csproj" />\n ' )
215
+ for pathInfo in pathInfos :
216
+ if 'microsoft.netcore.app.ref/' in pathInfo .lower ():
217
+ copiedFiles .add (pathInfo )
218
+ shutil .copy2 (pathInfos [pathInfo ], frameworkDir )
177
219
178
- pf .write (' <ProjectReference Include="../../' +
179
- frameworksDirName + '/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj" />\n ' )
220
+ for pathInfo in pathInfos :
221
+ if pathInfo not in copiedFiles :
222
+ print ('Not copied to nuget or framework folder: ' + pathInfo )
223
+ othersDir = os .path .join (stubsDir , 'others' )
224
+ if not os .path .exists (othersDir ):
225
+ os .makedirs (othersDir )
226
+ shutil .copy2 (pathInfos [pathInfo ], othersDir )
180
227
181
- pf .write (' </ItemGroup>\n ' )
182
- pf .write ('</Project>\n ' )
228
+ print ("\n --> Generated structured stub files: " + stubsDir )
183
229
184
- # Processing references frameworks
185
- for framework in frameworks :
186
- with open (os .path .join (frameworksDir , framework , framework + '.csproj' ), 'a' ) as pf :
187
230
188
- write_csproj_prefix (pf )
189
- pf .write (' <ItemGroup>\n ' )
190
- pf .write (
191
- ' <ProjectReference Include="../Microsoft.NETCore.App/Microsoft.NETCore.App.csproj" />\n ' )
192
- pf .write (' </ItemGroup>\n ' )
193
- pf .write ('</Project>\n ' )
194
231
195
- for pathInfo in pathInfos :
196
- if framework .lower () + '.ref' in pathInfo .lower ():
197
- copiedFiles .add (pathInfo )
198
- shutil .copy2 (pathInfos [pathInfo ], os .path .join (
199
- frameworksDir , framework ))
200
-
201
- # Processing assemblies in Microsoft.NETCore.App.Ref
202
- frameworkDir = os .path .join (frameworksDir , 'Microsoft.NETCore.App' )
203
- if not os .path .exists (frameworkDir ):
204
- os .makedirs (frameworkDir )
205
- with open (os .path .join (frameworksDir , 'Microsoft.NETCore.App' , 'Microsoft.NETCore.App.csproj' ), 'a' ) as pf :
206
- write_csproj_prefix (pf )
207
- pf .write ('</Project>\n ' )
208
-
209
- for pathInfo in pathInfos :
210
- if 'microsoft.netcore.app.ref/' in pathInfo .lower ():
211
- copiedFiles .add (pathInfo )
212
- shutil .copy2 (pathInfos [pathInfo ], frameworkDir )
213
-
214
- for pathInfo in pathInfos :
215
- if pathInfo not in copiedFiles :
216
- print ('Not copied to nuget or framework folder: ' + pathInfo )
217
- othersDir = os .path .join (stubsDir , 'others' )
218
- if not os .path .exists (othersDir ):
219
- os .makedirs (othersDir )
220
- shutil .copy2 (pathInfos [pathInfo ], othersDir )
221
-
222
- print ("\n --> Generated structured stub files: " + stubsDir )
232
+
233
+
234
+ generator = Generator (thisScript , relativeWorkDir , template )
235
+ generator .add_nuget (nuget , version )
236
+ generator .make_stubs ()
237
+
223
238
224
239
exit (0 )
0 commit comments