(English) NuGet Packages for unstable, in-development Libraries – cont. (III)

Leider ist der Eintrag nur auf Amerikanisches Englisch verfügbar. Der Inhalt wird unten in einer verfügbaren Sprache angezeigt. Klicken Sie auf den Link, um die aktuelle Sprache zu ändern.

Previously, I wrote about using one global msbuild xml file to override nuget package content for local development. While this does work, it comes with a warning if multiple packages use this mechanism:

***Test\packages\***.0.7.1-prerelease-\build\native\***.targets(7,5):
warning MSB4011: "***Test\packagesoverride.xml.user" cannot be imported again. It was already imported at "***Test\packages\***.0.7.1-prerelease-\build\native\***.targets (6,3)".
This is most likely a build authoring error. This subsequent import will be ignored. [***Test\***Test.vcxproj]

While this is not realy a problem, it is a warning. And I don’t like warning. I like my projects to build entirly without warnings.

A soltion for this comes from classic c++ programming: use an include guard. These are the changes required:

The packagesoverride.xml.user must define a default variable. I named it HAS_packagesoverride:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <HAS_packagesoverride>True</HAS_packagesoverride>
    <NugetDevPackageTest_testLib_DevDir>C:\Dev\SomeProject\Dir</NugetDevPackageTest_testLib_DevDir>
  </PropertyGroup>
</Project>

And now importing this xml in the nuget packages‘ target files can this for this variable to avoid multiple import:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="FaroMorfCopySymbols">

  <!-- Import override settings, if they exist -->
  <ImportGroup>
    <Import
      Condition="Exists('$(SolutionDir)packagesoverride.xml.user') and '$(HAS_packagesoverride)' != 'True'"
      Project="$(SolutionDir)packagesoverride.xml.user" />
  </ImportGroup>

<!-- ... -->

 

Getagged mit: ,

(English) NuGet Packages for unstable, in-development Libraries – cont. (II)

Leider ist der Eintrag nur auf Amerikanisches Englisch verfügbar. Der Inhalt wird unten in einer verfügbaren Sprache angezeigt. Klicken Sie auf den Link, um die aktuelle Sprache zu ändern.

Previously, I wrote about using NuGet for software components, which are still in active development. One of the most important factors was the capability to override the nuget package’s content with content fetched from a directory, e.g., a working copy clone. The key element for this was a MSBuild variable NugetDevPackageTest_testLib_DevDir.

The original plan was to edit this variable using a project property page. While having a UI is nice, this has proven not to work on larger projects. The reason is simple: in larger projects, we talk about a vs solution with multiple vc projects, and many of these projects might reference our NuGet package. If we now need to switch to our local directory, we need to adjust the project properties for every project consuming the package. This is tiring and error prone. Forget to adjust just one project and you might end up with inconsistent builds. Therefore, I was seeking a more centralized configuration.

Update 2019-03-02

I updated the code examples to reflect the updates I recently came up with.

Dev. Override – II

The principle idea of having a variable to control the override remains valid. The targets in your nuget might look like this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <!-- ... -->

  <!-- Compiler settings: defines and includes -->
  <ItemDefinitionGroup Condition="'$(NugetDevPackageTest_testLib_DevDir)' == ''">
    <ClCompile>
      <PreprocessorDefinitions>HAS_NUGETDEVPACKAGETEST_TESTLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(NugetDevPackageTest_testLib_DevDir)' != ''">
    <ClCompile>
      <PreprocessorDefinitions>HAS_NUGETDEVPACKAGETEST_TESTLIB;HAS_NUGETDEVPACKAGETEST_TESTLIB_DEVDIR;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <AdditionalIncludeDirectories>$(NugetDevPackageTest_testLib_DevDir)\Project\include\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
  </ItemDefinitionGroup>

  <!-- ... -->

</Project>

The obvious question is the definition of our DevDir variable.

For this is propose a central msbuild xml at the level of the vs solution!

