-->

dev nuget, dotnet

Package management is quite easy with .NET as we have NuGet as the default package manager. We have direct access to hundreds of thousands of packages freely hosted at NuGet.org.

Recently, a free package called FluentAssetions, which is a very popular NuGet package, became a paid product. So if you upgrade from the free version 7 to paid version 8 you have to pay for the package.

Normally when you start using a package it’s easy to upgrade. NuGet automatically upgrades everything to the latest version. This made me think, if you are using FluentAssertions, it may cause some issues if you have developers who aren’t aware of the licensing issue. They may without realizing license difference, automatically upgrade to a paid version.

To avoid this issue, you can control the version of your packages. Let’s see how it works in a demo application. Open a terminal and choose a directory that you want to work in.

Then run the following commands:

mkdir NuGetVersioningDemo
cd NuGetVersioningDemo
dotnet new console

Now you should have a new Console Application created in your directory. Open it with your IDE.

Add Newtonsoft.Json package to work with package versions by running the following command:

dotnet add package Newtonsoft.Json

At this point, your project should look like this (I’m using JetBrains Rider in this example but it the project structure and the NuGet package should look similar if you’re using a different IDE):

Screenshot of the project setup with a NuGet package added

If you don’t specify the version, NuGet automatically fetches the latest version which in this case is 13.0.3. To get a specific version you can use the same dotnet command and provide the version as shown in the example below:

dotnet add package Newtonsoft.Json --version 12.0.1

So for the sake of demonstrating version control, let’s assume Newtonsoft.Json became a paid product as of version 13 and you want to upgrade to all versions up to v13. I didn’t use actual FluentAssertions in this example because I didn’t want anyone to make a mistake and accidentally upgrade to the paid version.

The way to manage the versions is using square brackets and parentheses.

For example, the following command installs the latest package up until v13

dotnet add package Newtonsoft.Json --version "[*,13)"

This way you can lock in the maximum version you want to install for a specific version.

Resources

dev powershell, tip, match, contains, aws, lightsail, wordpress

I was working on a WordPress project recently. The project is to set up a WordPress blog using Amazon Lightsail service. I ended up blogging it here, but I want to talk about something else in this post.

Use Case: Filter results using -Contains operator

Amazon Lightsail comes with pre-packed applications, and you can create an instance by providing the blueprint id. You can search for blueprints by using the Get-LSBlueprintList cmdlet. It returns a list like this:

Screenshot of the terminal showing the results of Get-LSBlueprintList cmdlet

WordPress comes in two different blueprints: Single-site vs multi-site.

So my initial action was to filter the list based on the name containing the word “wordpress”. So I ran this script to get the results:

$applicationName = "wordpress"
Get-LSBlueprintList | Where-Object { 
    ($_.IsActive -eq $TRUE) -and
    ($_.Name -contains $applicationName)
}

To my surprise, this command returned the following result:

Screenshot of the terminal showing the results of Get-LSBlueprintList cmdlet with contains filter, filtering by the word wordpress and isactive set to true

The problem: Missing Wordpress blueprint

In the Amazon Lightsail dashboard, I can see the Wordpress Multisite exists:

Screenshot of Amazon Lightsail dashboard instance selection page with wordpress-multisite highlighted

I even captured the API call the dashboard makes when creating a WordPress Multisite instance and it looks like this:

Screenshot of captured API call showing wordpress_multisite as blueprintid

So how was it possible that wordpress_multisite blueprint id existed but I couldn’t get it via Get-LSBlueprintList? I thought there was something wrong with the cmdlet and even created a supported ticket for AWS!. To my surprise the problem was somewhere else.

The root cause: Contains operator works in mysterious ways!

As a C# developer, when I see “Contains”, I think of checking the existence of a substring in a string.

For example, check out this simple example:

Screenshot of C# application showing Contains function results

It’s checking whether or not the word “wordpress_multisite” contains the word “wordpress” and the answer is yes!

Now, let’s take a look at the Powershell-equivalent:

$wordpressMultisite = "wordpress_multisite"
$containsWordpress = $wordpressMultisite -contains "wordpress"
$containsWordpress

