Skip to content
/ update Public

Library to update software from different sources with user defined models.

License

Notifications You must be signed in to change notification settings

sunriax/update

Repository files navigation

Version: 1.0 Release Build Status codecov License: GPL v3

Update Tool

Description:

With Update Tool updates from different sources (e.g. GitHub, WWW, FTP, ...) can be made. An example library how UpdateModels are created can be found here.


Installation

To install Update Tool it is possible to download necessary libraries [zip | tar.gz] or install the library via nuget.

PM> Install-Package RaGae.Update

After adding/installing the UpdateLib in a project it is necessary to place the user update models to a directory in your project.

Installed Models

To copy the user created models to output folder it is necessary to setup the *.csproj file.

*.csproj

<Project Sdk="Microsoft.NET.Sdk">
  // ...

  <ItemGroup>
    <LibraryFiles Include="$(ProjectDir)Model\*" />
  </ItemGroup>

  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Copy SourceFiles="@(LibraryFiles)" DestinationFolder="$(TargetDir)Model" SkipUnchangedFiles="true" />
  </Target>
  
  // ...
</Project>

Configuration with path or file after Installation

UpdateLib.Path.json

{
  "ReflectionConfig": [
    {
      "ReflectionPath": "Model",
      "FileSpecifier": "*UpdateModelLib.dll"
    }
  ]
}

UpdateLib.File.json

{
  "ReflectionConfig": [
    {
      "Files": [
        "RaGae.UpdateLib.TemplateUpdateModelLib.dll",
        "RaGae.UpdateLib.??UpdateModelLib.dll",
        "..."
      ]
    }
  ]
}

An example project howto use the Update Tool can be found within this repository in the MakeUpdate project.


Structure

Initialisation

Update update = new Update("Arguments from command line");

UpdateLib.json

{
  "ReflectionConfig": [
    {
        "ReflectionPath": "Model",
        "FileSpecifier": "*UpdateModelLib.dll"
    }
  ]
}

UserGeneratedUpdateModelLib.json

{
  "UpdateConfig": {
    "Model": "Template",
    "SkipBeforeUpdate": false,
    "SkipUpdate": false,
    "SkipAfterUpdate": false
  },
  "ReflectionConfig": [
    {
      "ReflectionPath": "Marshaler",
      "FileSpecifier": "*MarshalerLib.dll"
    }
  ],
  "ArgumentConfig": {
    "Schema": [
      {
        "Argument": [
          "p",
          "parameter"
        ],
        "Marshaler": "*",
        "Required": true
      }
    ],
    "Delimiter": "-:/"
  }
}

Arguments from CLI

The first argument contains the filename for configuration of UpdateLib and is not bypassed to the UpdateModel libraries. The subsequent arguments are passed to the update model.

UserUpdate.exe UpdateLib.json UserGeneratedUpdateModelLib.json -p "Test"
# or
UserUpdate.exe UpdateLib.json UserGeneratedUpdateModelLib.json -parameter "Test"
string[] args = {
    "UpdateLib.json",
    "UserGeneratedUpdateModelLib.json"
    "-p",
    "Test"
};
Update update = new Update(args);
update.UpdateMessage += Console.WriteLine;  // Get messages from UpdateModel
update.ExecuteUpdate();

Build your own Model

  1. Create a new VisualStudio .NET Standard Classlibrary (??UpdateModelLib)
  2. Link a new project reference to RaGae.UpdateLib.UpdateModelLib.dll (in this repository) or install as nuget (see below)
  3. Write Model (See example code below)
  4. Copy the TestUpdateModelLib.dll to the Model directory in your executable project
PM> Install-Package RaGae.Update.Model

Model with no arguments

UpdateLib.json

{
  "ReflectionConfig": [
    {
      "ReflectionPath": "Model",
      "FileSpecifier": "*UpdateModelLib.dll"
    }
  ]
}

TestUpdateModelLib.NoArguments.json

{
  "UpdateConfig": {
    "Model": "Test",
    "SkipBeforeUpdate": false,
    "SkipUpdate": false,
    "SkipAfterUpdate": false
  }
}
using System;
using RaGae.UpdateLib.UpdateModelLib;