We include it in our targets file, right after the root Project tag starts:

<ImportGroup>
  <Import Project="$(SolutionDir)packagesoverride.xml.user" Condition="Exists('$(SolutionDir)packagesoverride.xml.user') and '$(HAS_packagesoverride)' != 'True'" />
</ImportGroup>

This line imports the msbuild xml file, if it exists. Notice, how the file name is generic and not related to our specific package. This is because multiple nuget packages can share this file!

The content of this central configuration is very simple:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <HAS_packagesoverride>True</HAS_packagesoverride>
    <NugetDevPackageTest_testLib_DevDir>C:\Dev\SomeProject\Dir</NugetDevPackageTest_testLib_DevDir>
  </PropertyGroup>
</Project>

Now if you need to override a nuget package for your whole solution, just create this file!

Drawback 1: If the file did not exist previously, an you create it, then you need to rebuild all projects with nugets referencing this package. Because they might be affected by this file.

However, once the file does exist, changes to the file are currectly and automatically detected by visual studio, and build operations are correctly triggered in the affected projects. So, it might be a nice idea to keep a file with an empty property group in place, just in case.

If you need to override multiple nugets at once, just add multiple entries into this one property group.

Drawback 2: There is no UI. So you need to edit it in your favorite text editor, meaning, you are prone to all typing errors you can come up with.

All in all, I believe this central file for the nuget override configuration is an improvement.

Getagged mit: ,

Ich mag Shields.io

Ich bin ein visueller Kerl. Das heißt, ich mag alle möglichen Arten von visuellen Repräsentationen abstrakter Daten. Natürlich mag ich also auch die ganzen fetzigen Badges die überall im Internet rumfahren. Es macht also nur Sinn dass ich die auch selber nutze.

Shields.io stellt Badges für Source-Code-Zeug zur verfügung. Und so, ohne Umschweife, hier ist die visuelle Zusammenfassung aller Nuget-Pakete die ich betreue:

 glfw
 glm
 lua
AntTweakBar
voro++
 teamcity-gtest-streamer

Bei Altem bleiben?

Es ist Zeit einen meiner Lieblingsstrips von xkcd zu rebloggen: tar

I don’t know what’s worse–the fact that after 15 years of using tar I still can’t keep the flags straight, or that after 15 years of technological advancement I’m still mucking with tar flags that were 15 years old when I started.

Es gibt viele solche Tools die noch heute benutzt werden, obwohl sie von Anfang an Müll waren. Jaja, das Beispiel hier macht sich über Nix lustig. Es gibt aber auch viele ähnliche Beispiele aus dem MS-Windows-Ökosystem.

Ich mach mich gar nicht über diese Tools lustig. Ich mach mich über die Leute lustig die noch heute diese Tools befürworten!

Getagged mit: ,

Serverumzug

Ich habe meinen alten Webhoster hinter mir gelassen und meine Webseite umgezogen.

Das war jetzt dringend nötig.

Ich hab auch das WordPress aktualisiert. Nun scheint das Plugin für mehrsprachige Posts nicht mehr richtig mit dem Editor zu funktionieren. Naja. Das ist ein Problem für ein anderes Mal.

SpringerJagd ist beendet

Meine Spielidee „SpringerJagd“ werde ich nicht weiter verfolgen.

Das Projekt ist schlicht der notwendigen Priorisierung meiner ganzen Projekte zum Opfer gefallen. Schade, aber es ist besser so. So habe ich mehr Zeit gezielt für andere Projekte. Und von denen werde ich schon bald hier schreiben. Und mit „bald“ meine ich in ein paar Monaten, oder so.

(English) Beautify HtmlAgilityPack

Leider ist der Eintrag nur auf Amerikanisches Englisch verfügbar. Der Inhalt wird unten in einer verfügbaren Sprache angezeigt. Klicken Sie auf den Link, um die aktuelle Sprache zu ändern.

