├── .gitattributes
├── .gitignore
├── .gitmodules
├── GitInfo.txt
├── LICENSE
├── README.md
├── VisualStudio.AndroidX.Migration.Console
├── App.config
├── ConsoleProgress.cs
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
└── VisualStudio.AndroidX.Migration.Console.csproj
├── VisualStudio.AndroidX.Migration.Core
├── Directory.Build.targets
├── MigrationRunner.cs
├── ProjectRewriter.cs
├── Rewriters
│ ├── MigrationRewriter.cs
│ ├── NamespaceRewriter.cs
│ ├── SemanticRewriter.cs
│ └── TypeRewriter.cs
├── TranslationResolver.cs
├── VisualStudio.AndroidX.Migration.Core.csproj
└── xamarin.snk
├── VisualStudio.AndroidX.Migration.Test
├── NameTests.cs
├── NamespaceTests.cs
├── NullProgress.cs
├── ProjectTests.cs
├── ResolverTests.cs
├── TestBase.cs
└── VisualStudio.AndroidX.Migration.Tests.csproj
├── VisualStudio.AndroidX.Migration.sln
├── azure-pipelines.yml
└── build.cake
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
3 | *.sh eol=lf
4 | gradlew eol=lf
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | tools
7 | !tools/packages.config
8 | .gradle
9 | output
10 | externals
11 | Resource.designer.cs
12 |
13 | # User-specific files
14 | *.suo
15 | *.user
16 | *.userosscache
17 | *.sln.docstates
18 |
19 | # User-specific files (MonoDevelop/Xamarin Studio)
20 | *.userprefs
21 |
22 | # Build results
23 | [Dd]ebug/
24 | [Dd]ebugPublic/
25 | [Rr]elease/
26 | [Rr]eleases/
27 | x64/
28 | x86/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Ll]og/
33 |
34 | # Visual Studio 2015/2017 cache/options directory
35 | .vs/
36 | # Uncomment if you have tasks that create the project's static files in wwwroot
37 | #wwwroot/
38 |
39 | # Visual Studio 2017 auto generated files
40 | Generated\ Files/
41 |
42 | # MSTest test Results
43 | [Tt]est[Rr]esult*/
44 | [Bb]uild[Ll]og.*
45 |
46 | # NUNIT
47 | *.VisualState.xml
48 | TestResult.xml
49 |
50 | # Build Results of an ATL Project
51 | [Dd]ebugPS/
52 | [Rr]eleasePS/
53 | dlldata.c
54 |
55 | # Benchmark Results
56 | BenchmarkDotNet.Artifacts/
57 |
58 | # .NET Core
59 | project.lock.json
60 | project.fragment.lock.json
61 | artifacts/
62 | **/Properties/launchSettings.json
63 |
64 | # StyleCop
65 | StyleCopReport.xml
66 |
67 | # Files built by Visual Studio
68 | *_i.c
69 | *_p.c
70 | *_i.h
71 | *.ilk
72 | *.meta
73 | *.obj
74 | *.iobj
75 | *.pch
76 | *.pdb
77 | *.ipdb
78 | *.pgc
79 | *.pgd
80 | *.rsp
81 | *.sbr
82 | *.tlb
83 | *.tli
84 | *.tlh
85 | *.tmp
86 | *.tmp_proj
87 | *.log
88 | *.vspscc
89 | *.vssscc
90 | .builds
91 | *.pidb
92 | *.svclog
93 | *.scc
94 |
95 | # Chutzpah Test files
96 | _Chutzpah*
97 |
98 | # Visual C++ cache files
99 | ipch/
100 | *.aps
101 | *.ncb
102 | *.opendb
103 | *.opensdf
104 | *.sdf
105 | *.cachefile
106 | *.VC.db
107 | *.VC.VC.opendb
108 |
109 | # Visual Studio profiler
110 | *.psess
111 | *.vsp
112 | *.vspx
113 | *.sap
114 |
115 | # Visual Studio Trace Files
116 | *.e2e
117 |
118 | # TFS 2012 Local Workspace
119 | $tf/
120 |
121 | # Guidance Automation Toolkit
122 | *.gpState
123 |
124 | # ReSharper is a .NET coding add-in
125 | _ReSharper*/
126 | *.[Rr]e[Ss]harper
127 | *.DotSettings.user
128 |
129 | # JustCode is a .NET coding add-in
130 | .JustCode
131 |
132 | # TeamCity is a build add-in
133 | _TeamCity*
134 |
135 | # DotCover is a Code Coverage Tool
136 | *.dotCover
137 |
138 | # AxoCover is a Code Coverage Tool
139 | .axoCover/*
140 | !.axoCover/settings.json
141 |
142 | # Visual Studio code coverage results
143 | *.coverage
144 | *.coveragexml
145 |
146 | # NCrunch
147 | _NCrunch_*
148 | .*crunch*.local.xml
149 | nCrunchTemp_*
150 |
151 | # MightyMoose
152 | *.mm.*
153 | AutoTest.Net/
154 |
155 | # Web workbench (sass)
156 | .sass-cache/
157 |
158 | # Installshield output folder
159 | [Ee]xpress/
160 |
161 | # DocProject is a documentation generator add-in
162 | DocProject/buildhelp/
163 | DocProject/Help/*.HxT
164 | DocProject/Help/*.HxC
165 | DocProject/Help/*.hhc
166 | DocProject/Help/*.hhk
167 | DocProject/Help/*.hhp
168 | DocProject/Help/Html2
169 | DocProject/Help/html
170 |
171 | # Click-Once directory
172 | publish/
173 |
174 | # Publish Web Output
175 | *.[Pp]ublish.xml
176 | *.azurePubxml
177 | # Note: Comment the next line if you want to checkin your web deploy settings,
178 | # but database connection strings (with potential passwords) will be unencrypted
179 | *.pubxml
180 | *.publishproj
181 |
182 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
183 | # checkin your Azure Web App publish settings, but sensitive information contained
184 | # in these scripts will be unencrypted
185 | PublishScripts/
186 |
187 | # NuGet Packages
188 | *.nupkg
189 | # The packages folder can be ignored because of Package Restore
190 | **/[Pp]ackages/*
191 | # except build/, which is used as an MSBuild target.
192 | !**/[Pp]ackages/build/
193 | # Uncomment if necessary however generally it will be regenerated when needed
194 | #!**/[Pp]ackages/repositories.config
195 | # NuGet v3's project.json files produces more ignorable files
196 | *.nuget.props
197 | *.nuget.targets
198 |
199 | # Microsoft Azure Build Output
200 | csx/
201 | *.build.csdef
202 |
203 | # Microsoft Azure Emulator
204 | ecf/
205 | rcf/
206 |
207 | # Windows Store app package directories and files
208 | AppPackages/
209 | BundleArtifacts/
210 | Package.StoreAssociation.xml
211 | _pkginfo.txt
212 | *.appx
213 |
214 | # Visual Studio cache files
215 | # files ending in .cache can be ignored
216 | *.[Cc]ache
217 | # but keep track of directories ending in .cache
218 | !*.[Cc]ache/
219 |
220 | # Others
221 | ClientBin/
222 | ~$*
223 | *~
224 | *.dbmdl
225 | *.dbproj.schemaview
226 | *.jfm
227 | *.pfx
228 | *.publishsettings
229 | orleans.codegen.cs
230 |
231 | # Including strong name files can present a security risk
232 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
233 | #*.snk
234 |
235 | # Since there are multiple workflows, uncomment next line to ignore bower_components
236 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
237 | #bower_components/
238 |
239 | # RIA/Silverlight projects
240 | Generated_Code/
241 |
242 | # Backup & report files from converting an old project file
243 | # to a newer Visual Studio version. Backup files are not needed,
244 | # because we have git ;-)
245 | _UpgradeReport_Files/
246 | Backup*/
247 | UpgradeLog*.XML
248 | UpgradeLog*.htm
249 | ServiceFabricBackup/
250 | *.rptproj.bak
251 |
252 | # SQL Server files
253 | *.mdf
254 | *.ldf
255 | *.ndf
256 |
257 | # Business Intelligence projects
258 | *.rdl.data
259 | *.bim.layout
260 | *.bim_*.settings
261 | *.rptproj.rsuser
262 |
263 | # Microsoft Fakes
264 | FakesAssemblies/
265 |
266 | # GhostDoc plugin setting file
267 | *.GhostDoc.xml
268 |
269 | # Node.js Tools for Visual Studio
270 | .ntvs_analysis.dat
271 | node_modules/
272 |
273 | # Visual Studio 6 build log
274 | *.plg
275 |
276 | # Visual Studio 6 workspace options file
277 | *.opt
278 |
279 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
280 | *.vbw
281 |
282 | # Visual Studio LightSwitch build output
283 | **/*.HTMLClient/GeneratedArtifacts
284 | **/*.DesktopClient/GeneratedArtifacts
285 | **/*.DesktopClient/ModelManifest.xml
286 | **/*.Server/GeneratedArtifacts
287 | **/*.Server/ModelManifest.xml
288 | _Pvt_Extensions
289 |
290 | # Paket dependency manager
291 | .paket/paket.exe
292 | paket-files/
293 |
294 | # FAKE - F# Make
295 | .fake/
296 |
297 | # JetBrains Rider
298 | *.sln.iml
299 |
300 | # CodeRush
301 | .cr/
302 |
303 | # Python Tools for Visual Studio (PTVS)
304 | __pycache__/
305 | *.pyc
306 |
307 | # Cake - Uncomment if you are using it
308 | # tools/**
309 | # !tools/packages.config
310 |
311 | # Tabs Studio
312 | *.tss
313 |
314 | # Telerik's JustMock configuration file
315 | *.jmconfig
316 |
317 | # BizTalk build output
318 | *.btp.cs
319 | *.btm.cs
320 | *.odx.cs
321 | *.xsd.cs
322 |
323 | # OpenCover UI analysis results
324 | OpenCover/
325 |
326 | # Azure Stream Analytics local run output
327 | ASALocalRun/
328 |
329 | # MSBuild Binary and Structured Log
330 | *.binlog
331 |
332 | # NVidia Nsight GPU debugger configuration file
333 | *.nvuser
334 |
335 | # MFractors (Xamarin productivity tool) working folder
336 | .mfractor/
337 |
338 | # Compiled class file
339 | *.class
340 |
341 | # Log file
342 | *.log
343 |
344 | # BlueJ files
345 | *.ctxt
346 |
347 | # Mobile Tools for Java (J2ME)
348 | .mtj.tmp/
349 |
350 | # Package Files #
351 | *.jar
352 | *.war
353 | *.nar
354 | *.ear
355 | *.zip
356 | *.tar.gz
357 | *.rar
358 |
359 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
360 | hs_err_pid*
361 |
362 | *.DS_Store
363 |
364 | # Built application files
365 | *.apk
366 | *.ap_
367 | *.aab
368 |
369 | # Files for the ART/Dalvik VM
370 | *.dex
371 |
372 | # Java class files
373 | *.class
374 |
375 | # Generated files
376 | bin/
377 | gen/
378 | out/
379 |
380 | # Gradle files
381 | .gradle/
382 | build/
383 |
384 | # Local configuration file (sdk path, etc)
385 | local.properties
386 |
387 | # Proguard folder generated by Eclipse
388 | proguard/
389 |
390 | # Log Files
391 | *.log
392 |
393 | # Android Studio Navigation editor temp files
394 | .navigation/
395 |
396 | # Android Studio captures folder
397 | captures/
398 |
399 | # IntelliJ
400 | .idea/workspace.xml
401 | .idea/tasks.xml
402 | .idea/gradle.xml
403 | .idea/assetWizardSettings.xml
404 | .idea/dictionaries
405 | .idea/libraries
406 | .idea/caches
407 | # Android Studio 3 in .gitignore file.
408 | .idea/caches/build_file_checksums.ser
409 | .idea/modules.xml
410 |
411 | # Keystore files
412 | # Uncomment the following lines if you do not want to check your keystore files in.
413 | #*.jks
414 | #*.keystore
415 |
416 | # External native build folder generated in Android Studio 2.2 and later
417 | .externalNativeBuild
418 |
419 | # Google Services (e.g. APIs or Firebase)
420 | # google-services.json
421 |
422 | # Freeline
423 | freeline.py
424 | freeline/
425 | freeline_project_description.json
426 |
427 | # fastlane
428 | fastlane/report.xml
429 | fastlane/Preview.html
430 | fastlane/screenshots
431 | fastlane/test_output
432 | fastlane/readme.md
433 |
434 | # Version control
435 | vcs.xml
436 |
437 | # lint
438 | lint/intermediates/
439 | lint/generated/
440 | lint/outputs/
441 | lint/tmp/
442 | # lint/reports/
443 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "externals/Java.Interop"]
2 | path = externals/Java.Interop
3 | url = https://github.com/xamarin/java.interop
4 |
--------------------------------------------------------------------------------
/GitInfo.txt:
--------------------------------------------------------------------------------
1 | 1.0.9
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Microsoft Corporation
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | MOVED: https://github.com/xamarin/AndroidX/tree/master/source/migration
2 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Console/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Console/ConsoleProgress.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace VisualStudio.AndroidX.Migration
8 | {
9 | class ConsoleProgress : IProgress
10 | {
11 | public void Report(string value)
12 | {
13 | Console.WriteLine(value);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Console/Program.cs:
--------------------------------------------------------------------------------
1 | using Core;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace VisualStudio.AndroidX.Migration
9 | {
10 | class Program
11 | {
12 | static void Main(string[] args)
13 | {
14 | var runner = new MigrationRunner(new ConsoleProgress());
15 | runner.MigrateSolution(args[0]);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Console/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Console")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Console")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("29e0e329-b35e-4a6c-b24d-e4700c6ba58f")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Console/VisualStudio.AndroidX.Migration.Console.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {29E0E329-B35E-4A6C-B24D-E4700C6BA58F}
8 | Exe
9 | Console
10 | Console
11 | v4.7.2
12 | 512
13 | true
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | 16.0.461
56 |
57 |
58 | 16.0.461
59 |
60 |
61 | 1.2.2
62 |
63 |
64 | 16.0.461
65 |
66 |
67 | 16.0.461
68 |
69 |
70 |
71 |
72 | {297b120f-de08-4460-bce6-5b2a74535c2d}
73 | VisualStudio.AndroidX.Migration.Core
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Core/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | true
5 |
6 |
7 |
8 | $(NoWarn);NU5105
9 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
23 |
24 |
26 |
27 |
28 |
29 | $(GitSemVerMajor).$(GitSemVerMinor).$(GitSemVerPatch)
30 | $(GitSemVerDashLabel)+@(VersionMetadata -> '%(Identity)', '-')
31 |
32 | $(VersionPrefix)
33 | $(AssemblyVersion)
34 | $(VersionPrefix)$(VersionSuffix)
35 | $(InformationalVersion)
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Core/MigrationRunner.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.MSBuild;
3 | using System;
4 | using System.Linq;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using VisualStudio.AndroidX.Migration;
8 | using System.Reflection;
9 |
10 | namespace Core
11 | {
12 | public class MigrationRunner
13 | {
14 | private TranslationResolver resolver;
15 | private IProgress progress;
16 |
17 | public MigrationRunner(IProgress progress)
18 | {
19 | var androidDirectory = Path.Combine(Path.GetDirectoryName(typeof(MigrationRunner).Assembly.Location), "Assemblies", "Android");
20 | var androidXDirectory = Path.Combine(Path.GetDirectoryName(typeof(MigrationRunner).Assembly.Location), "Assemblies", "AndroidX");
21 |
22 | resolver = new TranslationResolver(null, null);
23 | this.progress = progress;
24 | }
25 |
26 | public void MigrateSolution(string solutionPath, bool addMigrationNuget = false, bool migrateCode = false)
27 | {
28 | var workspace = MSBuildWorkspace.Create();
29 | workspace.WorkspaceFailed += (s,e) => { Console.WriteLine(e.Diagnostic.Message); };
30 | var solution = workspace.OpenSolutionAsync(solutionPath).Result;
31 |
32 | var newSolution = solution;
33 |
34 | progress.Report("Migrating Solution");
35 |
36 | foreach (var project in solution.Projects)
37 | {
38 | progress.Report(project.Name);
39 | newSolution = MigrateProject(project, newSolution, addMigrationNuget, migrateCode);
40 | }
41 |
42 | workspace.TryApplyChanges(newSolution);
43 | }
44 |
45 | public Solution MigrateProject(Project project, Solution solution, bool addMigrationNuget, bool migrateCode)
46 | {
47 | //foreach (var reference in project.MetadataReferences)
48 | // if (resolver.Nugets.Keys.Contains(Path.GetFileNameWithoutExtension(reference.Display)) && !resolver.AndroidAssemblies.Any(a => Path.GetFileName(a.CodeBase) == Path.GetFileName(reference.Display)))
49 | // resolver.AndroidAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(reference.Display));
50 | //solution = MigrateDocuments(project, solution);
51 | MigrateNugets(project, addMigrationNuget);
52 | //foreach (var reference in project.MetadataReferences)
53 | // if (resolver.Nugets.Values.Any(v => v.Key == (Path.GetFileNameWithoutExtension(reference.Display))) && !resolver.AndroidXAssemblies.Any(a => Path.GetFileName(a.CodeBase) == Path.GetFileName(reference.Display)))
54 | // resolver.AndroidXAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(reference.Display));
55 | //solution = PostProcessProject(project, solution);
56 | Jetify(project);
57 |
58 | return solution;
59 | }
60 |
61 | private Solution MigrateDocuments(Project project, Solution solution)
62 | {
63 | var rewriters = new List
64 | {
65 | new TypeRewriter(resolver, progress),
66 | new SemanticRewriter(resolver, progress)
67 | };
68 |
69 | foreach (var document in project.Documents)
70 | {
71 | solution = MigrateDocument(document, solution, rewriters);
72 | }
73 |
74 | return solution;
75 | }
76 |
77 | private void MigrateNugets(Project project, bool addMigrationNuget)
78 | {
79 | var rewriter = new ProjectRewriter(resolver, progress);
80 | rewriter.RewriteProject(project.FilePath, addMigrationNuget);
81 | }
82 |
83 | private Solution PostProcessProject(Project project, Solution solution)
84 | {
85 | var rewriters = new List
86 | {
87 | new NamespaceRewriter(resolver, progress)
88 | };
89 |
90 | foreach (var document in project.Documents)
91 | {
92 | solution = MigrateDocument(document, solution, rewriters);
93 | }
94 |
95 | return solution;
96 | }
97 |
98 | private Solution MigrateDocument(Document document, Solution solution, List rewriters)
99 | {
100 | foreach(var rewriter in rewriters)
101 | {
102 | solution = rewriter.Visit(solution, document);
103 | }
104 |
105 | return solution;
106 | }
107 |
108 | private void Jetify(Project project)
109 | {
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Core/ProjectRewriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Linq;
5 | using System.Xml;
6 | using System.IO;
7 |
8 | namespace VisualStudio.AndroidX.Migration
9 | {
10 | public class ProjectRewriter
11 | {
12 | private ITranslationResolver resolver;
13 | private IProgress progress;
14 |
15 | public ProjectRewriter(ITranslationResolver resolver, IProgress progress)
16 | {
17 | this.resolver = resolver;
18 | this.progress = progress;
19 | }
20 |
21 | public void RewriteProject(string projectFileName, bool addMigrationNuget)
22 | {
23 | var xml = RewriteCSProj(File.ReadAllText(projectFileName), addMigrationNuget);
24 | File.WriteAllText(projectFileName, xml);
25 | }
26 |
27 | public string RewriteCSProj(string csproj, bool addMigrationNuget = false)
28 | {
29 | bool hasAndroidNugets = false;
30 | var doc = new XmlDocument();
31 | doc.PreserveWhitespace = true;
32 | doc.LoadXml(csproj);
33 | var itemGroups = doc.GetElementsByTagName("ItemGroup");
34 | foreach (var group in itemGroups.OfType())
35 | {
36 | var references = group.ChildNodes.OfType().Where(c => c.Name == "PackageReference");
37 | foreach (var reference in references)
38 | {
39 | var androidNuget = reference.Attributes["Include"].InnerText;
40 | if (resolver.Nugets.ContainsKey(androidNuget))
41 | {
42 | hasAndroidNugets = true;
43 | progress?.Report($"Migrating Nuget {androidNuget}");
44 | reference.Attributes["Include"].InnerText = resolver.Nugets[reference.Attributes["Include"].InnerText].Key;
45 | var androidXVersion = resolver.Nugets[androidNuget].Value;
46 | if (reference.HasAttribute("Version"))
47 | {
48 | reference.Attributes["Version"].InnerText = androidXVersion;
49 | }
50 | else
51 | {
52 | var version = reference.ChildNodes.OfType().FirstOrDefault(n => n.Name == "Version");
53 | if (version != null)
54 | {
55 | version.InnerText = androidXVersion;
56 | }
57 | else
58 | {
59 | var versionAttribute = doc.CreateAttribute("Version");
60 | versionAttribute.InnerText = androidXVersion;
61 | reference.Attributes.Append(versionAttribute);
62 | }
63 | }
64 | }
65 | }
66 | if (addMigrationNuget && hasAndroidNugets)
67 | {
68 | addMigrationNuget = false;
69 | var node = doc.CreateNode(XmlNodeType.Element, "PackageReference", references.First().NamespaceURI);
70 | var includeAttribute = doc.CreateAttribute("Include");
71 | includeAttribute.Value = "Xamarin.AndroidX.Migration";
72 | node.Attributes.Append(includeAttribute);
73 | var versionAttribute = doc.CreateAttribute("Version");
74 | versionAttribute.Value = "1.0.0-preview03";
75 | node.Attributes.Append(versionAttribute);
76 | group.AppendChild(node);
77 | }
78 | }
79 | return doc.InnerXml;
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Core/Rewriters/MigrationRewriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.CodeAnalysis;
3 | using Microsoft.CodeAnalysis.CSharp;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace VisualStudio.AndroidX.Migration
8 | {
9 | public abstract class MigrationRewriter : CSharpSyntaxRewriter, IRewriter
10 | {
11 | public SemanticModel Semantic { get; set; }
12 | protected ITranslationResolver resolver;
13 | private IProgress progress;
14 |
15 | internal abstract bool UsesSemantic { get; }
16 |
17 | public MigrationRewriter(ITranslationResolver resolver, IProgress progress)
18 | {
19 | this.resolver = resolver;
20 | this.progress = progress;
21 | }
22 |
23 | public Solution Visit(Solution solution, Document document)
24 | {
25 | if (UsesSemantic)
26 | this.Semantic = document.Project.GetCompilationAsync().Result.GetSemanticModel(document.GetSyntaxRootAsync().Result.SyntaxTree);
27 | var root = this.Visit(document.GetSyntaxRootAsync().Result);
28 | return solution.WithDocumentSyntaxRoot(document.Id, root);
29 | }
30 |
31 | internal bool TryGetValue(string name, out string typeName)
32 | {
33 | typeName = string.Empty;
34 | if (resolver.FullTypeNames.ContainsKey(name))
35 | {
36 | typeName = resolver.FullTypeNames[name];
37 | return true;
38 | }
39 |
40 | return false;
41 | }
42 |
43 | }
44 |
45 | public interface IRewriter
46 | {
47 | Solution Visit(Solution solution, Document document);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Core/Rewriters/NamespaceRewriter.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.CSharp;
3 | using Microsoft.CodeAnalysis.CSharp.Syntax;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace VisualStudio.AndroidX.Migration
9 | {
10 | public class NamespaceRewriter : MigrationRewriter
11 | {
12 | private ITranslationResolver assemblyResolver;
13 |
14 | internal override bool UsesSemantic => false;
15 |
16 | public NamespaceRewriter(ITranslationResolver assemblyResolver, IProgress progress) : base(assemblyResolver, progress)
17 | {
18 | this.assemblyResolver = assemblyResolver;
19 | }
20 |
21 | public override SyntaxNode VisitUsingDirective(UsingDirectiveSyntax node)
22 | {
23 | var name = node.Name.WithoutTrivia().ToFullString();
24 | if (assemblyResolver.Namespaces.ContainsKey(name))
25 | return base.VisitUsingDirective(node.WithName(SyntaxFactory.ParseName(assemblyResolver.Namespaces[name])
26 | .WithLeadingTrivia(node.Name.GetLeadingTrivia())
27 | .WithTrailingTrivia(node.Name.GetTrailingTrivia())));
28 | else
29 | return base.VisitUsingDirective(node);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Core/Rewriters/SemanticRewriter.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.CSharp;
3 | using Microsoft.CodeAnalysis.CSharp.Syntax;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace VisualStudio.AndroidX.Migration
9 | {
10 | public class SemanticRewriter : MigrationRewriter
11 | {
12 | private ITranslationResolver assemblyResolver;
13 |
14 | internal override bool UsesSemantic => true;
15 |
16 | public SemanticRewriter(ITranslationResolver assemblyResolver, IProgress progress) : base(assemblyResolver, progress)
17 | {
18 | this.assemblyResolver = assemblyResolver;
19 | }
20 |
21 | public override SyntaxNode VisitQualifiedName(QualifiedNameSyntax node)
22 | {
23 | var symbol = Semantic.GetSymbolInfo(node);
24 | if (symbol.Symbol != null && node.ToFullString() != symbol.Symbol.ToDisplayString())
25 | return SyntaxFactory.ParseName(symbol.Symbol.ToDisplayString())
26 | .WithLeadingTrivia(node.GetLeadingTrivia())
27 | .WithTrailingTrivia(node.GetTrailingTrivia());
28 | else
29 | return base.VisitQualifiedName(node);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Core/Rewriters/TypeRewriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Microsoft.CodeAnalysis;
5 | using Microsoft.CodeAnalysis.CSharp;
6 | using Microsoft.CodeAnalysis.CSharp.Syntax;
7 |
8 | namespace VisualStudio.AndroidX.Migration
9 | {
10 | public class TypeRewriter : MigrationRewriter
11 | {
12 | private ITranslationResolver assemblyResolver;
13 |
14 | internal override bool UsesSemantic => false;
15 |
16 | public TypeRewriter(ITranslationResolver assemblyResolver, IProgress progress) : base(assemblyResolver, progress)
17 | {
18 | this.assemblyResolver = assemblyResolver;
19 | }
20 |
21 | public override SyntaxNode VisitQualifiedName(QualifiedNameSyntax node)
22 | {
23 | var name = node.WithoutTrivia().ToFullString();
24 | if (TryGetValue(name, out var typeName))
25 | return SyntaxFactory.ParseName(typeName)
26 | .WithLeadingTrivia(node.GetLeadingTrivia())
27 | .WithTrailingTrivia(node.GetTrailingTrivia());
28 | else
29 | return base.VisitQualifiedName(node);
30 | }
31 |
32 | public override SyntaxNode VisitAttribute(AttributeSyntax node)
33 | {
34 | var typeName = string.Empty;
35 | var identifier = node.Name + "Attribute";
36 | if (TryGetValue(identifier, out typeName))
37 | {
38 | if (typeName.EndsWith("Attribute"))
39 | {
40 | typeName = typeName.Remove(typeName.Length - 9);
41 | return node.WithName(SyntaxFactory.ParseName(typeName)
42 | .WithLeadingTrivia(node.GetLeadingTrivia())
43 | .WithTrailingTrivia(node.GetTrailingTrivia()));
44 | }
45 | }
46 | return base.VisitAttribute(node);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Core/TranslationResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 |
8 | namespace VisualStudio.AndroidX.Migration
9 | {
10 | public class TranslationResolver : ITranslationResolver
11 | {
12 | int SupportNamespace = 0;
13 | int SupportTypeName = 1;
14 | int AndroidXNamespace = 2;
15 | int AndroidXTypeName = 3;
16 |
17 | int SupportNuget = 2;
18 | int AndroidXNuget = 3;
19 | int AndroidXVersion = 4;
20 |
21 | public TranslationResolver(IList androidAssemblyLocations, IList androidXAssemblyLocations)
22 | {
23 | Namespaces = new Dictionary();
24 | FullTypeNames = new Dictionary();
25 | Nugets = new Dictionary>();
26 |
27 | using (var mapping = this.GetType().Assembly.GetManifestResourceStream("VisualStudio.AndroidX.Migration.Core.Resources.androidx-mapping.csv"))
28 | {
29 | using (var reader = new StreamReader(mapping))
30 | {
31 | var line = reader.ReadLine(); //skip first line
32 | while ((line = reader.ReadLine()) != null)
33 | {
34 | var values = line.Split(',');
35 | if (values[SupportNamespace] != string.Empty && values[AndroidXNamespace] != string.Empty)
36 | {
37 | if (!Namespaces.Any(n => n.Key == values[SupportNamespace]))
38 | Namespaces.Add(values[SupportNamespace], values[AndroidXNamespace]);
39 |
40 | if (!FullTypeNames.Any(t => t.Key == $"{values[SupportNamespace]}.{values[SupportTypeName]}"))
41 | FullTypeNames.Add($"{values[SupportNamespace]}.{values[SupportTypeName]}", $"{values[AndroidXNamespace]}.{values[AndroidXTypeName]}");
42 | }
43 |
44 | }
45 | }
46 | }
47 |
48 | AndroidAssemblies = AddAssemblies(androidAssemblyLocations ?? new List(), AndroidAssemblies);
49 | AndroidXAssemblies = AddAssemblies(androidXAssemblyLocations ?? new List(), AndroidXAssemblies);
50 |
51 | using (var nugets = this.GetType().Assembly.GetManifestResourceStream("VisualStudio.AndroidX.Migration.Core.Resources.androidx-assemblies.csv"))
52 | {
53 | using (var reader = new StreamReader(nugets))
54 | {
55 | var line = reader.ReadLine(); //skip first line
56 | while ((line = reader.ReadLine()) != null)
57 | {
58 | var values = line.Split(',');
59 | if (!Nugets.Any(n => n.Key == values[SupportNuget]))
60 | Nugets.Add(values[SupportNuget], new KeyValuePair(values[AndroidXNuget], values[AndroidXVersion]));
61 | }
62 | }
63 | }
64 | }
65 |
66 | public IList AddAssemblies(IList assemblyLocations, IList assemblies)
67 | {
68 | assemblies = assemblies ?? new List();
69 | foreach (var assembly in assemblyLocations)
70 | assemblies.Add(Assembly.ReflectionOnlyLoadFrom(assembly));
71 |
72 | return assemblies;
73 | }
74 |
75 | public IList AndroidAssemblies { get; private set; }
76 |
77 | public IList AndroidXAssemblies { get; private set; }
78 |
79 | public Dictionary Namespaces { get; private set; }
80 |
81 | public Dictionary FullTypeNames { get; private set; }
82 |
83 | public Dictionary> Nugets { get; private set; }
84 | }
85 |
86 | public interface ITranslationResolver
87 | {
88 | IList AndroidAssemblies { get; }
89 | IList AndroidXAssemblies { get; }
90 |
91 | Dictionary Namespaces { get; }
92 | Dictionary FullTypeNames { get; }
93 |
94 | Dictionary> Nugets { get; }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Core/VisualStudio.AndroidX.Migration.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | VisualStudio.AndroidX.Migration.Core
5 | VisualStudio.AndroidX.Migration
6 | net472
7 |
8 | Xamarin.VisualStudio.AndroidX.Migration
9 | Migration Tools for Xamarin AndroidX (Visual Studio)
10 | This package provides a Roslyn based migrator to be used in Visual Studio and Visual Studio for Mac.
11 | This package provides a Roslyn based migrator to be used in Visual Studio and Visual Studio for Mac.
12 | Xamarin.AndroidX Xamarin Android Support AndroidX Migration VS VSMac
13 | Microsoft
14 | Microsoft
15 | https://go.microsoft.com/fwlink/?linkid=2099353
16 | https://go.microsoft.com/fwlink/?linkid=2099438
17 | true
18 | © Microsoft Corporation. All rights reserved.
19 | true
20 | xamarin.snk
21 | false
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Resources\androidx-assemblies.csv
34 | PreserveNewest
35 |
36 |
37 | Resources\androidx-mapping.csv
38 | PreserveNewest
39 |
40 |
41 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Core/xamarin.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xamarin/XamarinAndroidXMigration/425ee3d0c0f67d7993780b0e03f9a227bd327ece/VisualStudio.AndroidX.Migration.Core/xamarin.snk
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Test/NameTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using Microsoft.CodeAnalysis;
6 | using Xunit;
7 |
8 | namespace VisualStudio.AndroidX.Migration
9 | {
10 | public class NameTests : TestBase
11 | {
12 | [Fact]
13 | public void when_defining_fully_qualified_fields_then_replace_namespace()
14 | {
15 | var solution = CreateSolution(@"
16 | using System;
17 |
18 | namespace ClassLibrary1
19 | {
20 | public class Class1
21 | {
22 | Android.Arch.Lifecycle.ViewModelProviders modelProvider;
23 | }
24 | }");
25 |
26 | var methodFixer = new TypeRewriter(resolver, new NullProgress());
27 | solution = methodFixer.Visit(solution, GetFirstDocument(solution));
28 |
29 | var root = GetText(solution);
30 |
31 | Assert.Contains("AndroidX.Lifecycle.ViewModelProviders", root);
32 | Assert.DoesNotContain("Android.Arch.Lifecycle.ViewModelProviders", root);
33 | }
34 |
35 | [Fact]
36 | public void when_defining_fully_qualified_properties_then_replace_namespace()
37 | {
38 | var file = @"
39 | using System;
40 |
41 | namespace ClassLibrary1
42 | {
43 | public class Class1
44 | {
45 | Android.Arch.Lifecycle.ViewModelProviders modelProvider { get; set; }
46 | }
47 | }";
48 |
49 | var solution = CreateSolution(file);
50 |
51 | var methodFixer = new TypeRewriter(resolver, new NullProgress());
52 | solution = methodFixer.Visit(solution, GetFirstDocument(solution));
53 |
54 | var root = GetText(solution);
55 |
56 | Assert.Contains("AndroidX.Lifecycle.ViewModelProviders", root);
57 | Assert.DoesNotContain("Android.Arch.Lifecycle.ViewModelProviders", root);
58 | }
59 |
60 | [Fact]
61 | public void when_defining_fully_qualified_parameters_then_replace_namespace()
62 | {
63 | var solution = CreateSolution(@"
64 | using System;
65 |
66 | namespace ClassLibrary1
67 | {
68 | public class Class1
69 | {
70 | public void Method(Android.Arch.Lifecycle.ViewModelProviders modelProvider)
71 | {
72 | }
73 | }
74 | }");
75 |
76 | var methodFixer = new TypeRewriter(resolver, new NullProgress());
77 | solution = methodFixer.Visit(solution, GetFirstDocument(solution));
78 |
79 | var root = GetText(solution);
80 |
81 | Assert.Contains("public void Method(AndroidX.Lifecycle.ViewModelProviders modelProvider)", root);
82 | Assert.DoesNotContain("public void Method(Android.Arch.Lifecycle.ViewModelProviders modelProvider)", root);
83 | }
84 |
85 | [Fact]
86 | public void when_defining_fully_qualified_return_then_replace_namespace()
87 | {
88 | var solution = CreateSolution(@"
89 | using System;
90 |
91 | namespace ClassLibrary1
92 | {
93 | public class Class1
94 | {
95 | public Android.Arch.Lifecycle.ViewModelProviders Method()
96 | {
97 | return null;
98 | }
99 | }
100 | }");
101 |
102 | var methodFixer = new TypeRewriter(resolver, new NullProgress());
103 | solution = methodFixer.Visit(solution, GetFirstDocument(solution));
104 |
105 | var root = GetText(solution);
106 |
107 | Assert.Contains("AndroidX.Lifecycle.ViewModelProviders", root);
108 | Assert.DoesNotContain("Android.Arch.Lifecycle.ViewModelProviders", root);
109 | }
110 |
111 |
112 | [Fact]
113 | public void when_defining_attribute_then_replace_attribute_name()
114 | {
115 | var solution = CreateSolution(@"
116 | using System;
117 |
118 | namespace ClassLibrary1
119 | {
120 | [Android.Support.V17.Leanback.Widget.Visibility]
121 | public class Class1
122 | {
123 | }
124 | }");
125 |
126 | var methodFixer = new TypeRewriter(resolver, new NullProgress());
127 | solution = methodFixer.Visit(solution, GetFirstDocument(solution));
128 |
129 | var root = GetText(solution);
130 |
131 | Assert.Contains("AndroidX.Leanback.Widget.Visibility", root);
132 | Assert.DoesNotContain("Android.Support.V17.Leanback.Widget.Visibility", root);
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Test/NamespaceTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Xunit;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace VisualStudio.AndroidX.Migration
11 | {
12 | public class NamespaceTests : TestBase
13 | {
14 | [Fact]
15 | public void when_defining_namespaces_then_replace_namespace()
16 | {
17 | var solution = CreateSolution(@"
18 | using System;
19 | using Android.Arch.Lifecycle;
20 |
21 | namespace ClassLibrary1
22 | {
23 | public class Class1
24 | {
25 | }
26 | }");
27 |
28 | var methodFixer = new NamespaceRewriter(resolver, new NullProgress());
29 | solution = methodFixer.Visit(solution, GetFirstDocument(solution));
30 |
31 | var root = GetText(solution);
32 |
33 | Assert.Contains("using AndroidX.Lifecycle;", root);
34 | Assert.DoesNotContain("using Android.Arch.Lifecycle;", root);
35 | }
36 |
37 | [Fact]
38 | public void when_defining_aliased_namespaces_then_replace_namespace()
39 | {
40 | var solution = CreateSolution(@"
41 | using System;
42 | using life = Android.Arch.Lifecycle;
43 |
44 | namespace ClassLibrary1
45 | {
46 | public class Class1
47 | {
48 | }
49 | }");
50 |
51 | var methodFixer = new NamespaceRewriter(resolver, new NullProgress());
52 | solution = methodFixer.Visit(solution, GetFirstDocument(solution));
53 |
54 | var root = GetText(solution);
55 |
56 | Assert.Contains("using life = AndroidX.Lifecycle;", root);
57 | Assert.DoesNotContain("using life = Android.Arch.Lifecycle;", root);
58 | }
59 |
60 | [Fact]
61 | public void when_defining_aliased_namespaces_then_fully_qualify_if_needed()
62 | {
63 | var solution = CreateSolution(@"
64 | using System;
65 | using support = Android.Support;
66 |
67 | namespace ClassLibrary1
68 | {
69 | public class MainActivity : support.V7.App.AppCompatActivity
70 | {
71 | }
72 | }");
73 |
74 | var methodFixer = new SemanticRewriter(resolver, new NullProgress());
75 | var typeFixer = new TypeRewriter(resolver, new NullProgress());
76 | solution = methodFixer.Visit(solution, GetFirstDocument(solution));
77 | solution = typeFixer.Visit(solution, GetFirstDocument(solution));
78 |
79 | var root = GetText(solution);
80 |
81 | Assert.Contains(": AndroidX.AppCompat.App.AppCompatActivity", root);
82 | Assert.DoesNotContain(": support.V7.App.AppCompatActivity", root);
83 | }
84 |
85 | [Fact]
86 | public void when_defining_types_then_dont_break_fully_qualified()
87 | {
88 | var solution = CreateSolution(@"
89 | using System;
90 |
91 | namespace ClassLibrary1
92 | {
93 | public class MainActivity : Android.Support.V7.App.AppCompatActivity
94 | {
95 | }
96 | }");
97 |
98 | var methodFixer = new SemanticRewriter(resolver, new NullProgress());
99 | solution = methodFixer.Visit(solution, GetFirstDocument(solution));
100 |
101 | var root = GetText(solution);
102 |
103 | Assert.Contains(": Android.Support.V7.App.AppCompatActivity", root);
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Test/NullProgress.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace VisualStudio.AndroidX.Migration
8 | {
9 | class NullProgress : IProgress
10 | {
11 | public void Report(string value)
12 | {
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Test/ProjectTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using Xunit;
5 |
6 | namespace VisualStudio.AndroidX.Migration
7 | {
8 | public class ProjectTests
9 | {
10 | [Fact]
11 | public void when_nuget_version_is_not_inlined_replace_it()
12 | {
13 | var csproj = versionedCsProj;
14 |
15 | var resolver = new TranslationResolver(new List(), new List { });
16 | var projectFixer = new ProjectRewriter(resolver, new NullProgress());
17 |
18 | csproj = projectFixer.RewriteCSProj(csproj);
19 |
20 | Assert.Contains(@"", csproj);
21 | Assert.DoesNotContain(@"28.0.0.1", csproj);
22 | Assert.Contains(@"1.0.0-preview02", csproj); //replace version number
23 | Assert.Contains(@"27.0.0.1", csproj); //don't remove version for xamarin.essentials
24 | }
25 |
26 | [Fact]
27 | public void when_include_migration_then_migration_is_present()
28 | {
29 | var csproj = sampleCsProj;
30 |
31 | var resolver = new TranslationResolver(new List(), new List { });
32 | var projectFixer = new ProjectRewriter(resolver, new NullProgress());
33 |
34 | csproj = projectFixer.RewriteCSProj(csproj, true);
35 |
36 | Assert.Contains(@"", csproj);
37 | }
38 |
39 | [Fact]
40 | public void when_nuget_is_àppcompat_replace_with_androidx()
41 | {
42 | var csproj = sampleCsProj;
43 |
44 | var resolver = new TranslationResolver(new List(), new List { });
45 | var projectFixer = new ProjectRewriter(resolver, new NullProgress());
46 |
47 | csproj = projectFixer.RewriteCSProj(csproj);
48 |
49 | Assert.Contains(@"", csproj);
50 | }
51 |
52 |
53 | [Fact]
54 | public void when_version_is_inline_replace_inline()
55 | {
56 | var csproj = sampleCsProj;
57 |
58 | var resolver = new TranslationResolver(new List(), new List { });
59 | var projectFixer = new ProjectRewriter(resolver, new NullProgress());
60 |
61 | csproj = projectFixer.RewriteCSProj(csproj);
62 |
63 | Assert.Contains(@"", csproj);
64 | }
65 |
66 | [Fact]
67 | public void in_poolmath_replace_androidx()
68 | {
69 | var csproj = poolMathCsproj;
70 |
71 | var resolver = new TranslationResolver(new List(), new List { });
72 | var projectFixer = new ProjectRewriter(resolver, new NullProgress());
73 |
74 | csproj = projectFixer.RewriteCSProj(csproj);
75 |
76 | Assert.Contains(@"
77 | 1.2.0.2
78 | ", csproj);
79 | }
80 |
81 | [Fact]
82 | public void when_nuget_is_support_replace_with_androidx()
83 | {
84 | var csproj = sampleCsProj;
85 |
86 | var resolver = new TranslationResolver(new List(), new List { });
87 | var projectFixer = new ProjectRewriter(resolver, new NullProgress());
88 |
89 | csproj = projectFixer.RewriteCSProj(csproj);
90 |
91 | Assert.Contains(@"", csproj);
92 | }
93 |
94 | string sampleCsProj =
95 | @"
96 |
97 |
98 | Debug
99 | AnyCPU
100 | 8.0.30703
101 | 2.0
102 | {EA94CF80-A750-4881-9468-638D0472C6C9}
103 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
104 | {84dd83c5-0fe3-4294-9419-09e7c8ba324f}
105 | Library
106 | Properties
107 | App43
108 | App43
109 | 512
110 | True
111 | Resources\Resource.designer.cs
112 | Resource
113 | Off
114 | false
115 | v9.0
116 | Properties\AndroidManifest.xml
117 | Resources
118 | Assets
119 | true
120 | Xamarin.Android.Net.AndroidClientHandler
121 |
122 |
123 | True
124 | portable
125 | False
126 | bin\Debug\
127 | DEBUG;TRACE
128 | prompt
129 | 4
130 | True
131 | None
132 | False
133 |
134 |
135 | True
136 | portable
137 | True
138 | bin\Release\
139 | TRACE
140 | prompt
141 | 4
142 | true
143 | False
144 | SdkOnly
145 | True
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 | Designer
168 |
169 |
170 | Designer
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
211 | ";
212 |
213 |
214 | string versionedCsProj =
215 | @"
216 |
217 |
218 | Debug
219 | AnyCPU
220 | 8.0.30703
221 | 2.0
222 | {EA94CF80-A750-4881-9468-638D0472C6C9}
223 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
224 | {84dd83c5-0fe3-4294-9419-09e7c8ba324f}
225 | Library
226 | Properties
227 | App43
228 | App43
229 | 512
230 | True
231 | Resources\Resource.designer.cs
232 | Resource
233 | Off
234 | false
235 | v9.0
236 | Properties\AndroidManifest.xml
237 | Resources
238 | Assets
239 | true
240 | Xamarin.Android.Net.AndroidClientHandler
241 |
242 |
243 | True
244 | portable
245 | False
246 | bin\Debug\
247 | DEBUG;TRACE
248 | prompt
249 | 4
250 | True
251 | None
252 | False
253 |
254 |
255 | True
256 | portable
257 | True
258 | bin\Release\
259 | TRACE
260 | prompt
261 | 4
262 | true
263 | False
264 | SdkOnly
265 | True
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 | Designer
288 |
289 |
290 | Designer
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 | 28.0.0.1
319 |
320 |
321 | 27.0.0.1
322 |
323 |
324 |
325 |
332 | ";
333 |
334 | string poolMathCsproj = @"
335 |
336 |
337 | Debug
338 | AnyCPU
339 | {C62B0A31-9EF4-46F9-A4FA-2CCDA1937444}
340 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
341 | Library
342 | TroubleFreePool.Droid
343 | com.troublefreepool.poolmath
344 | v9.0
345 | True
346 | Resources\Resource.designer.cs
347 | Resource
348 | Properties\AndroidManifest.xml
349 | Resources
350 | Assets
351 | false
352 |
353 |
354 | None
355 | true
356 | true
357 | Xamarin.Android.Net.AndroidClientHandler
358 |
359 |
360 | true
361 | full
362 | false
363 | bin\Debug
364 | DEBUG;
365 | prompt
366 | 4
367 | false
368 | arm64-v8a;armeabi-v7a;x86;x86_64
369 | true
370 |
371 |
372 | ..\Signing\poolmath.keystore
373 | poolmath
374 | poolmath
375 | poolmath
376 | true
377 |
378 |
379 | true
380 | pdbonly
381 | true
382 | bin\Release
383 | prompt
384 | 4
385 | true
386 | True
387 | ..\Signing\poolmath.keystore
388 | poolmath
389 | poolmath
390 | poolmath
391 | armeabi-v7a;arm64-v8a
392 | SdkOnly
393 | true
394 | 1G
395 | -Xss4096k
396 | true
397 |
398 |
399 | true
400 | pdbonly
401 | true
402 | bin\Release
403 | prompt
404 | 4
405 | true
406 | True
407 | ..\Signing\poolmath.keystore
408 | poolmath
409 | poolmath
410 | poolmath
411 | armeabi-v7a;arm64-v8a
412 | SdkOnly
413 | true
414 | 1G
415 | -Xss4096k
416 | true
417 | APPSTORE;
418 |
419 |
420 | $(MSBuildThisFileDirectory)..\
421 |
422 |
423 | 26.0.2
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 | 1.4.1
475 |
476 |
477 | 28.0.0.1
478 |
479 |
480 | 28.0.0.1
481 |
482 |
483 | 28.0.0.1
484 |
485 |
486 | 28.0.0.1
487 |
488 |
489 | 28.0.0.1
490 |
491 |
492 | 28.0.0.1
493 |
494 |
495 | 28.0.0.1
496 |
497 |
498 | 28.0.0.1
499 |
500 |
501 | 28.0.0.1
502 |
503 |
504 | 28.0.0.1
505 |
506 |
507 | 28.0.0.1
508 |
509 |
510 | 28.0.0.1
511 |
512 |
513 | 60.1142.1
514 |
515 |
516 | 12.0.1
517 |
518 |
519 | 1.14.0
520 |
521 |
522 | 1.14.0
523 |
524 |
525 | 1.14.0
526 |
527 |
528 | 1.14.0
529 |
530 |
531 | 1.14.0
532 |
533 |
534 | 1.2.0-beta
535 |
536 |
537 | 1.2.0-beta
538 |
539 |
540 | 2.0.3
541 |
542 |
543 | 2.1.0.187-beta
544 |
545 |
546 | 3.0.0.12
547 |
548 |
549 | 0.4.12-preview3
550 |
551 |
552 | 4.38.0
553 |
554 |
555 | 3.6.0.344457
556 |
557 |
558 | 2.5.16
559 |
560 |
561 | 1.1.0
562 |
563 |
564 |
565 |
566 | {E0A1FD19-6E12-449D-8C07-5A00EB73C465}
567 | PoolMath.Core
568 |
569 |
570 | {C6C52109-A9B0-4027-A9A3-F1D2A3314F0E}
571 | PoolMathApp.Share
572 |
573 |
574 | {B986F10C-01CB-4F0A-881D-29C06A91DF89}
575 | AmazonIap
576 |
577 |
578 |
579 |
580 | ";
581 | }
582 | }
583 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Test/ResolverTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Xunit;
7 |
8 | namespace VisualStudio.AndroidX.Migration
9 | {
10 | public class ResolverTests
11 | {
12 | [Fact]
13 | public void when_translation_resolver_doesnt_have_assemblies_it_still_initializes()
14 | {
15 | var resolver = new TranslationResolver(null, null);
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Test/TestBase.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 |
7 | namespace VisualStudio.AndroidX.Migration
8 | {
9 | public class TestBase
10 | {
11 | internal static ITranslationResolver resolver;
12 |
13 | static TestBase()
14 | {
15 | var codeBase = new Uri(typeof(TestBase).Assembly.CodeBase).AbsolutePath;
16 | var binDirectory = Path.GetDirectoryName(codeBase);
17 |
18 | var assembliesDirectory = Path.Combine(binDirectory, "Assemblies", "Android");
19 |
20 | resolver = new TranslationResolver(Directory.GetFiles(assembliesDirectory), new List { });
21 | }
22 |
23 |
24 | public static Solution CreateSolution(string file)
25 | {
26 | var workspace = new AdhocWorkspace();
27 | var project = workspace.AddProject("MethodTest", "C#");
28 | foreach (var assembly in resolver.AndroidAssemblies)
29 | project = project.AddMetadataReference(MetadataReference.CreateFromFile(assembly.Location));
30 | var document = project.AddDocument("Class1.cs", file);
31 | return document.Project.Solution;
32 | }
33 |
34 | internal static string GetText(Solution solution)
35 | {
36 | return solution.Projects.First().Documents.First().GetSyntaxRootAsync().Result.ToFullString();
37 | }
38 |
39 | internal static Document GetFirstDocument(Solution solution)
40 | {
41 | return solution.Projects.First().Documents.First();
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.Test/VisualStudio.AndroidX.Migration.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net472
5 | VisualStudio.AndroidX.Migration
6 | VisualStudio.AndroidX.Migration.Tests
7 |
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/VisualStudio.AndroidX.Migration.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.28803.443
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualStudio.AndroidX.Migration.Core", "VisualStudio.AndroidX.Migration.Core\VisualStudio.AndroidX.Migration.Core.csproj", "{297B120F-DE08-4460-BCE6-5B2A74535C2D}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualStudio.AndroidX.Migration.Console", "VisualStudio.AndroidX.Migration.Console\VisualStudio.AndroidX.Migration.Console.csproj", "{29E0E329-B35E-4A6C-B24D-E4700C6BA58F}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualStudio.AndroidX.Migration.Tests", "VisualStudio.AndroidX.Migration.Test\VisualStudio.AndroidX.Migration.Tests.csproj", "{2E87329E-6B9A-4F80-9D80-A3147B15BBA9}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {297B120F-DE08-4460-BCE6-5B2A74535C2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {297B120F-DE08-4460-BCE6-5B2A74535C2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {297B120F-DE08-4460-BCE6-5B2A74535C2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {297B120F-DE08-4460-BCE6-5B2A74535C2D}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {29E0E329-B35E-4A6C-B24D-E4700C6BA58F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {29E0E329-B35E-4A6C-B24D-E4700C6BA58F}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {29E0E329-B35E-4A6C-B24D-E4700C6BA58F}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {29E0E329-B35E-4A6C-B24D-E4700C6BA58F}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {2E87329E-6B9A-4F80-9D80-A3147B15BBA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {2E87329E-6B9A-4F80-9D80-A3147B15BBA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {2E87329E-6B9A-4F80-9D80-A3147B15BBA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {2E87329E-6B9A-4F80-9D80-A3147B15BBA9}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {77E00823-76E8-4B60-ABF0-181ABA21AE6C}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | - master
3 | - refs/tags/*
4 |
5 | resources:
6 | repositories:
7 | - repository: internal-templates
8 | type: github
9 | name: xamarin/yaml-templates
10 | endpoint: xamarin
11 | - repository: components
12 | type: github
13 | name: xamarin/XamarinComponents
14 | endpoint: xamarin
15 |
16 | jobs:
17 | - template: .ci/build.yml@components
18 | parameters:
19 | artifactsPath: 'output/nugets'
20 | postBuildSteps:
21 | - task: PublishTestResults@2
22 | displayName: Publish test results
23 | condition: always()
24 | inputs:
25 | testResultsFormat: xUnit
26 | testResultsFiles: output/test-results/**/*.xml
27 | testRunTitle: 'tests-$(System.JobName)'
28 | - ${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
29 | - template: sign-artifacts/jobs/v1.yml@internal-templates
30 | parameters:
31 | dependsOn: [ 'build' ]
32 |
--------------------------------------------------------------------------------
/build.cake:
--------------------------------------------------------------------------------
1 | #tool "nuget:?package=xunit.runner.console&version=2.4.1"
2 |
3 | #addin "nuget:?package=Cake.FileHelpers&version=3.2.1"
4 |
5 | var target = Argument("t", Argument("target", "ci"));
6 | var verbosity = Argument("v", Argument("verbosity", Verbosity.Normal));
7 | var configuration = Argument("c", Argument("configuration", "Release"));
8 |
9 | var mappingVersion = "f48a9d16427ddc449e57fe73017cc2fecf52eb3d";
10 | var mappingAssemblies = $"https://raw.githubusercontent.com/xamarin/AndroidX/{mappingVersion}/mappings/androidx-assemblies.csv";
11 | var mappingMappings = $"https://raw.githubusercontent.com/xamarin/AndroidX/{mappingVersion}/mappings/androidx-mapping.csv";
12 |
13 | Task("externals")
14 | .Does(() =>
15 | {
16 | EnsureDirectoryExists("./externals/mappings/");
17 |
18 | if (!FileExists("./externals/mappings/androidx-assemblies.csv"))
19 | DownloadFile(mappingAssemblies, "./externals/mappings/androidx-assemblies.csv");
20 | if (!FileExists("./externals/mappings/androidx-mapping.csv"))
21 | DownloadFile(mappingMappings, "./externals/mappings/androidx-mapping.csv");
22 | });
23 |
24 | Task("tests-externals")
25 | .Does(() =>
26 | {
27 | var testAssembliesFolder = "./externals/test-assets/Assemblies/";
28 |
29 | if (DirectoryExists($"{testAssembliesFolder}AndroidX"))
30 | return;
31 |
32 | var androidXNugets = new [] {
33 | "https://globalcdn.nuget.org/packages/xamarin.androidx.appcompat.1.1.0.1.nupkg",
34 | "https://globalcdn.nuget.org/packages/xamarin.androidx.leanback.1.0.0.1.nupkg",
35 | "https://globalcdn.nuget.org/packages/xamarin.androidx.lifecycle.common.2.2.0.1.nupkg",
36 | };
37 | var androidNugets = new [] {
38 | "https://globalcdn.nuget.org/packages/xamarin.android.arch.lifecycle.common.1.1.1.3.nupkg",
39 | "https://globalcdn.nuget.org/packages/xamarin.android.support.v7.appcompat.28.0.0.3.nupkg",
40 | "https://globalcdn.nuget.org/packages/xamarin.android.support.v17.leanback.28.0.0.3.nupkg",
41 | };
42 |
43 | EnsureDirectoryExists($"{testAssembliesFolder}AndroidX");
44 | foreach (var nuget in androidXNugets) {
45 | var tmp = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
46 | CreateDirectory(tmp);
47 | DownloadFile(nuget, $"{tmp}/nuget.nupkg");
48 | Unzip($"{tmp}/nuget.nupkg", tmp);
49 | CopyFiles(GetFiles($"{tmp}/lib/monoandroid90/*.dll"), $"{testAssembliesFolder}AndroidX");
50 | DeleteDirectory(tmp, new DeleteDirectorySettings { Recursive = true, Force = true });
51 | }
52 |
53 | EnsureDirectoryExists($"{testAssembliesFolder}Android");
54 | foreach (var nuget in androidNugets) {
55 | var tmp = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
56 | CreateDirectory(tmp);
57 | DownloadFile(nuget, $"{tmp}/nuget.nupkg");
58 | Unzip($"{tmp}/nuget.nupkg", tmp);
59 | CopyFiles(GetFiles($"{tmp}/lib/monoandroid90/*.dll"), $"{testAssembliesFolder}Android");
60 | DeleteDirectory(tmp, new DeleteDirectorySettings { Recursive = true, Force = true });
61 | }
62 | });
63 |
64 | Task("libs")
65 | .IsDependentOn("externals")
66 | .IsDependentOn("tests-externals")
67 | .Does(() =>
68 | {
69 | MSBuild("./VisualStudio.AndroidX.Migration.sln", new MSBuildSettings {
70 | Configuration = configuration,
71 | Restore = true,
72 | BinaryLogger = new MSBuildBinaryLogSettings
73 | {
74 | Enabled = true,
75 | FileName = MakeAbsolute((DirectoryPath)"./output/binlogs/libs.binlog").FullPath,
76 | }
77 | });
78 | });
79 |
80 | Task("nuget")
81 | .IsDependentOn("libs")
82 | .Does(() =>
83 | {
84 | DeleteFiles("./output/nugets/*.nupkg");
85 |
86 | var csproj = "./VisualStudio.AndroidX.Migration.Core/VisualStudio.AndroidX.Migration.Core.csproj";
87 | var settings = new MSBuildSettings {
88 | Configuration = configuration,
89 | Properties = {
90 | { "PackageOutputPath", new [] { MakeAbsolute((DirectoryPath)"./output/nugets/").FullPath } },
91 | },
92 | BinaryLogger = new MSBuildBinaryLogSettings
93 | {
94 | Enabled = true,
95 | FileName = MakeAbsolute((DirectoryPath)"./output/binlogs/pack.binlog").FullPath,
96 | }
97 | };
98 | MSBuild(csproj, settings.WithTarget("Pack"));
99 | });
100 |
101 | Task("tests")
102 | .IsDependentOn("libs")
103 | .Does(() =>
104 | {
105 | try {
106 | var testAssemblies = GetFiles($"./VisualStudio.AndroidX.Migration.Test/bin/{configuration}/*/*.Tests.dll");
107 | foreach (var assembly in testAssemblies) {
108 | XUnit2(new [] { assembly }, new XUnit2Settings {
109 | XmlReport = true,
110 | NoAppDomain = true,
111 | OutputDirectory = $"./output/test-results/VisualStudio.AndroidX.Migration.Tests",
112 | WorkingDirectory = assembly.GetDirectory(),
113 | });
114 | }
115 | } catch (Exception ex) {
116 | Error("##[error]Tests failed: " + ex.Message);
117 | Error(ex);
118 | }
119 | });
120 |
121 | Task("ci")
122 | .IsDependentOn("externals")
123 | .IsDependentOn("libs")
124 | .IsDependentOn("nuget")
125 | .IsDependentOn("tests");
126 |
127 | RunTarget(target);
128 |
--------------------------------------------------------------------------------