313 строки
14 KiB
C#
313 строки
14 KiB
C#
#addin nuget:?package=Cake.Incubator&version=3.0.0
|
|
#addin nuget:?package=Cake.Yaml&version=2.1.0
|
|
#addin nuget:?package=Cake.Json&version=3.0.1
|
|
#addin nuget:?package=Newtonsoft.Json&version=9.0.1
|
|
#addin nuget:?package=YamlDotNet&version=4.2.1
|
|
|
|
#load "poco.cake"
|
|
#load "poco.yaml.cake"
|
|
// #load "poco.xml.cake"
|
|
|
|
using System.Linq;
|
|
|
|
using YamlDotNet.Core;
|
|
using YamlDotNet.Serialization;
|
|
using Newtonsoft.Json;
|
|
|
|
var TARGET = Argument ("target", Argument ("t", Argument ("Target", "build")));
|
|
var COMPONENT_NAME = Argument ("component-name", Argument ("cn", Argument ("Component-name", "")));
|
|
var COMPONENT_VERSION = Argument ("component-version", Argument ("cv", Argument ("Component-version", "")));
|
|
var BUMP_DEPENDENTS = Argument ("bump-dependents", Argument ("bd", false));
|
|
|
|
// Creates a dictionary of components available in repo that are not deprecated.
|
|
public Dictionary<string, GoogleBase> CreateComponents ()
|
|
{
|
|
var googleComponents = new Dictionary<string, GoogleBase> ();
|
|
|
|
googleComponents ["Firebase.ABTesting"] = GetComponent<Firebase.ABTesting> ();
|
|
googleComponents ["Firebase.AdMob"] = GetComponent<Firebase.AdMob> ();
|
|
googleComponents ["Firebase.Analytics"] = GetComponent<Firebase.Analytics> ();
|
|
googleComponents ["Firebase.Auth"] = GetComponent<Firebase.Auth> ();
|
|
googleComponents ["Firebase.CloudFirestore"] = GetComponent<Firebase.CloudFirestore> ();
|
|
googleComponents ["Firebase.CloudMessaging"] = GetComponent<Firebase.CloudMessaging> ();
|
|
googleComponents ["Firebase.Core"] = GetComponent<Firebase.Core> ();
|
|
googleComponents ["Firebase.Crashlytics"] = GetComponent<Firebase.Crashlytics> ();
|
|
googleComponents ["Firebase.CrashReporting"] = GetComponent<Firebase.CrashReporting> ();
|
|
googleComponents ["Firebase.Database"] = GetComponent<Firebase.Database> ();
|
|
googleComponents ["Firebase.DynamicLinks"] = GetComponent<Firebase.DynamicLinks> ();
|
|
googleComponents ["Firebase.InstanceID"] = GetComponent<Firebase.InstanceID> ();
|
|
googleComponents ["Firebase.Invites"] = GetComponent<Firebase.Invites> ();
|
|
googleComponents ["Firebase.MLKit"] = GetComponent<Firebase.MLKit> ();
|
|
googleComponents ["Firebase.MLKit.Common"] = GetComponent<Firebase.MLKit.Common> ();
|
|
googleComponents ["Firebase.MLKit.ModelInterpreter"] = GetComponent<Firebase.MLKit.ModelInterpreter> ();
|
|
googleComponents ["Firebase.PerformanceMonitoring"] = GetComponent<Firebase.PerformanceMonitoring> ();
|
|
googleComponents ["Firebase.RemoteConfig"] = GetComponent<Firebase.RemoteConfig> ();
|
|
googleComponents ["Firebase.Storage"] = GetComponent<Firebase.Storage> ();
|
|
|
|
googleComponents ["Google.Analytics"] = GetComponent<Google.Analytics> ();
|
|
googleComponents ["Google.AppIndexing"] = GetComponent<Google.AppIndexing> ();
|
|
googleComponents ["Google.Cast"] = GetComponent<Google.Cast> ();
|
|
googleComponents ["Google.Core"] = GetComponent<Google.Core> ();
|
|
googleComponents ["Google.InstanceID"] = GetComponent<Google.InstanceID> ();
|
|
googleComponents ["Google.Maps"] = GetComponent<Google.Maps> ();
|
|
googleComponents ["Google.MobileAds"] = GetComponent<Google.MobileAds> ();
|
|
googleComponents ["Google.Places"] = GetComponent<Google.Places> ();
|
|
googleComponents ["Google.PlayGames"] = GetComponent<Google.PlayGames> ();
|
|
googleComponents ["Google.SignIn"] = GetComponent<Google.SignIn> ();
|
|
googleComponents ["Google.TagManager"] = GetComponent<Google.TagManager> ();
|
|
|
|
googleComponents ["Xamarin.Build.Download"] = GetComponent<Xamarin.Build.Download> ();
|
|
|
|
return googleComponents;
|
|
}
|
|
|
|
// Gets a component with its basic information.
|
|
public T GetComponent<T> () where T : GoogleBase, new ()
|
|
{
|
|
T component = new T ();
|
|
|
|
FilePath nuspecPath = null;
|
|
|
|
// XBD doesn't have its own .nuspec file, we need to get
|
|
// the XBD version from one of the Firebase/Google .nuspec files.
|
|
// Get the version with XPath.
|
|
if (component is Xamarin.Build.Download) {
|
|
nuspecPath = GetFiles ($"./Firebase.Core/nuget/*.nuspec").ToList () [0];
|
|
component.CurrentVersion = XmlPeek (nuspecPath, "/package/metadata/dependencies/group[@targetFramework='Xamarin.iOS10']/dependency[@id='Xamarin.Build.Download']/@version");
|
|
} else {
|
|
nuspecPath = GetFiles ($"./{component.Name}/nuget/*.nuspec").ToList () [0];
|
|
component.CurrentVersion = XmlPeek (nuspecPath, "/package/metadata/version/text()");
|
|
}
|
|
|
|
// Create the bumped version, in case we need to use it,
|
|
// by incresing by one the last digit.
|
|
var versionParts = component.CurrentVersion.Split ('.');
|
|
var lastIndex = versionParts.Length - 1;
|
|
versionParts [lastIndex] = (int.Parse (versionParts [lastIndex]) + 1).ToString ();
|
|
component.NewVersion = string.Join (".", versionParts);
|
|
|
|
return component;
|
|
}
|
|
|
|
// Updates versions inside of the component.yaml of the desired component
|
|
public void UpdateYamlVersions (GoogleBase component)
|
|
{
|
|
var yamlPath = new FilePath ($"./{component.Name}/component/component.yaml");
|
|
|
|
// Some components doesn't have a component.yaml file
|
|
if (!FileExists (yamlPath))
|
|
return;
|
|
|
|
Information ($"Updating version in component.yaml file of {component.Name} component.");
|
|
|
|
// Deserialize the component.yaml into an object
|
|
var componentData = DeserializeYamlFromFile<Component> (yamlPath);
|
|
|
|
// Update the main version of component.yaml
|
|
componentData.Version = component.NewVersion;
|
|
|
|
// Update the NuGet package version of component.yaml
|
|
var parts = componentData.Packages.iOSUnifiedPaths [0].Split ('=');
|
|
parts [1] = component.NewVersion;
|
|
componentData.Packages.iOSUnifiedPaths [0] = string.Join ("=", parts);
|
|
|
|
// Serialize the object into component.yaml file
|
|
SerializeYamlToFile (yamlPath, componentData);
|
|
}
|
|
|
|
// Updates the main version of the .nuspec file of desired component
|
|
public void UpdateNuspecMainVersion (GoogleBase component)
|
|
{
|
|
// XBD doesn't have its own .nuspec file, so,
|
|
// we cannot update a main version of .nuspec file.
|
|
if (component is Xamarin.Build.Download)
|
|
return;
|
|
|
|
Information ($"Updating main version in .nuspec file of {component.Name} component.\n");
|
|
|
|
// There is just one .nuspec file per component,
|
|
// so we are safe to call the first result.
|
|
var nuspecPath = GetFiles ($"./{component.Name}/nuget/*.nuspec").ToList () [0];
|
|
XmlPoke (nuspecPath, "/package/metadata/version", component.NewVersion);
|
|
}
|
|
|
|
// Updates the dependency version of the .nuspec file on dependent components
|
|
public void UpdateNuspecDependencyVersion (GoogleBase component)
|
|
{
|
|
foreach (var name in component.BaseOf) {
|
|
Information ($"Updating {component.Name} dependency version in .nuspec file of {name} component.");
|
|
|
|
// There is just one .nuspec file per component,
|
|
// so we are safe to call the first result.
|
|
var nuspecPath = GetFiles ($"./{name}/nuget/*.nuspec").ToList () [0];
|
|
|
|
var result = XmlPeek (nuspecPath, $"/package/metadata/dependencies/group[@targetFramework='Xamarin.iOS10']/dependency[@id='{component.NuGetId}']/@version");
|
|
if (!string.IsNullOrWhiteSpace (result))
|
|
XmlPoke (nuspecPath, $"/package/metadata/dependencies/group[@targetFramework='Xamarin.iOS10']/dependency[@id='{component.NuGetId}']/@version", component.NewVersion);
|
|
}
|
|
}
|
|
|
|
// This method is only called if we are updating XBD
|
|
// Updates XBD's version in all packages.config files of component's samples
|
|
public void UpdateSamplesPackagesConfigVersion (GoogleBase component)
|
|
{
|
|
foreach (var name in component.BaseOf) {
|
|
// A component could have more than one sample, so,
|
|
// we need to iterate through all of sample's packages.config
|
|
var packagesPaths = GetFiles ($"./{name}/samples/**/packages.config");
|
|
|
|
foreach (var packagePath in packagesPaths) {
|
|
Information ($"Updating {component.Name} version in packages.config file of {name} sample component.");
|
|
XmlPoke (packagePath, $"/packages/package[@id='{component.Name}']/@version", component.NewVersion);
|
|
}
|
|
}
|
|
}
|
|
|
|
// This method is only called if we are updating XBD
|
|
// Updates XBD's version in all .csproj files of component's samples
|
|
public void UpdateCsprojVersion (GoogleBase component)
|
|
{
|
|
// Xml .csproj has Namespaces, we need to pass the namespaces
|
|
// to XPath to be able to find the desired node.
|
|
var xmlPeekSettings = new XmlPeekSettings {
|
|
Namespaces = new Dictionary<string, string> { { "Project", "http://schemas.microsoft.com/developer/msbuild/2003" } }
|
|
};
|
|
var xmlPokeSettings = new XmlPokeSettings {
|
|
Namespaces = new Dictionary<string, string> { { "Project", "http://schemas.microsoft.com/developer/msbuild/2003" } }
|
|
};
|
|
|
|
foreach (var name in component.BaseOf) {
|
|
// A component could have more than one sample, so,
|
|
// we need to iterate through all of sample's .csproj
|
|
var csprojPaths = GetFiles ($"./{name}/samples/**/*.csproj");
|
|
|
|
foreach (var csprojPath in csprojPaths) {
|
|
Information ($"Updating {component.Name} version in .csproj file of {name} sample component.");
|
|
|
|
var result = XmlPeek (csprojPath, $"/Project:Project/Project:Import[contains(@Project, '{component.Name}.props')]/@Project", xmlPeekSettings);
|
|
var parts = result.Split (new [] { component.CurrentVersion }, StringSplitOptions.RemoveEmptyEntries);
|
|
var newValue = string.Join (component.NewVersion, parts);
|
|
XmlPoke (csprojPath, $"/Project:Project/Project:Import[contains(@Project, '{component.Name}.props')]/@Project", newValue, xmlPokeSettings);
|
|
|
|
result = XmlPeek (csprojPath, $"/Project:Project/Project:Import[contains(@Project, '{component.Name}.props')]/@Condition", xmlPeekSettings);
|
|
parts = result.Split (new [] { component.CurrentVersion }, StringSplitOptions.RemoveEmptyEntries);
|
|
newValue = string.Join (component.NewVersion, parts);
|
|
XmlPoke (csprojPath, $"/Project:Project/Project:Import[contains(@Project, '{component.Name}.props')]/@Condition", newValue, xmlPokeSettings);
|
|
|
|
result = XmlPeek (csprojPath, $"/Project:Project/Project:Import[contains(@Project, '{component.Name}.targets')]/@Project", xmlPeekSettings);
|
|
parts = result.Split (new [] { component.CurrentVersion }, StringSplitOptions.RemoveEmptyEntries);
|
|
newValue = string.Join (component.NewVersion, parts);
|
|
XmlPoke (csprojPath, $"/Project:Project/Project:Import[contains(@Project, '{component.Name}.targets')]/@Project", newValue, xmlPokeSettings);
|
|
|
|
result = XmlPeek (csprojPath, $"/Project:Project/Project:Import[contains(@Project, '{component.Name}.targets')]/@Condition", xmlPeekSettings);
|
|
parts = result.Split (new [] { component.CurrentVersion }, StringSplitOptions.RemoveEmptyEntries);
|
|
newValue = string.Join (component.NewVersion, parts);
|
|
XmlPoke (csprojPath, $"/Project:Project/Project:Import[contains(@Project, '{component.Name}.targets')]/@Condition", newValue, xmlPokeSettings);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void UpdateComponentVersion (Dictionary<string, GoogleBase> components, string componentName, bool bumpDependents)
|
|
{
|
|
var message = $"Working on {componentName} component";
|
|
Information ($"{new string ('/', message.Length + 6)}");
|
|
Information ($"// {message} //");
|
|
Information ($"{new string ('/', message.Length + 6)}\n");
|
|
|
|
var component = components [componentName];
|
|
|
|
UpdateYamlVersions (component);
|
|
UpdateNuspecMainVersion (component);
|
|
UpdateNuspecDependencyVersion (component);
|
|
|
|
if (component is Xamarin.Build.Download) {
|
|
UpdateSamplesPackagesConfigVersion (component);
|
|
UpdateCsprojVersion (component);
|
|
}
|
|
|
|
if (!bumpDependents)
|
|
return;
|
|
|
|
Information ($"\nBUMP_DEPENDENTS was set to true! Starting bumping {component.Name} dependent components due {component.Name} version update...");
|
|
|
|
foreach (var name in component.BaseOf) {
|
|
var dependentComponent = components [name];
|
|
dependentComponent.Bumped = true;
|
|
Information ($"\nBumping {dependentComponent.Name} component from version {dependentComponent.CurrentVersion} to {dependentComponent.NewVersion}...\n");
|
|
UpdateComponentVersion (components, name, false);
|
|
}
|
|
}
|
|
|
|
Task ("build").Does (() =>
|
|
{
|
|
if (string.IsNullOrWhiteSpace (COMPONENT_NAME))
|
|
throw new CakeException ("COMPONENT_NAME You must to specify a Component Name to update with -cn | --component-name | --Component-name.");
|
|
|
|
if (string.IsNullOrWhiteSpace (COMPONENT_VERSION))
|
|
throw new CakeException ("COMPONENT_VERSION You must to specify the new Component version with -cv | --component-version | --Component-version.");
|
|
|
|
var components = CreateComponents();
|
|
var updatedComponent = components [COMPONENT_NAME];
|
|
updatedComponent.NewVersion = COMPONENT_VERSION;
|
|
|
|
Information ($"Component to updated: {updatedComponent.Name} {updatedComponent.CurrentVersion} => {updatedComponent.NewVersion}\n");
|
|
|
|
UpdateComponentVersion (components, COMPONENT_NAME, BUMP_DEPENDENTS);
|
|
|
|
components.Remove (updatedComponent.Name);
|
|
|
|
Information ($"Component updated: {updatedComponent.Name} {updatedComponent.CurrentVersion} => {updatedComponent.NewVersion}\n");
|
|
|
|
Information ("List of bumped components due update:");
|
|
foreach (var pair in components)
|
|
if (pair.Value.Bumped)
|
|
Information ($"{pair.Key,-31}{pair.Value.CurrentVersion,-11}=>{"",-3}{pair.Value.NewVersion}");
|
|
});
|
|
|
|
Task ("Default").IsDependentOn ("build");
|
|
|
|
RunTarget (TARGET);
|
|
|
|
// public T DeserializeXmlFromFile<T> (FilePath filename)
|
|
// {
|
|
// T result = default (T);
|
|
// // var serializer = new System.Xml.XmlSerializer (typeof (T));
|
|
|
|
// // A FileStream is needed to read the XML document.
|
|
// using (FileStream fileStream = new FileStream (filename.FullPath, FileMode.Open)) {
|
|
// var reader = XmlReader.Create (fileStream);
|
|
// // result = (T)serializer.Deserialize (reader);
|
|
// }
|
|
|
|
// return result;
|
|
// }
|
|
|
|
// public void SerializeXmlToFile<T> (FilePath filename, T instance)
|
|
// {
|
|
// var serializer = new XmlSerializer (typeof (T));
|
|
// var namespace = new XmlSerializerNamespaces ();
|
|
// namespace.Add ("", "");
|
|
|
|
// using (var textWriter = new StreamWriter (nuspec))
|
|
// serializer.Serialize (textWriter, instance, namespace);
|
|
// }
|
|
|
|
// public void AddNuGetCommentToFilesNode (FilePath filename)
|
|
// {
|
|
// XDocument xml = null;
|
|
// using (FileStream fileStream = new FileStream (filename.FullPath, FileMode.Open))
|
|
// xml = XDocument.Load (fileStream);
|
|
|
|
// var filesNode = xml.Root.Element ("files");
|
|
|
|
// foreach (var fileNode in filesNode.Elements ()) {
|
|
// if (!fileNode.Attribute ("target").Value.EndsWith ("targets", StringComparison.CurrentCulture))
|
|
// continue;
|
|
|
|
// fileNode.AddBeforeSelf (new XComment ("Add targets file for external native reference download"));
|
|
// break;
|
|
// }
|
|
|
|
// using (TextWriter textWriter = new NoEncodingStreamWriter (nuspec))
|
|
// xml.Save (tw);
|
|
// } |