Skip to content
close up photo of matrix background

Creating and publishing a NuGet package on Linux

Suppose you have a couple of .dll files that were built on a TeamCity server and you want to bundle them into a NuGet package and publish them on nuget.org, how would you do that if you were a Linux user? Is that even possible??? Let’s find out!

  1. Preparation

    First things first, lets create a clean working environment:

    mkdir -p ~/repos/qa-nugetlinux
    cd qa-nugetlinux
    git init
    gi linux,vagrant >> .gitignore
    git add .gitignore
    git commit -m ".gitignore created by https://www.gitignore.io/api/linux,vagrant"
    vagrant init --minimal ubuntu/yakkety64
    git add Vagrantfile
    git commit -m "Add Vagrantfile"
    vagrant up --provider virtualbox

    This creates a Vagrant box where I will conduct my experiments. Let’s dive in and make sure that everything is up-to-date inside:

    vagrant ssh
    sudo apt-get update
    sudo apt-get -y dist-upgrade
    sudo apt-get -y autoremove
     
     
     
  2. Installing NuGet

    Now let’s get this party going!

    cd ~/vagrant
    wget https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
    chmod +x nuget.exe
    ./nuget.exe
    -bash: ./nuget.exe: cannot execute binary file: Exec format error

    Computer says no…
    Why not?

    file nuget.exe
    nuget.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

    Oops, silly me. It’s a Mono executable.

    mono nuget.exe
    The program 'mono' is currently not installed. You can install it by typing:
    sudo apt install mono-runtime

    Thank you for that helpful message, Ubuntu!

    sudo apt-get -y install mono-runtime

    16 MiB later, I try again:

    mono nuget.exe
    Unhandled Exception:
    System.IO.FileNotFoundException: Could not load file or assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies.
    File name: 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
      at NuGet.CommandLine.Program.Main (System.String[] args)  in :0 
    [ERROR] FATAL UNHANDLED EXCEPTION: System.IO.FileNotFoundException: Could not load file or assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies.
    File name: 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
      at NuGet.CommandLine.Program.Main (System.String[] args)  in :0

    System.Core is missing? OK let’s install that.

    sudo apt-get -y install libmono-system-*

    And try again:

    mono nuget.exe
    Could not load file or assembly or one of its dependencies.

    Sigh. Ok, let’s use a cannon to shoot a mosquito:

    sudo apt-get -y install mono-complete

    Does it work now?

    mono nuget.exe
    NuGet Version: 3.4.4.1321
    usage: NuGet  [args] [options] 
    Type 'NuGet help ' for help on a specific command.
    Available commands:
     add         Adds the given package to a hierarchical source. http sources are not supported. For more info, goto https://docs.nuget.org/consume/command-line-reference#add-command.
     config      Gets or sets NuGet config values.
     delete      Deletes a package from the server.
     help (?)    Displays general help information and help information about other commands.
     init        Adds all the packages from the  to the hierarchical . http feeds are not supported. For more info, goto https://docs.nuget.org/consume/command-line-reference#init-command.
     install     Installs a package using the specified sources. If no sources are specified, all sources defined in the NuGet configuration file are used. If the configuration file specifies no sources, uses the default NuGet feed.
     list        Displays a list of packages from a given source. If no sources are specified, all sources defined in %AppData%NuGetNuGet.config are used. If NuGet.config specifies no sources, uses the default NuGet feed.
     locals      Clears or lists local NuGet resources such as http requests cache, packages cache or machine-wide global packages folder.
     pack        Creates a NuGet package based on the specified nuspec or project file.
     push        Pushes a package to the server and publishes it.
                 NuGet's default configuration is obtained by loading %AppData%NuGetNuGet.config, then loading any nuget.config or .nugetnuget.config starting from root of drive and ending in current directory.
     restore     Restores NuGet packages.
     setApiKey   Saves an API key for a given server URL. When no URL is provided API key is saved for the NuGet gallery.
     sources     Provides the ability to manage list of sources located in %AppData%NuGetNuGet.config
     spec        Generates a nuspec for a new package. If this command is run in the same folder as a project file (.csproj, .vbproj, .fsproj), it will create a tokenized nuspec file.
     update      Update packages to latest available versions. This command also updates NuGet.exe itself.
    For more information, visit http://docs.nuget.org/docs/reference/command-line-reference

    And there was much rejoicing (Monty Python And The Holy Grail)
  3. Creating the .nuspec file

    1. Trying the easy way, and failing miserably

      According to some Idiot’s Guide to Creating and Publishing a NuGet package I found, I should be able to create a .nuspec file by running NuGet in the same directory as a .csproj file. Let’s try that:

      cd ~/vagrant/itextcore-dotnet/itext/itext.barcodes/
      mono ~/vagrant/nuget.exe pack itext.barcodes.csproj -verbosity detailed
      Attempting to build package from 'itext.barcodes.csproj'.
      MSBuild auto-detection: using msbuild version '4.0' from '/usr/lib/mono/4.5'. Use option -MSBuildVersion to force nuget to use a specific version of MSBuild.
      System.NotImplementedException: The method or operation is not implemented.
        at (wrapper dynamic-method) System.Object:CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object)
        at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0] (System.Runtime.CompilerServices.CallSite site, System.Dynamic.T0 arg0)  in :0 
        at NuGet.CommandLine.ProjectFactory.ResolveTargetPath ()  in :0 
        at NuGet.CommandLine.ProjectFactory.BuildProject ()  in :0 
        at NuGet.CommandLine.ProjectFactory.CreateBuilder (System.String basePath)  in :0 
        at NuGet.CommandLine.PackCommand.BuildFromProjectFile (System.String path)  in :0 
        at NuGet.CommandLine.PackCommand.BuildPackage (System.String path)  in :0 
        at NuGet.CommandLine.PackCommand.ExecuteCommand ()  in :0 
        at NuGet.CommandLine.Command.ExecuteCommandAsync ()  in :0 
        at NuGet.CommandLine.Command.Execute ()  in :0 
        at NuGet.CommandLine.Program.MainCore (System.String workingDirectory, System.String[] args)  in :0

      That seems like a big ball of NOPE to me… According to this GitHub comment from a NuGet member, this is to be expected.

    2. Hand Crank the .nuspec File

      So it’s going to be the hard way.

      <TO BE CONTINUED>
      This blog post was a draft, and I decided to publish whatever I had already, and if anyone is ever interested, I may or may not finish it. ¯_(ツ)_/¯

