TeamBuild 2010 : Paramètre extensible personnalisé 1

TeamBuild 2010 : Paramètre extensible personnalisé

Voici un petit billet sur comment ajouter un paramètre “extensible” à un workflow de build. Ce que j’entend par paramètre extensible est un paramètre à coté duquel s’affiche un petit + permettant de l’ouvrir pour remplir des propriétés, la ligne principale affichant un résumé des valeurs :

image

Pour cela rien de plus simple, on commence par créer une classe qui va contenir nos données :

public class VersioningSettings
{
    public string AssemblyInfoFileSpec { get; set; }

    public string AssemblyVersionFormat { get; set; }

    public string AssemblyFileVersionFormat { get; set; }

    public string AssemblyInformationalVersionFormat { get; set; }
}

Une fois cette classe écrite on décore l’ensemble des propriétés pour personnaliser l’affichage dans la grille des propriétés (contrôle WinForms de type PropertyGrid). Voici certain des attributs que l’on peut utiliser :

  • DisplayNameAttribute : le libellé a affiche à la place du nom de la propriété.
  • DescriptionAttribute : un petit descriptif de la propriété qui est affiché en bas de la grille des propriétés .
  • BrowsableAttribute : indique si la propriété doit être affichée dans la grille des propriétés .
  • RefreshPropertiesAttribute : indique comment la grille des propriétés doit être rafraichit suite à la modification de la valeur de la propriété. La liste des valeurs possible est disponible ici.

Voici ce que cela donne appliqué à l’exemple ci-dessus :

public class VersioningSettings
{
    [DisplayName(@"AssemblyInfo Filespec")]
    [Description(@"Specifiy the search pattern for locating AssemblyInfo files - e.g. **\*AssemblyInfo*.cs.")]
    [RefreshProperties(RefreshProperties.All)]
    [Browsable(true)]
    public string AssemblyInfoFileSpec { get; set; }

    [DisplayName("AssemblyVersion Format")]
    [Description("Specify the AssemblyVersion format. Supported tokens are: $(current), $(increment), $(date:<format>).")]
    [RefreshProperties(RefreshProperties.All)]
    [Browsable(true)]
    public string AssemblyVersionFormat { get; set; }

    [DisplayName("AssemblyFileVersion Format")]
    [Description("Specify the AssemblyFileVersion format. Supported tokens are: $(current), $(increment), $(date:<format>).")]
    [RefreshProperties(RefreshProperties.All)]
    [Browsable(true)]
    public string AssemblyFileVersionFormat { get; set; }

    [DisplayName("AssemblyInformationalVersion Format")]
    [Description("Specify the AssemblyInformationalVersion format. Supported tokens are: $(version), $(fileversion), $(date:<format>).")]
    [RefreshProperties(RefreshProperties.All)]
    [Browsable(true)]
    public string AssemblyInformationalVersionFormat { get; set; }

    [Browsable(false)]
    public bool HasAssemblyInfoFileSpec
    {
        get
        {
            return !string.IsNullOrEmpty(this.AssemblyInfoFileSpec);
        }
    }
}

Dans le code suivant j’ai ajouté une propriété HasAssemblyInfoFileSpec qui n’est pas visible dans la grille de propriété mais qui me sert dans mon workflow. Il reste maintenant à ajouter des attributs sur la classe elle même :

  • SerializableAttribute : pour qu’une classe puisse être utilisée comment paramètre d’un workflow elle doit être sérialisable.
  • TypeConverterAttribute : spécifie le type de convertisseur à utiliser pour afficher la classe. Dans notre cas on utilisera un convertisseur de type ExpandableObjectConverter, c’est cet attribut qui va indiquer à la grille de propriété qu’il faut afficher un “+” et les propriétés de l’objet.

Cela donne :

[Serializable]
[TypeConverter(typeof(ExpandableObjectConverter))]
public class VersioningSettings
{
    //...
}

Afin d’afficher sur la ligne principale un résumé, il faudrait normalement faire son propre TypeConverter héritant de ExpandableObjectConverter et renvoyant le résumé via la méthode ConvertTo. Malheureusement il y a un bogue dans TeamExplorer qui fait que notre TypeConverter n’est pas utilisé, le problème devrait être corrigé dans la prochaine version de Visual Studio mais en attendant il va falloir contourner ce bogue :(

Pour cela on va tout simplement surcharger la méthode ToString de notre classe :

//...
public class VersioningSettings
{
    //...

    public override string ToString()
    {
        if (this.HasAssemblyInfoFileSpec)
        {
            var args = new List<string>();
            if (!string.IsNullOrEmpty(this.AssemblyVersionFormat))
            {
                args.Add(
                    string.Format("'{0}' for version", this.AssemblyVersionFormat)
                    );
            }

            if (!string.IsNullOrEmpty(this.AssemblyFileVersionFormat))
            {
                args.Add(
                    string.Format("'{0}' for file version", this.AssemblyFileVersionFormat)
                    );
            }

            if (!string.IsNullOrEmpty(this.AssemblyInformationalVersionFormat))
            {
                args.Add(
                    string.Format("'{0}' for informational version", this.AssemblyInformationalVersionFormat)
                    );
            }

            if (args.Count != 0)
            {
                return string.Format(
                    "Update AssemblyInfo files matching '{0}' using {1}",
                    this.AssemblyInfoFileSpec,
                    args.Aggregate((a1, a2) => a1 + ", " + a2)
                    );
            }
            else
            {
                return string.Format("Update AssemblyInfo files matching '{0}'", this.AssemblyInfoFileSpec);
            }
        }

        return string.Empty;
    }
}

Voila notre classe est prête à être utilisée, il ne reste plus qu’a éditer le workflow de build, ajouter une référence à l’assembly contenant le type du paramètre et ajouter le paramètre. Pour le déploiement, il faut mettre l’assembly dans le contrôleur de source et configurer le contrôleur de build. Vous pouvez consulter mon billet sur mon activité UpdateAssemblyInfo pour des informations détaillées.

Carpe Diem.

Vous pouvez voir l’exemple complet sur codeplex : http://updateassemblyinfo.codeplex.com/SourceControl/changeset/view/84894#1658227

Leave a Reply

  

  

  

CAPTCHA *