Skip to content

Commit

Permalink
* add ability to select assemblies to reference if more than 1
Browse files Browse the repository at this point in the history
* add logic to ensure correct target framework folder is selected, if present
  • Loading branch information
Kiliman committed Aug 9, 2010
1 parent a566197 commit b410684
Show file tree
Hide file tree
Showing 16 changed files with 692 additions and 248 deletions.
10 changes: 10 additions & 0 deletions src/NuForVS.Test/Mocks/MockConfigurationManager.cs
Expand Up @@ -15,9 +15,19 @@ public MockConfigurationManager(Configuration config)
_config = config;
}

public string ConfigurationAsText
{
get { throw new NotImplementedException(); }
}

public Configuration GetConfig()
{
return _config;
}

public void SaveConfig(string configText)
{
throw new NotImplementedException();
}
}
}
43 changes: 35 additions & 8 deletions src/NuForVS.Test/PackageManagerTests.cs
Expand Up @@ -8,17 +8,16 @@ namespace NuForVS.Test
[TestFixture]
public class PackageManagerTests
{
[TestCase("net-3.5", true)]
[TestCase("NET40", true)]
[TestCase("silverlight-2.0", true)]
[TestCase("abc123", false)]
[TestCase("123xyz", false)]
public void IsTargetFramework(string path, bool expectedResult)
[TestCase("net-3.5", 0x00030005)]
[TestCase("NET40", 0x00040000)]
[TestCase("silverlight-2.0", 0)]
[TestCase("abc123", 0)]
[TestCase("123xyz", 0)]
public void GetTargetFrameworkVersion(string path, int expectedResult)
{
var pm = ObjectMother.CreatePackageManager();
var targetFramework = 0;

Assert.AreEqual(expectedResult, pm.IsTargetFramework(path, targetFramework));
Assert.AreEqual(expectedResult, pm.GetTargetFrameworkVersion(path));
}

[Test]
Expand Down Expand Up @@ -125,6 +124,34 @@ public void InstallGemShouldReturn1GemAnd2AssembliesNotReferenced()
Assert.IsFalse(pm.Project.HasReference(@"C:\Projects\Test\lib\log4net\log4net.dll"));
}

[TestCase(0x00020000, @"C:\Projects\Test\lib\log4net\net-2.0\log4net.dll")]
[TestCase(0x00030005, @"C:\Projects\Test\lib\log4net\net-3.5\log4net.dll")]
[TestCase(0x00040000, @"C:\Projects\Test\lib\log4net\net-4.0\log4net.dll")]
public void InstallGemShouldReturnCorrectTargetFramework(int targetFramework, string expectedResults)
{
var commandLines = new string[]
{
"Found Gem",
"Copy From: C:/Tools/Ruby191/lib/ruby/gems/1.9.1/gems/log4net-1.2.10.0/lib",
"Copy To: C:/Projects/Test/lib/log4net"
};

var paths = new string[]
{
@"C:\Projects\Test\lib\log4net\net-2.0\log4net.dll",
@"C:\Projects\Test\lib\log4net\net-3.5\log4net.dll",
@"C:\Projects\Test\lib\log4net\net-4.0\log4net.dll",
};

var pm = ObjectMother.CreatePackageManager(targetFramework: targetFramework, commandLines: commandLines, paths: paths);

// mock fs: contents of gem (2 assemblies)
var gemname = "log4net";
var gems = pm.InstallGem(gemname, noOutput);

Assert.IsTrue(pm.Project.HasReference(expectedResults));
}