HtmlAgilityPackAs can be read on the internet: HtmlAgilityPack is not for beautiful, aka human readable, html files.

“[…] it’s a ‘by design’ choice.” [https://stackoverflow.com/a/5969074]

So everyone redirects you to some other library.

Now, I am a bit stubborn. I want to use HtmlAgilityPack and I want to have indented, human-readable html files. The magic is within text nodes in the DOM. So, I wrote two utility functions to help me out.

First, to get rid of all unwanted whitespaces. This one might be a bit aggressiv, but it was ok for me:

static private void removeWhitespace(HtmlNode node) {
  foreach (HtmlNode n in node.ChildNodes.ToArray()) {
    if (n.NodeType == HtmlNodeType.Text) {
      if (string.IsNullOrWhiteSpace(n.InnerHtml)) {
        node.RemoveChild(n);
      }
    } else removeWhitespace(n);
  }
}

And, second, to create white spaces for line breaks and indentions:

internal static void beautify(HtmlDocument doc) {
  foreach (var topNode in doc.DocumentNode.ChildNodes.ToArray()) {
    switch (topNode.NodeType) {
      case HtmlNodeType.Comment: {
          HtmlCommentNode cn = (HtmlCommentNode)topNode;
          if (string.IsNullOrEmpty(cn.Comment)) continue;
          if (!cn.Comment.EndsWith("\n")) cn.Comment += "\n";
        } break;
      case HtmlNodeType.Element: {
          beautify(topNode, 0);
          topNode.AppendChild(doc.CreateTextNode("\n"));
          //doc.DocumentNode.InsertAfter(doc.CreateTextNode("\n"), topNode);
        } break;
      case HtmlNodeType.Text:
        break;
      default:
        break;
    }
  }
}

private static bool beautify(HtmlNode node, int level) {
  if (!node.HasChildNodes) return false;

  var children = node.ChildNodes.ToArray();
  bool onlyText = true;
  foreach (var c in children) {
    if (c.NodeType != HtmlNodeType.Text) onlyText = false;
  }
  if (onlyText) return false;

  string nli = "\n" + new string('\t', level);

  foreach (var c in children) {
    node.InsertBefore(node.OwnerDocument.CreateTextNode(nli), c);
    if (c.NodeType == HtmlNodeType.Element) {
      if (c.HasChildNodes) {
        if (beautify(c, level + 1)) {
          c.AppendChild(c.OwnerDocument.CreateTextNode(nli));
        }
      }
    }
  }
  return true;
}

As you might see, the code is pretty hacky. But, it works for me. Maybe, it also works for you, or it can be a starting point.

Getagged mit: ,

Another Nuget: TeamCity GoogleTest Streamer

Und hier ist nochmal ein neues Nuget Package:

https://bitbucket.org/sgrottel_nuget/teamcity-gtest-streamer

https://www.nuget.org/packages/teamcity-gtest-streamer

Eine kleine Bibliothek für eine bessere Integration von GoogleTest in TeamCity. Tatsächlich ist es eine einzelne Datei als Header Only Library. Es gibt trotzdem ein Nuget-Paket für einfache Integration und Updates.

Getagged mit: ,

GLM 0.9.9 NuGet

GLM ist eine nette, schlanke, gute mathe Bibliothek für OpenGL. Sie ist header-only. Macht ein NuGet trotzdem sinn? Ich meine „Ja“. Die einfache Benutzung und die saubere Versionierung sind den minimalen Mehraufwand absolut wert.

Ich habe nun auch die Wartung des GLM Nuget-Pakets mit übernommen und das Paket auf die Version 0.9.9 aktualisiert.

Getagged mit: ,

Lua Nuget aktualisiert auf 5.3.5

Lua wurde auf 5.3.5 aktualisiert.

Also habe ich auch mein NuGet-Paket auf Lua 5.3.5 aktualisiert.

Getagged mit: ,
Top