and here is the result:

Screenshot of Powershell script showing Contains operator results with substring

In this case, the answer is no!

The reason is contains operator is by design meant to be used to search collections for a string. For example, the following example illustrates the intended use:

$listOfApplications = "wordpress", "lamp", "nodejs"
$listOfApplicationsContainsWordpress = $listOfApplications -contains "wordpress"
$listOfApplicationsContainsWordpress

and the result is:

Screenshot of Powershell script showing Contains operator results over a list of strings

The solution: Match Operator

The solution is using the match operator for substrings. In my original script, all I had to do was replace contains with match and got the expected results.

Final script:

$applicationName = "wordpress"
Get-LSBlueprintList | Where-Object { 
    ($_.IsActive -eq $TRUE) -and
    ($_.Name -match $applicationName)
}

Output of the script:

Screenshot of Powershell script showing both wordpress and wordpress_nultisite results

Conclusion

So there you have it: Always read the documentation!

As Powershell is based on the .NET framework, I instinctively assumed contains would search a string for substrings, but it works entirely differently.

I lost some time but learned a valuable lesson. I hope you find this post useful too, and it prevents the same thing from happening to you too.

Resources

hobby raspberry_pi, plex, media_server

Raspberry Pis these days are powerful computers that can run a lot of tasks at home with very efficient electricity usage. In this post I’m going to show how to use a Raspberry Pi 4 8GB as a Plex server and serve your own media files in your own network.

Hardware

  • Raspberry Pi 4 (8 GB)
  • Argon ONE case (with M.2 adapter)
  • M.2 SATA SSD (1TB)
  • Standard pi power supply

Getting Started

In this project I used an Argon ONE M.2 Case for Raspberry Pi 4 as it allowed me to use an SSD drive with the Pi which is a lot faster than a microSD card.

Argon ONE comes with a comprehensive used guide and take about 10 minutes to put everything together so it’s not too different than using a regular Pi case. The added benefits are:

  • You get to use a M.2 SATA SSD (Be mindful about the SATA here. It doesn’t work with NVMe SSDs even though it fits. So make sure to buy a M.2 SATA SSD)
  • You get 2 full-sized HDMI ports instead of the micro ones that come with a Pi 4

The final build looks like this with a 5-bay YottaMaster enclosure attached to it:

Software Installation

The easiest installation way I could find is downloading the Plex Media Server for Linux package from Plex Downloads Page

First choose Linux from the OS list

and click Choose Distribution

Once you’ve downloaded the installation package right click and select Package install

After the installation open http://localhost:32400/web and you’re ready to go!

Plex Account

I already had an account so I just logged in with my credentials. This automatically adds the new server to your account so you can see the libraries in other server instances in your account as well.

File Share

Because I attached a 5-bay hard drive enclosure to the Pi, I wanted to use it for a general file server as well. This also helps if your media files are located somewhere else on the network and you want to copy them over the network if you’re not able to attach the source drive directly to the Plex Server Pi.

To create the file server I followed this guide to install Samba on my Pi: Samba: Set up a Raspberry Pi as a File Server for your local network

Troubleshoot File Permission Issue

One issue I had when I tried to add some test folders was that Plex wasn’t able to list the folders in a selected drive. I found the solution here: Plex Media Server cannot see sub folders.. Permissions issue?

Basically added the permissions to the folders in the path as shown in the accepted answer:

sudo chmod a+rX /mnt
sudo chmod a+rX /mnt/sda
sudo chmod a+rX /mnt/sda/will

Client

I’m not going to go into much detail on the client side as there are a vast number of ways to consume content from a Plex Server. In my case, I’m using a Kodi on another Raspberry Pi and as soon as I added the new Plex Server to my Plex account I was able to view the content on my client Kodi Pi.

Conclusion

Overall it was quite straightforward as the server package came ready to install. The only issue I had was to figure out the folder permission issue and after that’s been resolved I was able to enjoy a brand new Plex Server instance in my own network. Hope this helps if you’re after similar results.

Resources