[Test]
public void InstallGemShouldReturn2GemsBothAutoReferenced()
{
Expand Down
21 changes: 3 additions & 18 deletions src/NuForVS.TestUI/Program.cs
Expand Up @@ -19,28 +19,13 @@ static void Main()
Application.SetCompatibleTextRenderingDefault(false);

var solutionPath = @"C:\Projects\Test\Solution.sln";
var targetFramework = 0;
var targetFramework = 0x00030005;
var project = new MockProject(@"C:\Projects\Test\Test.csproj");
project.AddReference(@"C:\Projects\Test\lib\log4net\log4net.dll");

var runner = new CommandRunner();
// mock fs: contents of 2 gem
var fs = new MockFileSystem(new string[] {
@"C:\Projects\Test\lib\log4net\LICENSE.txt",
@"C:\Projects\Test\lib\log4net\log4net.dll",
@"C:\Projects\Test\lib\log4net\log4net.xml",
@"C:\Projects\Test\lib\log4net\NOTICE.txt",
@"C:\Projects\Test\lib\log4net\README.txt",

@"C:\Projects\Test\lib\nunit\LICENSE.txt",
@"C:\Projects\Test\lib\nunit\nunit.dll",
@"C:\Projects\Test\lib\nunit\nunit.xml",
@"C:\Projects\Test\lib\nunit\NOTICE.txt",
@"C:\Projects\Test\lib\nunit\README.txt",
});
var config = new Configuration {GemCommand = "gem"};

var configManager = new MockConfigurationManager(config);
var fs = new FileSystem();
var configManager = new ConfigurationManager();

Application.Run(new AddReferenceForm(solutionPath, targetFramework, project, runner, fs, configManager));
}
Expand Down
59 changes: 58 additions & 1 deletion src/NuForVS/Core/ConfigurationManager.cs
@@ -1,15 +1,72 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace NuForVS.Core
{
public class ConfigurationManager : IConfigurationManager
{
private string _configPath;
private Configuration _config = new Configuration();

public ConfigurationManager()
{
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "NuForVS");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}

_configPath = Path.Combine(path, "config.ini");

if (!File.Exists(_configPath))
{
// copy default config from resource
using (var sr = new StreamReader(this.GetType().Assembly.GetManifestResourceStream("NuForVS.Resources.config.ini")))
{
File.WriteAllText(_configPath, sr.ReadToEnd());
}
}

loadConfig();
}

private void loadConfig()
{
var ini = new IniFile(_configPath);
_config.GemCommand = ini.ReadValue("general", "gemCommand");
_config.GemServer = ini.ReadValue("general", "gemServer");
_config.AutoReferences.Clear();

var references = ini.GetSection("auto-reference");
foreach (var item in references)
{
var part = item.Split('=');
var autoRef = new AutoReference {GemName = part[0]};
var assemblies = part[1];
foreach (var path in assemblies.Split(','))
{
autoRef.Assemblies.Add(path);
}
_config.AutoReferences.Add(autoRef);
}
}

public string ConfigurationAsText
{
get { return File.ReadAllText(_configPath); }
}
public Configuration GetConfig()
{
return new Configuration();
return _config;
}

public void SaveConfig(string configText)
{
File.WriteAllText(_configPath, configText);
loadConfig();
}
}
}
1 change: 1 addition & 0 deletions src/NuForVS/Core/Gem.cs
Expand Up @@ -6,6 +6,7 @@ public class Gem
{
public string Name { get; set; }
public string Version { get; set; }
public bool IsAutoReferenced { get; set; }
public bool IsReferenced { get; set; }
public bool IsRemote { get; set; }
public IList<string> Assemblies { get; private set; }
Expand Down
2 changes: 2 additions & 0 deletions src/NuForVS/Core/IConfigurationManager.cs
Expand Up @@ -7,6 +7,8 @@ namespace NuForVS.Core
{
public interface IConfigurationManager
{
string ConfigurationAsText { get; }
Configuration GetConfig();
void SaveConfig(string configText);
}
}
70 changes: 70 additions & 0 deletions src/NuForVS/Core/IniFile.cs
@@ -0,0 +1,70 @@
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace NuForVS.Core
{
public class IniFile
{
private string _path;

[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section,
string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section,
string key, string def, StringBuilder retVal,
int size, string filePath);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern uint GetPrivateProfileSection(string lpAppName,
IntPtr lpReturnedString, uint nSize, string lpFileName);

public IniFile(string path)
{
_path = path;
}

public void WriteValue(string section, string key, string value)
{
WritePrivateProfileString(section, key, value, _path);
}

public string ReadValue(string section, string key)
{
var sb = new StringBuilder(255);
var i = GetPrivateProfileString(section, key, "", sb, sb.Capacity, _path);
return sb.ToString();
}

public string[] GetSection(string section)
{
var items = new string[0];

if (!System.IO.File.Exists(_path))
return items;

uint MAX_BUFFER = 32767;

IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);

uint bytesReturned = GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, _path);

if ((bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))
{
Marshal.FreeCoTaskMem(pReturnedString);
return items;
}

//bytesReturned -1 to remove trailing \0

// NOTE: Calling Marshal.PtrToStringAuto(pReturnedString) will
// result in only the first pair being returned
string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned - 1);

items = returnedString.Split('\0');

Marshal.FreeCoTaskMem(pReturnedString);
return items;
}
}
}
71 changes: 53 additions & 18 deletions src/NuForVS/Core/PackageManager.cs
Expand Up @@ -17,6 +17,7 @@ public class PackageManager
private IFileSystem _fs;
private IConfigurationManager _configManager;
private Configuration _config;
private Regex _targetRegex = new Regex("(net)[ -]?(\\d)[.]?(\\d*)", RegexOptions.Compiled | RegexOptions.IgnoreCase);

