Quickstart & Nuget

Publié par Fabrice Michellonet sous le(s) label(s) , , le 17 mai 2011

Dans mon précédent post j’effleurais le sujet des gains de productivité que pouvais procurer les templates et autres Quickstart dans vos développement de tous les jours.

Prenons le cas d’un Quickstart, qui je le rappelle n’est autre qu’une solution templatisée. Imaginons que l’on souhaite utiliser 3 ou 4 librairies externes .NET bien sentie et pourquoi pas une ou deux librairies javascript s’il s’agit d’une solution Web.

En m’appuyant sur Nuget lors de la création des templates de projet composant le Quickstart, les dépendances pourrons être facilement être mise à jour par les développeurs à posteriori toujours grâce à Nuget. Rien de magique dans tout ça, en fait chaque projet est doté de son propre fichier 'packages.config' (repository nuget pour le projet) relatant la version des librairies référencées.

Voici ce que j’aimerais mettre en place en plus :

  • Mise à jour automatique de nuget avant toute autre opération.
  • Téléchargement et installation automatisée des dépendances référencées pour chaque projet.
  • Mise à jour automatique des dépendances lors de la première installation.

Infos complémentaires :

Microsoft depuis le MVC3 Tool Update du 12 Avril 2011 propose un nouveau template de projet MVC3 basé lui aussi sur nuget. La technique utilisée est quelque peu différente de celle que je vous présente ici, mais ne permet pas la mise à jour automatique des dépendances à l’installation.

Je reviendrais surement très rapidement sur cette façon de faire dans un prochain billet.

Pour réaliser ces différents points il nous faudra coder un Wizard custom.

La première tâche consistant à déployer nuget.exe est simplissime. Il nous suffit de l’embarquer dans les ressources de notre Wizard, puis au runtime extraire l’exécutable et le copier par exemple dans le dossier « packages » au sein de la solution. Pour info, le dossier « package » est utilisé par nuget pour y stocker les dépendances qu’il a téléchargé.

DirectoryInfo packageDirInfo = _solutionDirInfo.CreateSubdirectory("packages");
string _nugetFilePath = Path.Combine(packageDirInfo.FullName, "Nuget.exe");
File.WriteAllBytes(_nugetFilePath, Resources.NuGet);

Notez que le dossier package doit absolument se trouvé dans le même répertoire que votre fichier sln, si vous voulez pouvoir profiter de la mise à jour des packages. Il s’agit d’une restriction imposé par nuget lui-même

Nuget déployé, il est possible de le mettre à jour automatiquement en exécutant la ligne de commande suivante :

nuget update

Dans notre Wizard on pourra utiliser le code suivant :

Process nugetProc = new Process
            {
                StartInfo = new ProcessStartInfo(_nugetFilePath)
                {
                    Arguments = "update",
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true
                },
            };
            nugetProc.Start();
            StreamReader output = nugetProc.StandardOutput;
            StreamReader error = nugetProc.StandardError;
            nugetProc.WaitForExit();

Concernant l’installation des dépendances de chaque projet se fera simplement en utilisant une fois de plus une ligne de commande ; que l’on créera en C# de la manière suivante :

Process nugetProc = new Process
            {
                StartInfo = new ProcessStartInfo(_nugetFilePath)
                {
                    Arguments = string.Format("install {0}", _packageFilePath),
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    WorkingDirectory = new FileInfo(_nugetFilePath).DirectoryName
                 },
            };
            nugetProc.Start();

L’idée ici est en fait d’exécuter 1 fois pour chacun de vos projets la commande suivante :

nuget install %path/to%/packages.config

Reste encore la tache de mettre à jour toutes les dépendances. Malheureusement, pour l’instant nuget.exe ne propose pas encore de commande permettant la mise à jour des dépendances. Cependant un récent post, Phil Haack annonce la disponibilité de cette option pour la version de 1.4 de nuget.

En attendant cette fonctionnalité, nous pouvons nous en sortir en installant par default le package NuGetPackageUpdater. Ce dernier vous offre la possibilité d’exécuter la commande 'Update-Package' qui se chargera d’effectuer la mise à jour de toutes les dépendances de la solution.

J’espère qu’en suivant ces instructions vous pourrez construire des Templates qui se mettrons à jour tout seul.

Pour ceux qui souhaiteraient jeter un coup d’œil plus approfondi au code que je viens de présenter, il est disponible sur Codeplex avec l’ensemble des briques du Quikstart Obsidian sur lequel je travaille actuellement.

Project Template, Quickstart et VSIX

