[GSoC 2024] - Command-Line Preferences Manipulation

When you “import FreeCAD” from Python, all the additional module paths are automatically added. But that might not be what you want… Can you explain better what you want to achieve?

FYI you can launch FreeCAD with a “-P myscript.py” parameters to execute a python script. You could try to hack on that

Harshita_Saraswat do you have a git repo where we can have a look at your progresses?

Hello Everyone.
Here is the git repo.
Current progress:
Done:

  1. preference management function mapping
  2. CRUD logic
  3. Command Design Pattern
  4. Basic Test

Next:

  1. Commandline interface using argparse lib
  2. Documentation
  3. Tests

Some key points:
Instead of going with the XML parser route(as I mentioned in the proposal) we used the FreeCAD’s already built-in system for that.
This was because writing a new XML parser would not only would have been time consuming but also would had to be maintained if any changes was to be made to the preferences were managed in future. Using builtin functions ensures the maintainability and compatibility.
But this also introduced a new issue as the for this we had to add freecad lib to the sys.path for FreeCAD to be imported which is different for all of us.
So for this we decided to create a runner python script which runs the cli.py file using

FreeCADCmd cli.py arg1 arg2...

Intention was that FreeCADCmd command itself will remain same across systems and will automatically import FreeCAD without any issue.
you can check out the runner script in main.py

Hello Everyone.
I have finally completed the interface and it can be tested now by cloning the repository.

I have made slight changes in the way the runner calls cli.py.
Previously it just called the

freecadcmd cli.py arg1, arg2...

Issues with this:

  1. freecad was taking options for the cli.py as its own.
    This made passing of arguments and option to the cli.py difficult and buggy.
    solution: I made a file called share. the runner.py writes the arguments to this file then while execution of cli.py, it reads the file to extract arguments and run them.
  2. I also made runner.py and the interface.py use a common Argparse Interface so that the runner.py behaves as it is the main Parser but it just takes the arguments and exposes the interface that is actually used is cli.py

Have a look at the above mentioned files. What Do you think about this approach?

Currently I am working on packaging and running into some errors that I am unable to understand and resolve. I am using pyproject.toml with setup utils.
My goal is to add a script that is globally accessible by the user how installs the package. On Windows, the script is simple not recognised and on Linux(Ubuntu 24.04) the script is recognised but produces package not found error even though pip list shows that the package is installed.
Can someone with packaging experience drop some pointers or guide me through it?

my pyproject.toml file

Hi Harshita_Saraswat,

For me it seems to work. I did the following things:

First, I make sure that FreeCAD is installed on Windows.
Then, I install Python through the Windows App store. I then run the following commands while being in the root directory of your project (in PowerShell):

pip install build
python -m build
cd dist
pip install freecad_preference_manager...

It turns out that freecad-preference-manager is not available, so I first try to install it in a virtual environment:

python -m venv venv

It turns out I cannot activate the virtual environment because Windows doesn’t allow me to run scripts. To solve this I run PowerShell as administrator and execute the following command:

Set-ExecutionPolicy RemoteSigned

With this, I can activate the virtual environment with:

./venv/Scripts/Activate

I can then install the package:

pip install freecad_preference_manager....whl

This installs correctly and gives me freecad-preference-manager.exe as being available. While executing, it turns out that FreeCAD is not available, so I get this error:

Neither of the following commands are available: FreeCADCmd, freecadcmd

After adding C:\Program Files\FreeCAD 0.21\bin to the Path environment variable, freecad-preference-manager works correctly.

Ok, but this is in a virtual environment. To run it outside of the virtual environment I need to place the following directory in the Path environment variable as well:

C:\Users\Pieter\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n...\LocalCache\local-packages\Python312\Scripts

After that the command preference-manager-freecad is available in general, without a virtual environment and it works correctly.

Project Update: Commandline Preference Management

Hello everyone,

Over the past few weeks, I’ve been working on various enhancements and addressing the issues raised by pieterhijma on GitHub. Here’s a detailed overview of the changes and improvements:

Previous State

  1. Non-Hierarchical Argument Parsing:
  • Arguments were not structured hierarchically, leading to confusion. For example, the -v parameter was allowed for the read command but assigning a value to it didn’t make sense.
  • Issue discussed: Hierarchical argument parsing #3
  1. Directory Creation as Side Effect:
  • When trying to read a specific parameter, a new folder was being created as a side effect instead of retrieving the parameter value.
  • Issue discussed: Directory creation as side effect #2
  1. Argument Completion:
  • There was no support for argument completion, making it difficult to use the CLI efficiently.
  • Issue discussed: Argument completion #4

Current State

  1. Hierarchical Argument Parsing:
  • The -n parameter for specifying the name has been removed. Now, the parameter name is provided along with the group path, separated by a colon (:). For example, BaseApp/Preferences/PythonConsole:PythonBlockCursor.
  • Added a new command called list that operates on parameter groups.
  • Reference: Hierarchical argument parsing #3
  1. Improved Parameter Reading:
  • The new approach allows reading specific parameters without unintended side effects. Now you can directly read a parameter value using the colon-separated format.
  • For example: freecad-preference-manager read BaseApp/Preferences/PythonConsole:ProfilerInterval will correctly retrieve the value.
  • Reference: Directory creation as side effect #2
  1. Argument Completion:
  1. Trie Data Structure for Parsing:
  • Introduced a Trie data structure for efficient parameter group parsing and optimized suggestions.
  1. Updated Documentation:
  • The README has been updated to reflect these changes and provide clear instructions on the new command formats and functionalities.

Additional Changes

One of the most significant updates is the ability to run the tool without using the CLI and executor. I’ve figured out a way to add the FreeCAD library to the sys.path regardless of the operating system. This has been tested on both Windows and Linux systems so far.

Here is a short demo that follows the readme example and shows how autosuggestion is working.

Hello everyone. As the GSOC coding period ends, here is my final work submission blog for the project.
https://harshitasaraswat.github.io/GSOC-2024-Work-Submission-Blog/