public PackageManager(string solutionPath, int targetFramework, IProject project, ICommandRunner runner, IFileSystem fs, IConfigurationManager configManager)
{
Expand Down Expand Up @@ -137,16 +138,19 @@ public IList<Gem> InstallGem(string gemname, Action<string> output)
}
}

// for each gem, auto reference gems with 1 assembly
// for each gem, auto reference gems with 1 assembly (or configured auto-ref)
// return rest to prompt user
foreach (var gem in gems)
{
// if only 1 assembly in this gem, auto reference it
if (gem.Assemblies.Count == 1)
if (gem.Assemblies.Count == 1 || gem.IsAutoReferenced)
{
output("Adding Reference: " + gem.Assemblies[0]);
_project.AddReference(gem.Assemblies[0]);
gem.IsReferenced = true;
foreach (var assembly in gem.Assemblies)
{
output("Adding Reference: " + assembly);
_project.AddReference(assembly);
gem.IsReferenced = true;
}
}
}

Expand All @@ -158,40 +162,71 @@ private void getAssemblies(Gem gem, string installPath)
{
if (!_fs.FolderExists(installPath)) return;

var currentFrameworkVersion = 0;

// check for framework folders
foreach (var folder in _fs.GetFolders(installPath))
{
if (IsTargetFramework(Path.GetFileName(folder), _targetFramework))
var version = GetTargetFrameworkVersion(Path.GetFileName(folder));
if (version != 0 && version > currentFrameworkVersion && version <= _targetFramework)
{
currentFrameworkVersion = version;
installPath = folder;
}
}

foreach (var filename in _fs.GetFiles(installPath))
// look for auto-ref
var autoref = _config.AutoReferences.FirstOrDefault(a => a.GemName == gem.Name);
if (autoref != null)
{
if (filename.EndsWith(".dll"))
gem.IsAutoReferenced = true;
foreach (var path in autoref.Assemblies)
{
gem.Assemblies.Add(filename);
var filePath = path.Replace("/", "\\");
// strip leading /
if (filePath.StartsWith("\\")) filePath = filePath.Substring(1);
// if ends with * then add all in path
if (filePath.EndsWith("*"))
{
foreach (var filename in _fs.GetFiles(Path.Combine(installPath, Path.GetDirectoryName(filePath))))
{
if (filename.EndsWith(".dll"))
{
gem.Assemblies.Add(filename);
}
}
}
else
{
gem.Assemblies.Add(Path.Combine(installPath, filePath));
}
}
}
}
else
{

public bool IsTargetFramework(string folder, int targetFramework)
{
var majorVersion = targetFramework >> 16;
var minorVersion = targetFramework & 0xFFFF;

var re = new Regex("(net|mono|sl|silverlight)[ -]?(\\d+)[.]?(\\d*)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
foreach (var filename in _fs.GetFiles(installPath))
{
if (filename.EndsWith(".dll"))
{
gem.Assemblies.Add(filename);
}
}
}
}

var m = re.Match(folder);
if (!m.Success) return false;
public int GetTargetFrameworkVersion(string folder)
{
var m = _targetRegex.Match(folder);
if (!m.Success) return 0;

var platform = m.Groups[1].Value;
var platformMajorVersion = Convert.ToInt32(m.Groups[2].Value);
var platformMinorVersion = 0;
if (m.Groups[3].Value != "") platformMinorVersion = Convert.ToInt32(m.Groups[3].Value);

return m.Success;
return platformMajorVersion << 16 | platformMinorVersion;

}
}
Expand Down

0 comments on commit b410684

Please sign in to comment.