DEV Community

Cover image for PACX ⁓ Working with solutions
Riccardo Gregori
Riccardo Gregori

Posted on

PACX ⁓ Working with solutions

PAC CLI provides a rich namespace dedicated to working with Dataverse solutions.

The commands provided there are really powerful, and designed to drive a code-first approach to solution management, that personally I ❤️ a lot.

Before PACX, my usual Dataverse development cycle was:

  1. use pac solution init to initialize locally my dataverse solution project (*.cdsproj)
  2. manually update the generated Solution.xml file to add details about my company's publisher
  3. build the solution via dotnet build
  4. if not previously done, connect to my Dataverse environment via pac auth
  5. publish the solution to dataverse via pac solution import
  6. start manually create/update solution components via make.powerapps.com
  7. sync the changes locally via pac solution sync
  8. when ready, commit everything on my Azure DevOps repo

When I started scripting data model manipulations with PACX, I felt the urge of a couple more commands to streamline my development activities.

pacx solution setDefault

At first it was pacx solution setDefault. This came before Dataverse preferred solution feature came out, and it's pretty much a "local" version of it.

When I created tables or columns via PACX (we'll see how to in the upcoming articles) I wanted them to be placed automatically in the context of a given solution. pacx solution setDefault allows user to define which solution should be considered "default" from now on, on the currently selected environment.

pacx solution setDefault

PACX saves in it's local settings storage the default solution specified for each environment. Then, when I ran any command such as pacx table create, I no longer needed to pass the --solution argument. Time saved 😎

pacx solution getDefault

In complex scenarios, when I have multiple solutions in place, it happens to forget which solution is set as default for the current environment. That's why I created the second command, pacx solution getDefault. It simply returns the default solution set for the current environment, if any.

pacx solution getDefault

pacx solution create

The code-first approach to solution management is great but... what if you just need to create a temporary solution (e.g. to work with Ribbon Workbench) that you don't want to save locally or on the repo?

I often found myself in the situation where the solution where already there, and I needed to segregate specific components in a separate one. pacx solution create creates a new solution directly on the current environment, without saving anything locally.

If you want, you can later clone that solution using pac solution clone and keep it updated via pac solution sync.

pacx solution create has the same behavior of pac solution init: creates the solution and also the publisher if needed.

The minimum required info for the command is the (display) name of the solution to create, and one of publisherUniqueName or publisherPrefix (you can specify both, at least 1 is required).

pacx solution create --name master --publisherUniqueName greg
pacx solution create -n master -pun greg

pacx solution create --name master --publisherPrefix greg
pacx solution create -n master -pp greg
Enter fullscreen mode Exit fullscreen mode

The following conventions apply:

  • if the uniqueName argument is not specified, it's reduced from the name argument considering only letters, numbers or underscores, all in lowercase.
  • solution version is set to 1.0.0.0 by default
  • solution is (of course) unmanaged
  • about the publisher
    • if publisherUniqueName is specified, the tool tries to find a publisher with that unique name in the environment. If found, it is used as publisher for the solution.
    • if publisherUniqueName is not specified, but publisherPrefix is provided, the tool tries to find a publisher with that prefix in the environment. If found, it is used as publisher for the solution.

If no publisher has been found, a new publisher is created, with the following defaults:

  • uniquename:
    • uses publisherUniqueName if provided, otherwise
    • uses publisherFriendlyName if provided (considering only letters, numbers and underscores), otherwise
    • uses publisherPrefix
  • friendlyname:
    • uses publisherFriendlyName if provided, otherwise
    • uses publisherUniqueName if provided, otherwise
    • uses publisherPrefix
  • customizationprefix:
    • uses publisherPrefix if provided, otherwise
    • uses publisherUniqueName if provided, considering only letters or numbers. If the length of the generated string is <= 5 chars, takes the whole string, otherwise extracts the first 3 chars. Otherwise...
    • uses publisherFriendlyName, considering only letters or numbers. If the length of the generated string is <= 5 chars, takes the whole string, otherwise extracts the first 3 chars.
  • customizationoptionvalueprefix:
    • uses publisherOptionSetPrefix argument if provided, otherwise sets it to 10000

Personally, now I use it a lot. I changed the approach described in the beginning of the current article this way:

  1. use pacx solution create to create my solution on the dataverse environment, also creating the publisher if needed
  2. set that solution to default via pacx solution setDefault
  3. start the data model manipulations via pacx table, pacx column and pacx rel commands
  4. when ready, clone the solution locally via pac solution clone
  5. do all the other stuff via pacx or make.powerapps.com
  6. sync the changes locally via pac solution sync
  7. when ready, commit everything on my Azure DevOps repo

I find this approach more lean and direct, and allows me to focus on content right at step #2 instead of step #6 as before.

pacx solution delete

I added this command because I'm lazy. PAC CLI already contains a command to delete a solution from a given environment, but I kept forgetting it and writing

pacx solution delete ...
Enter fullscreen mode Exit fullscreen mode

instead of

pac solution delete ...
Enter fullscreen mode Exit fullscreen mode

Thus... I created an alias command, that does basically the same thing.

pacx solution getPublisherList

This is quite easy, it just prints the list of publishers already available in the current environment

pacx solution getPublisherList


In the next articles we'll deep dive on table management commands.

Top comments (0)