Publié par Fabrice Michellonet sous le(s) label(s) le 13 mai 2011

Dernièrement j’ai fait mumuse avec les template de fichiers et projets que l’on peut créer dans Visual Studio.

coccinelle

Pour ceux qui ne connaissent pas, les template de fichier vous permettent de définir l’ossature d’un type de fichier que vous utilisez souvent. Une fois créé vous retrouverez votre template dans le menu de Visual Studio « Add new Item ».

Par extension les projects template vous permettent de définir la structure d’un type projet, afin de prendre en compte les conventions de votre équipe par exemple. Vous y définissez l’ensemble des fichiers présent dès la création du projet.

Ce qui est très intéressant, c'est que cela permet d'avoir des projets prêts à l'emploi dans votre environnement, avec par exemple NLog et votre conteneur DI préféré. Si vous êtes expérimenté cela vous évitera quelques copier-coller, si par contre vous ne connaissez pas bien une des briques technique cela vous évitera un tas de problématique.

Quoi qu'il en soit voici quelques astuces sur ces templates :


  1. Bien que le SDK de Visual Studio vous propose des projets de type Item Template et Project Template, le plus simple reste d’utiliser le menu File -> Export Template de Viual Studio pour générer votre précieux template.

  2. Pour créer un quickstart, qui n’est autre qu’un template de solution (plusieurs projets), je vous conseille de :

    1. Exporter vos différents projets template et extraire les archives zip correspondante dans un même dossier.

    2. Ajouter dans ce dossier de travail un fichier .vstemplate reprenant cette structure

    3. <VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup">
        <TemplateData>
          <Name>Ma solution</Name>
          <Description>Ma description</Description>
          <ProjectType>CSharp</ProjectType>
          <ProjectSubType></ProjectSubType>
          <SortOrder>1000</SortOrder>
          <CreateNewFolder>false</CreateNewFolder>
          <LocationField>Enabled</LocationField>
          <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
          <Icon>monicone_100x100.ico</Icon>
        </TemplateData>
        <TemplateContent>
          <ProjectCollection>
            <ProjectTemplateLink ProjectName="Web">
              Web\MyTemplate.vstemplate
            </ProjectTemplateLink>
            <ProjectTemplateLink ProjectName="Domain">
              Domain\MyTemplate.vstemplate
            </ProjectTemplateLink>
            <ProjectTemplateLink ProjectName="DAL">
              DAL\MyTemplate.vstemplate
            </ProjectTemplateLink>
            <ProjectTemplateLink ProjectName="IServices">
              IServices\MyTemplate.vstemplate
            </ProjectTemplateLink>
            <ProjectTemplateLink ProjectName="Services">
              Services\MyTemplate.vstemplate
            </ProjectTemplateLink>
          </ProjectCollection>
        </TemplateContent>
      </VSTemplate>
      

      Vous pouvez y mettre autant de référence a des projects que vous le souhaitez en ajoutant des balises ProjectTemplateLink.

    4. Créez une archive zip du dossier de travail et placez la dans le dossier %VSInstallDir%\Common7\IDE\ProjectTemplates\. Après redémarrage de Visual Studio le nouveau template sera dispo.

  3. Dans le fichier vstemplate de votre Quickstart, la première occurrence à un projet sera par convention le startup project.

  4. Pour étendre avec du code custom vos project template il vous faudra :

    1. Créer une assembly et implémenter l’interface Microsoft.VisualStudio.TemplateWizard.IWizard

    2. Ajouter la balise WizardExtension dans le fichier .vstemplate de votre project template

    3. <VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
        …
        <WizardExtension>
          <Assembly>MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=952e5fc020f3b126</Assembly>
          <FullClassName>MyAssembly.Wizard</FullClassName>
        </WizardExtension>
      </VSTemplate>
      
  5. Il est possible de faire appel à une assembly custom dans un template de type quickstart, mais attention, la plupart des appels que vous ferez sur les objects EnvDTE et plus particulièrement EnvDTE.Project fréquemment utilisés dans la méthode IWizard. ProjectFinishedGenerating vous renverront des valeurs nulles.

  6. La façon la plus simple de créer un VSIX de déploiement est d’utiliser le projet de type VSIX Project (Visual C# -> Extensibility -> VSIX Project). Le SDK doit être installé.

  7. Dans le designer de VSIX, le champ ID comporte un GUID… n’y touchez surtout pas !

  8. Il est possible de définir dans quelle catégorie de template se trouvera l’élément que vous déployez via votre VSIX en renseignant le champ Add to subfolder.

  9. subfolder