Author: brett Date: Mon Aug 12 13:07:42 2013 New Revision: 1513126 URL: http://svn.apache.org/r1513126 Log: [NPANDAY-579] Discover referenced assemblies
When generating dependencies, we need to also inspect the referenced assemblies. Currently, we look for those that exist in the same directory as the assembly and add them to the POM if they exist, as well as to the generated POM for the assembly copied to the local Maven repository. Modified: incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/pom.xml incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/src/main/csharp/Converter/Algorithms/AbstractPomConverter.cs incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/src/main/csharp/NPanday.ProjectImporterEngine.csproj incubator/npanday/trunk/dotnet/assemblies/NPanday.Utils/src/main/csharp/RepositoryUtility.cs Modified: incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/pom.xml URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/pom.xml?rev=1513126&r1=1513125&r2=1513126&view=diff ============================================================================== --- incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/pom.xml (original) +++ incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/pom.xml Mon Aug 12 13:07:42 2013 @@ -90,6 +90,12 @@ <type>dotnet-library</type> </dependency> <dependency> + <groupId>Mono.Cecil</groupId> + <artifactId>Mono.Cecil</artifactId> + <version>0.9.5.4</version> + <type>dotnet-library</type> + </dependency> + <dependency> <groupId>NUnit</groupId> <artifactId>NUnit.Framework</artifactId> <version>2.2.8.0</version> Modified: incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/src/main/csharp/Converter/Algorithms/AbstractPomConverter.cs URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/src/main/csharp/Converter/Algorithms/AbstractPomConverter.cs?rev=1513126&r1=1513125&r2=1513126&view=diff ============================================================================== --- incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/src/main/csharp/Converter/Algorithms/AbstractPomConverter.cs (original) +++ incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/src/main/csharp/Converter/Algorithms/AbstractPomConverter.cs Mon Aug 12 13:07:42 2013 @@ -30,6 +30,7 @@ using NPanday.ProjectImporter.Digest.Mod using NPanday.Utils; using Microsoft.Win32; using System.Text.RegularExpressions; +using System.Reflection; /// Author: Leopoldo Lee Agdeppa III @@ -918,7 +919,7 @@ namespace NPanday.ProjectImporter.Conver if (warnNonPortable) { - WarnNonPortableReference(path, refDependency); + WarnNonPortableReference(path, refDependency, GetReferencedAssemblies(path)); } else { @@ -1108,7 +1109,7 @@ namespace NPanday.ProjectImporter.Conver return null; } - private void WarnNonPortableReference(string path, Dependency refDependency) + private void WarnNonPortableReference(string path, Dependency refDependency, List<Dependency> dependencies) { if (projectDigest.DependencySearchConfig.CopyToMaven) { @@ -1118,6 +1119,16 @@ namespace NPanday.ProjectImporter.Conver // reset the dependency refDependency.scope = null; refDependency.systemPath = null; + + Model.Pom.Model dependencyModel = new Model.Pom.Model(); + dependencyModel.modelVersion = "4.0.0"; + dependencyModel.groupId = refDependency.groupId; + dependencyModel.artifactId = refDependency.artifactId; + dependencyModel.version = refDependency.version; + dependencyModel.packaging = "dotnet-library"; + dependencyModel.dependencies = dependencies.ToArray(); + string file = RepositoryUtility.GetArtifactPath(refDependency.groupId, refDependency.artifactId, refDependency.version, "pom"); + PomHelperUtility.WriteModelToPom(new FileInfo(file), dependencyModel); } else { @@ -1142,17 +1153,25 @@ namespace NPanday.ProjectImporter.Conver private Dependency ResolveDependencyFromHintPath(Reference reference) { - if (!string.IsNullOrEmpty(reference.HintFullPath) && new FileInfo(reference.HintFullPath).Exists) + return ResolveDependencyFromPath(reference.HintFullPath, reference.Name, reference.Version); + } + + private Dependency ResolveDependencyFromPath(string hintFullPath, string name, string version) + { + if (!string.IsNullOrEmpty(hintFullPath) && new FileInfo(hintFullPath).Exists) { string prjRefPath = Path.Combine(projectDigest.FullDirectoryName, ".references"); //verbose for new-import - if (!reference.HintFullPath.ToLower().StartsWith(prjRefPath.ToLower()) && !reference.Name.Contains("Interop")) + if (!hintFullPath.ToLower().StartsWith(prjRefPath.ToLower()) && !name.Contains("Interop")) { - Dependency refDependency = CreateDependencyFromSystemPath(reference, reference.HintFullPath); + Dependency refDependency = CreateDependencyFromPartsAndSystemPath(name, version, hintFullPath); + + log.DebugFormat("Resolved {0} from hint path: {1}:{2}:{3}", name, refDependency.groupId, refDependency.artifactId, refDependency.version); - WarnNonPortableReference(reference.HintFullPath, refDependency); + // this will pick up some NuGet packaged references + List<Dependency> dependencies = GetReferencedAssemblies(hintFullPath); - log.DebugFormat("Resolved {0} from hint path: {1}:{2}:{3}", reference.Name, refDependency.groupId, refDependency.artifactId, refDependency.version); + WarnNonPortableReference(hintFullPath, refDependency, dependencies); return refDependency; } @@ -1162,21 +1181,21 @@ namespace NPanday.ProjectImporter.Conver // TODO: not a very good parsing of .references - if we have .references, don't we already know it from local repo? Dependency refDependency = new Dependency(); - refDependency.artifactId = reference.Name; + refDependency.artifactId = name; //get version from the name above the last path - string[] pathTokens = reference.HintFullPath.Split("\\\\".ToCharArray()); + string[] pathTokens = hintFullPath.Split("\\\\".ToCharArray()); if (pathTokens.Length < 3) { // should only hit this if it is in .references, and it was incorrectly constructed - throw new Exception("Invalid hint path: " + reference.HintFullPath); + throw new Exception("Invalid hint path: " + hintFullPath); } refDependency.groupId = pathTokens[pathTokens.Length - 3]; - refDependency.version = pathTokens[pathTokens.Length-2].Replace(reference.Name+"-","") ?? "1.0.0.0"; + refDependency.version = pathTokens[pathTokens.Length-2].Replace(name+"-","") ?? "1.0.0.0"; refDependency.type = "dotnet-library"; log.DebugFormat("Resolved {0} from previously resolved references: {1}:{2}:{3}", - reference.Name, refDependency.groupId, refDependency.artifactId, refDependency.version); + name, refDependency.groupId, refDependency.artifactId, refDependency.version); return refDependency; } @@ -1184,12 +1203,41 @@ namespace NPanday.ProjectImporter.Conver return null; } + private List<Dependency> GetReferencedAssemblies(string path) + { + List<Dependency> dependencies = new List<Dependency>(); + + Mono.Cecil.AssemblyDefinition assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(path); + + // resolve referenced assemblies in the same directory + foreach (Mono.Cecil.AssemblyNameReference assemblyName in assembly.MainModule.AssemblyReferences) + { + Dependency d = ResolveDependencyFromPath(Path.Combine(new FileInfo(path).DirectoryName, assemblyName.Name + ".dll"), + assemblyName.Name, + assemblyName.Version != null ? assemblyName.Version.ToString() : null); + if (d != null) + { + dependencies.Add(d); + + // Add it to the POM as well, in case transitive dependency is not available later + AddDependency(d); + } + } + + return dependencies; + } + private static Dependency CreateDependencyFromSystemPath(Reference reference, string path) { + return CreateDependencyFromPartsAndSystemPath(reference.Name, reference.Version, path); + } + + private static Dependency CreateDependencyFromPartsAndSystemPath(string name, string version, string path) + { Dependency refDependency = new Dependency(); - refDependency.artifactId = reference.Name; - refDependency.groupId = reference.Name; - refDependency.version = reference.Version ?? "1.0.0.0"; + refDependency.artifactId = name; + refDependency.groupId = name; + refDependency.version = version ?? "1.0.0.0"; refDependency.type = "dotnet-library"; refDependency.scope = "system"; refDependency.systemPath = path; Modified: incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/src/main/csharp/NPanday.ProjectImporterEngine.csproj URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/src/main/csharp/NPanday.ProjectImporterEngine.csproj?rev=1513126&r1=1513125&r2=1513126&view=diff ============================================================================== --- incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/src/main/csharp/NPanday.ProjectImporterEngine.csproj (original) +++ incubator/npanday/trunk/dotnet/assemblies/NPanday.ProjectImporter/Engine/src/main/csharp/NPanday.ProjectImporterEngine.csproj Mon Aug 12 13:07:42 2013 @@ -39,6 +39,8 @@ <Reference Include="Microsoft.Build.Framework" /> <Reference Include="Microsoft.Build.Tasks" /> <Reference Include="Microsoft.Build.Utilities" /> + <Reference Include="Mono.Cecil"> + </Reference> <Reference Include="NPanday.Model.Pom, Version=0.14.0.0, Culture=neutral, PublicKeyToken=4b435f4d76e2f0e6, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> <HintPath>..\..\..\..\..\NPanday.Model.Pom\target\NPanday.Model.Pom.dll</HintPath> @@ -47,7 +49,6 @@ <HintPath>..\..\..\..\..\NPanday.Model.Settings\target\NPanday.Model.Settings.dll</HintPath> </Reference> <Reference Include="NUnit.Framework"> - <HintPath>C:\Documents and Settings\user\.m2\uac\gac_msil\NUnit.Framework\2.2.8.0__NUnit\NUnit.Framework.dll</HintPath> </Reference> <Reference Include="System" /> <Reference Include="System.Data" /> Modified: incubator/npanday/trunk/dotnet/assemblies/NPanday.Utils/src/main/csharp/RepositoryUtility.cs URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.Utils/src/main/csharp/RepositoryUtility.cs?rev=1513126&r1=1513125&r2=1513126&view=diff ============================================================================== --- incubator/npanday/trunk/dotnet/assemblies/NPanday.Utils/src/main/csharp/RepositoryUtility.cs (original) +++ incubator/npanday/trunk/dotnet/assemblies/NPanday.Utils/src/main/csharp/RepositoryUtility.cs Mon Aug 12 13:07:42 2013 @@ -36,22 +36,17 @@ namespace NPanday.Utils { try { - string m2Dir = Path.GetFullPath(string.Format("{0}\\..\\.m2", System.Environment.GetFolderPath(Environment.SpecialFolder.Personal))); - string artifactDir = Path.Combine(m2Dir, string.Format(@"repository\{0}\{1}\{2}", groupId.Replace('.','\\'), artifactId, version)); - string artifactFilename = string.Format("{0}-{1}{2}", artifactId, version, Path.GetExtension(filename)); + string path = GetArtifactPath(groupId, artifactId, version, Path.GetExtension(filename).Substring(1)); if (!File.Exists(filename)) throw new Exception("Cannot find Assembly to install."); - if (!Directory.Exists(artifactDir)) - Directory.CreateDirectory(artifactDir); - //if assembly already installed skip the copying - if (File.Exists(Path.Combine(artifactDir, artifactFilename))) + if (File.Exists(path)) { if (overwrite) { - File.Delete(Path.Combine(artifactDir, artifactFilename)); + File.Delete(path); } else { @@ -59,8 +54,12 @@ namespace NPanday.Utils } } + string artifactDir = Path.GetDirectoryName(path); + if (!Directory.Exists(artifactDir)) + Directory.CreateDirectory(artifactDir); + //copy file - File.Copy(filename, Path.Combine(artifactDir, artifactFilename)); + File.Copy(filename, path); return true; } @@ -69,5 +68,13 @@ namespace NPanday.Utils throw; } } + + public static string GetArtifactPath(string groupId, string artifactId, string version, string ext) + { + string m2Dir = Path.GetFullPath(string.Format("{0}\\..\\.m2", System.Environment.GetFolderPath(Environment.SpecialFolder.Personal))); + string artifactDir = Path.Combine(m2Dir, string.Format(@"repository\{0}\{1}\{2}", groupId.Replace('.', '\\'), artifactId, version)); + string artifactFilename = string.Format("{0}-{1}.{2}", artifactId, version, ext); + return Path.Combine(artifactDir, artifactFilename); + } } }