namespace RaGae.UpdateLib.TestUpdateModelLib
{
    public class TestUpdateModel : UpdateModel
    {
        public override event WriteMessage UpdateMessage;

        private const string model = "Test";
        public override string Model { get => model.ToLower(); }

        // Necessary for reflector library, otherwise the class can not be found!
        // If the constructor is not used it can be private
        // If no arguments are passed to the model use this constructor
        private TestUpdateModel()
        {

        }

        // If no arguments are passed to the model the constructor can be removed!
        // public TestUpdateModel(IEnumerable<string> args) : base(args)
        // {
        //     // Initiate config
        //     this.config = new TestUpdateConfig()
        //     {
        //       // ...
        //     };
            
        // }

        public override void BeforeUpdate()
        {
            this.UpdateMessage?.Invoke("Things to do before update");
        }

        public override void Update()
        {
            this.UpdateMessage?.Invoke("Things to update");
        }

        public override void AfterUpdate()
        {
            this.UpdateMessage?.Invoke("Things to do after update");
        }
    }
}

Application

UserUpdate.exe UpdateLib.json TestUpdateModelLib.NoArguments.json
string[] args = {
    "UpdateLib.json",
    "TestUpdateModelLib.NoArguments.json"
};
Update update = new Update(args);
update.UpdateMessage += Console.WriteLine;  // Get messages from UpdateModel
update.ExecuteUpdate();

Model with arguments

Important: If arguments are used it is necessary to install required marshalers in the application folder. A readme howto do this can be found here.

UpdateLib.json

{
  "ReflectionConfig": [
    {
      "ReflectionPath": "Model",
      "FileSpecifier": "*UpdateModelLib.dll"
    }
  ]
}

TestUpdateModelLib.NoArguments.json

{
  "UpdateConfig": {
    "Model": "Test",
    "SkipBeforeUpdate": false,
    "SkipUpdate": false,
    "SkipAfterUpdate": false
  },
  "ReflectionConfig": [
    {
      "ReflectionPath": "Marshaler",
      "FileSpecifier": "*MarshalerLib.dll"
    }
  ],
  "ArgumentConfig": {
    "Schema": [
      {
        "Argument": [
          "p",
          "parameter"
        ],
        "Marshaler": "*",
        "Required": true
      }
    ],
    "Delimiter": "-:/"
  }
}
using System;
using RaGae.UpdateLib.UpdateModelLib;

namespace RaGae.UpdateLib.TestUpdateModelLib
{
    public class TestUpdateModel : UpdateModel
    {
        public override event WriteMessage UpdateMessage;

        private const string model = "Test";
        public override string Model { get => model.ToLower(); }

        private readonly TestUpdateConfig config;

        // Necessary for reflector library, otherwise the class can not be found!
        // If the constructor is not used it can be private
        // If no arguments are passed to the model use this constructor
        private TestUpdateModel()
        {

        }

        // If no arguments are passed to the model the constructor can be removed!
        public TestUpdateModel(IEnumerable<string> args) : base(args)
        {
            // Initiate config
            this.config = new TestUpdateConfig()
            {
              Parameter = base.argument.GetValue<string>("p")
              // or
              // Parameter = base.argument.GetValue<string>("parameter")
            };
            
        }

        public override void BeforeUpdate()
        {
            this.UpdateMessage?.Invoke("Things to do before update");
        }

        public override void Update()
        {
            this.UpdateMessage?.Invoke("Things to update");
            this.UpdateMessage?.Invoke($"Parameter {this.config.Parameter}");
        }

        public override void AfterUpdate()
        {
            this.UpdateMessage?.Invoke("Things to do after update");
        }

        internal class TestUpdateConfig
        {
          public string Parameter { get; set; }
        }
    }
}

Application

UserUpdate.exe UpdateLib.json UserGeneratedUpdateModelLib.json -p "Test"
# or
UserUpdate.exe UpdateLib.json UserGeneratedUpdateModelLib.json -parameter "Test"
string[] args = {
    "UpdateLib.json",
    "TestUpdateModelLib.NoArguments.json"
    "-p",
    // or
    // "-parameter",
    "Test"
};
Update update = new Update(args);
update.UpdateMessage += Console.WriteLine;  // Get messages from UpdateModel
update.ExecuteUpdate();

R. Gächter