google search engine on macbook pro

Popular Search Terms

These are currently the popular search terms on my blog:

  • blog amedee be
    Yeah, that’s this blog.
  • localhost
    Which used to be my IRC handle a looooong time ago.
  • upgrade squeeze to wheezy sed -i
    Sometimes I blog about Ubuntu, or Linux in general.
  • guild wars bornem
    Okay, I have played Guild Wars, but not very often, and I have been in Bornem, but the combination???
  • giftige amedeeamedee giftig
    Wait, I am toxic???
  • orgasme
    Ehhhh… dunno why people come looking for orgasms on my blog.
  • telenet service
    I used to blog about bad service I got a couple of times from Telenet.
  • taxipost 2007
    Dunno.
  • ik bond ixq
    Lolwut?
vintage brown crt tv on parquet wood flooring

VRT plukt foto’s van Twitter zonder toestemming

Begin september was ik bij een familielid op bezoek in het AZ Nikolaas. Dat weekend waren de Vredefeesten bezig in Sint-Niklaas, waarbij er tientallen warmeluchtballons opstijgen van op de Grote Markt. Een spectaculair schouwspel, waar jaarlijks tienduizenden kijklustigen op afkomen.
Van op de vijfde verdieping van AZ Nikolaas had ik een mooi uitzicht over de stad en de voorbij vliegende ballons. Ik heb de panoramafunctie van mijn Nexus 4 gebruikt en de foto op Twitter geplaatst:
http://twitter.com/amedee/status/508293460898897920
Op de foto zie je een vleugel van het gebouw van AZ Nikolaas, en ik kreeg ook een bezorgde reactie van @mariegoos.
Een tijdje later werd mijn foto ook integraal geretweet door de officiele twitteraccount van @stadsintniklaas. Fijn.

De volgende dag kreeg ik van een kennis bericht dat mijn foto gebruikt werd op de VRT website deredactie.be. Ik ben even gaan zoeken (met Google Image Search) en effectief, de foto staat bij 2 artikels:

Ik ben daar eigenlijk niet zo gelukkig mee. OK, mijn naam staat er wel bij, maar moet dat nu echt, VRT? Is dit het gevolg van de opgelegde besparingen? 92.000 mensen kwamen naar de Vredefeesten, zaten daar echt geen professionele fotografen bij? Die mensen moeten ook het beleg op hun boterham verdienen! Ik ben maar een amateur die een beetje met zijn smartphone zat te prutsen, en ik vind het zelf niet eens een mooie foto.

Ik heb mijn licht eens opgestoken bij bevriende fotografen (dankjewel Monica en Evy) en ik heb de SOFAM-tarieven geraadpleegd. Blijkbaar kan ik 110.30 euro vragen per gebruik van een foto, + 200% schadevergoeding wegens geen toestemming gevraagd of gegeven, + 200% schadevergoeding wegens schending van de integriteit (want ze hebben een stuk weggeknipt, waardoor de context van het AZ Nikolaas verloren ging).
Dat komt dus in totaal op 1103 euro.

En NEEN, het is niet omdat iets op Twitter, Facebook, Instagram of soortgelijken staat, dat je het zomaar mag gebruiken. Volgens de regeltjes van Twitter mag je een tweet maar overnemen als het een embedded tweet is, zoals mijn tweet hierboven. Dus de integrale tweet, inclusief de context. Niet een stukje van de tweet, zoals een (deel van een) foto.

Ik heb een onkostennota verstuurd naar de VRT. Het bedrag dat ze me gaan betalen (if any), ga ik integraal doorstorten naar het Fonds Pascal Decroos voor Onderzoeksjournalistiek.

EDIT: deze blogpost is nog geen half uur gepubliceerd en ik zie in Google Analytics dat er al een referral is van contactbeheer.vrt.be. Ze hebben het dus gezien.

brown and black merrell hiking shoes

Dodentocht – A touch of Rose #doto14

Dodentocht 2014
A Touch of Rose

Op vrijdag 8 augustus 2014 stap ik de 100 km Dodentocht te Bornem ten voordele van het Psychosociaal Oncologisch Welzijnscentrum ‘A touch of Rose’.

De aangeboden zorg in ‘A touch of Rose’ betekent een belangrijke aanvulling op de klassieke medische therapie van een patiënt met kanker. De patiënt en zijn of haar familie, kunnen hier extra kracht uit putten om de strijd met de ziekte ten volle aan te gaan of zo goed mogelijk verder te leven met de gevolgen ervan.

De werking van ‘A touch of Rose’ wordt niet gesubsidieerd of financieel gesteund door andere organisaties. Deze extra zorg kan dus enkel maar haalbaar blijven door middel van ondersteuning door giften of acties.

Een tocht van 100 km is niet niks, maar voor het goede doel kan een mens net dat “tikkeltje meer”.
Daarom zoek ik sponsors die mij per gestapte kilometer willen steunen of een vrije bijdrage willen schenken voor dit goede doel. Wil ook jij mijn sponsor zijn?

Aarzel niet en stort je gift:

  • op het rekeningnummer van ‘A touch of Rose’
    IBAN BE56 0016 4511 9188
    BIC GEBABEBB
  • op de projectrekening bij de Koning Boudewijnstichting
    IBAN BE 10 0000 0000 0404
    BIC BPOTBEB1
    met vermelding van de volgende gestructureerde mededeling 128/2513/00150.
  • Opgepast: indien je een fiscaal attest wenst, moet de storting steeds via de Koning Boudewijnstichting verlopen!
  • Vergeet je naam en de vermelding ‘Dodentocht 2014’ + de naam van de moedige stapper die je steunt niet ! (Amedee Van Gasse, dus 🙂 )

Ik hou je op de hoogte van mijn afgelegde kilometers en de totale opbrengst van de Dodentocht ten voordele van ‘A touch of Rose’!

Vanwege ‘A touch of Rose’ en mezelf Dank-je-wel!

Voor meer info: zie www.atouchofrose.be


Mijn startnummer: 1647. Je kan me live volgen via de tracking op http://tracking2.dodentocht.be/Default.aspx?s=1647, of je kan me komen aanmoedigen langs het parcours!

Fosdem

Mijn schema

photo of person typing on computer keyboard

LAN-party games

Artemis bridge simulator
Left 4 Dead
Payday
Guild Wars 2
Alien Swarm

technology computer desktop programming

screenshots van de framebuffer

Soms moet ne mens al eens iets speciaals doen, zoals het nemen van een screenshot op een toestel dat wel Linux draait, maar geen X. Oink? Volgens StackExchange zou ik fbgrab of fbdump moeten gebruiken, maar dat is in dit concrete geval niet mogelijk because reasons.

In dit concrete geval is er een toepassing die rechtstreeks naar de framebuffer beelden stuurt. Bon, alles is een file onder Linux, dus ik ging eens piepen wat er dan eigenlijk in dat framebuffer device zat:


$ cp /dev/fb0 /tmp/framebuffer.data
$ head -c 64 /tmp/framebuffer.data
kkk�kkk�kkk�kkk�kkk�kkk�kkk�kkk�kkk�kkk�kkk�kkk�kkk�kkk�kkk�kkk�

IEKS!!!
Alhoewel…
Tiens, dat zag er verdacht regelmatig uit, telkens in groepjes van 4 bytes. “k” heeft ASCII waarde 107, of 6B hexadecimaal, en #6B6B6B is een grijstint. Ik had voorlopig nog geen enkel idee wat die “�” betekende, maar ik wist dat ik iets op het spoor was!

Ik heb framebuffer.data dan gekopieerd naar een pc met daarop Gimp. (referentie naar Contact invoegen)

YouTube fragmenten van AMC

1. Allerlei
2. Danse Macabre + Thriller / Prins Igor
3. Young person’s guide to the orchestra