10 Commits

Author SHA1 Message Date
5efae02594 Fix argument 2023-04-12 04:08:26 +02:00
1eed4ed198 Update workflow 2023-04-12 03:58:47 +02:00
922765c7eb Merge branch 'relative-path' 2023-04-12 03:55:11 +02:00
9a449b01fa Installer: add to start 2023-04-12 03:46:46 +02:00
bfcab5f46d Save relative path in python files 2023-03-30 04:25:48 +02:00
0c2174525e Fix FileNotFound not catched 2023-03-30 02:54:53 +02:00
2a6c42829f Fix installer build script 2023-03-30 02:11:42 +02:00
8b719bc3f9 Update Windows installer scripts 2023-03-30 02:02:45 +02:00
118425f994 Add example git hook 2023-03-30 01:28:51 +02:00
53712f76ce Added HEADLESS loglevel 2023-03-28 22:52:25 +02:00
11 changed files with 119 additions and 45 deletions

View File

@@ -19,14 +19,9 @@ jobs:
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3
with: with:
name: dyn2py.exe name: dyn2py.exe
- name: Update version number - name: Build
run: | run: |
$regex = Select-String -Path pyproject.toml -Pattern '^version = "((?:\d\.){2}\d)"$' .\dyn2py-installer.ps1
$version = $regex.Matches.Groups[1].Value
(Get-Content dyn2py-installer.iss).Replace("x.x.x",$version) | Set-Content dyn2py-installer.iss
- name: Build installer
run: |
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" -Qp $(Join-Path $PWD.Path dyn2py-installer.iss)
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v3
name: Upload artifact name: Upload artifact
with: with:

View File

@@ -5,6 +5,7 @@ on:
branches: ["main"] branches: ["main"]
pull_request: pull_request:
branches: ["main"] branches: ["main"]
workflow_dispatch:
permissions: permissions:
contents: read contents: read

View File

@@ -53,7 +53,7 @@ options:
-h, --help show this help message and exit -h, --help show this help message and exit
-v, --version show program's version number and exit -v, --version show program's version number and exit
-l LOGLEVEL, --loglevel LOGLEVEL -l LOGLEVEL, --loglevel LOGLEVEL
set log level, possible options: CRITICAL, ERROR, WARNING, INFO, DEBUG set log level, possible options: HEADLESS, CRITICAL, ERROR, WARNING, INFO, DEBUG
-n, --dry-run do not modify files, only show log -n, --dry-run do not modify files, only show log
-F, --force overwrite even if the files are older -F, --force overwrite even if the files are older
-b, --backup create a backup for updated files -b, --backup create a backup for updated files
@@ -68,36 +68,37 @@ dynamo options, only for processing Dynamo graphs:
The script by default overwrites older files with newer files. The script by default overwrites older files with newer files.
Do not move the source Dynamo graphs, or update won't work with them later. Do not move the source Dynamo graphs, or update won't work with them later.
Multiple sources are supported, separate them by spaces. Multiple sources are supported, separate them by spaces.
HEADLESS loglevel only prints modified filenames.
``` ```
#### Examples #### Examples
*Notes: In Windows cmd use backward slashes as path separators, in any other shells use forward slashes. Powershell accepts both of them. Wrap paths with spaces in double quotes.* *Notes: In Windows cmd use backward slashes as path separators, in any other shells use forward slashes. Powershell accepts both of them. Wrap paths with spaces in double quotes.*
Extract all nodes next to a Dynamo file: ```shell
# Extract all nodes next to a Dynamo file:
```
dyn2py path/to/dynamofile.dyn dyn2py path/to/dynamofile.dyn
```
Update a Dynamo file from previously exported and modified python files: # Update a Dynamo file from previously exported and modified python files:
```
dyn2py --update path/to/dynamofile.dyn dyn2py --update path/to/dynamofile.dyn
```
Extract python nodes to a specific folder, process multiple Dynamo files: # Extract python nodes to a specific folder, process multiple Dynamo files:
```
dyn2py --python-folder path/to/pythonfiles path/to/dynamofile1.dyn path/to/dynamofile2.dyn dyn2py --python-folder path/to/pythonfiles path/to/dynamofile1.dyn path/to/dynamofile2.dyn
```
Update Dynamo files from python files from a folder. Only check python files, create backups: # Update Dynamo files from python files from a folder. Only check python files, create backups:
```
dyn2py --filter py --backup path/to/pythonfiles dyn2py --filter py --backup path/to/pythonfiles
``` ```
#### Git hooks
Git Hooks are a built-in feature of Git that allow developers to automate tasks throughout the Git workflow. Read more here: https://githooks.com/
With the `pre-commit` hook it's possible to add more files to the currently initialized commit.
You can find an example pre-commit hook here: [pre-commit](pre-commit). Copy this file to the `.git/hooks` folder of your repo of Dynamo graph. This folder is hidden by default, but it should exist in all initialized git repo. Do not rename this file.
This script will go through staged `.dyn` files and export python scripts from them, and add them to the current commit. Now you can check check changed lines in a diff tool!
### As a python module ### As a python module
Full API documentation available here: https://infeeeee.github.io/dyn2py Full API documentation available here: https://infeeeee.github.io/dyn2py
@@ -180,17 +181,9 @@ pyinstaller dyn2py.spec
### Create installer for Windows ### Create installer for Windows
- Install Inno Setup: https://jrsoftware.org/isdl.php - Install Inno Setup: https://jrsoftware.org/isdl.php
- The already built exe should be in the root folder - Build an exe
- Run this in powershell: - Run `dyn2py-installer.ps1` in powershell
```powershell
# Read version number from pyproject.toml and update in innosetup:
$regex = Select-String -Path pyproject.toml -Pattern '^version = "((?:\d\.){2}\d)"$'
$version = $regex.Matches.Groups[1].Value
(Get-Content dyn2py-installer.iss).Replace("x.x.x",$version) | Set-Content dyn2py-installer.iss
# Build:
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" -Qp $(Join-Path $PWD.Path dyn2py-installer.iss)
```
### Live module documentation ### Live module documentation
``` ```

View File

@@ -22,7 +22,7 @@
- [x] API docs - [x] API docs
- [x] Installation in readme - [x] Installation in readme
- [x] Terminal examples in readme - [x] Terminal examples in readme
- [ ] About git hooks in readme - [x] About git hooks in readme
## Extra features maybe later ## Extra features maybe later

View File

@@ -7,7 +7,8 @@ AppPublisherURL=https://github.com/infeeeee/dyn2py
AppSupportURL=https://github.com/infeeeee/dyn2py/issues AppSupportURL=https://github.com/infeeeee/dyn2py/issues
AppUpdatesURL=https://github.com/infeeeee/dyn2py/releases/latest AppUpdatesURL=https://github.com/infeeeee/dyn2py/releases/latest
DefaultDirName={autopf}\dyn2py DefaultDirName={autopf}\dyn2py
DisableProgramGroupPage=yes DisableProgramGroupPage=auto
DefaultGroupName=dyn2py
LicenseFile=LICENSE LicenseFile=LICENSE
PrivilegesRequired=admin PrivilegesRequired=admin
OutputBaseFilename=dyn2py-installer OutputBaseFilename=dyn2py-installer
@@ -22,6 +23,9 @@ Name: "english"; MessagesFile: "compiler:Default.isl"
[Files] [Files]
Source: "dyn2py.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "dyn2py.exe"; DestDir: "{app}"; Flags: ignoreversion
[Icons]
Name: "{group}\dyn2py (cmd)"; Filename: "{cmd}"; WorkingDir: "{userdocs}"; Parameters: "/k dyn2py"
Name: "{group}\dyn2py (powershell)"; Filename: "powershell"; WorkingDir: "{userdocs}"; Parameters: "-noexit -command dyn2py"
[Code] [Code]
const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'; const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';

24
dyn2py-installer.ps1 Normal file
View File

@@ -0,0 +1,24 @@
$InnoSetupPath = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
# Check if innosetup installed
if (-not (Test-Path -Path $InnoSetupPath -PathType Leaf)) {
throw "Innosetup not found!"
}
# Copy dyn2py.exe from default folder:
if (Test-Path -Path ".\dist\dyn2py.exe" -PathType Leaf) {
Copy-Item ".\dist\dyn2py.exe" -Destination "." -Force
}
# Check if dyn2py.exe exists at all
if (-not(Test-Path -Path "dyn2py.exe" -PathType Leaf)) {
throw "dyn2py.exe not found!"
}
# Read version number from pyproject.toml and update in innosetup:
$regex = Select-String -Path pyproject.toml -Pattern '^version = "((?:\d\.){2}\d)"$'
$version = $regex.Matches.Groups[1].Value
(Get-Content dyn2py-installer.iss).Replace("x.x.x", $version) | Set-Content dyn2py-installer.iss
# Build:
& $InnoSetupPath -Qp $(Join-Path $PWD.Path dyn2py-installer.iss)

View File

@@ -45,6 +45,7 @@ def __command_line() -> None:
The script by default overwrites older files with newer files. The script by default overwrites older files with newer files.
Do not move the source Dynamo graphs, or update won't work with them later. Do not move the source Dynamo graphs, or update won't work with them later.
Multiple sources are supported, separate them by spaces. Multiple sources are supported, separate them by spaces.
HEADLESS loglevel only prints modified filenames.
""") """)
) )
@@ -117,8 +118,13 @@ def run(options: Options) -> None:
from_command_line = bool(inspect.stack()[1].function == "__command_line") from_command_line = bool(inspect.stack()[1].function == "__command_line")
# Set up logging: # Set up logging:
if options.loglevel == "HEADLESS":
loglevel = "CRITICAL"
else:
loglevel = options.loglevel
logging.basicConfig(format='%(levelname)s: %(message)s', logging.basicConfig(format='%(levelname)s: %(message)s',
level=options.loglevel) level=loglevel)
logging.debug(f"Run options: {vars(options)}") logging.debug(f"Run options: {vars(options)}")
# Set up sources: # Set up sources:
@@ -193,8 +199,14 @@ def run(options: Options) -> None:
elif f.is_python_file(): elif f.is_python_file():
logging.debug("Source is a Python file") logging.debug("Source is a Python file")
f.update_dynamo(options) try:
f.update_dynamo(options)
except FileNotFoundError:
logging.error(f"Source Dynamo file not found! {f.filepath}")
# Write files at the end: # Write files at the end:
for f in DynamoFile.open_files | PythonFile.open_files: for f in DynamoFile.open_files | PythonFile.open_files:
f.write(options) try:
f.write(options)
except FileNotFoundError:
logging.error(f"Cannot save file! {f.filepath}")

View File

@@ -120,6 +120,7 @@ class File():
Raises: Raises:
TypeError: If called on a File object TypeError: If called on a File object
FileNotFoundError: Target folder does not exist
""" """
if not options: if not options:
@@ -136,18 +137,24 @@ class File():
# Create backup: # Create backup:
if not options.dry_run and self.filepath.exists() and options.backup: if not options.dry_run and self.filepath.exists() and options.backup:
backup_filename = sanitize_filename( backup_filename = sanitize_filename(
f"{self.basename}_{self.mtimeiso}{self.extension}") filename=f"{self.basename}_{self.mtimeiso}{self.extension}")
backup_path = self.dirpath.joinpath(backup_filename) backup_path = self.dirpath.joinpath(backup_filename)
logging.info(f"Creating backup to {backup_path}") logging.info(f"Creating backup to {backup_path}")
self.filepath.rename(backup_path) self.filepath.rename(backup_path)
if options.loglevel == "HEADLESS":
print(backup_path)
# Call filetype specific methods: # Call filetype specific methods:
if options.dry_run: if options.dry_run:
logging.info( logging.info(
f"Should write file, but it's a dry-run: {self.filepath}") f"Should write file, but it's a dry-run: {self.filepath}")
else: else:
if not self.dirpath.exists():
raise FileNotFoundError("File dir does not exist!")
logging.info(f"Writing file: {self.filepath}") logging.info(f"Writing file: {self.filepath}")
self._write_file() self._write_file()
if options.loglevel == "HEADLESS":
print(self.filepath)
def _write_file(self): def _write_file(self):
"""Should be implemented in subclasses """Should be implemented in subclasses
@@ -403,10 +410,10 @@ class PythonFile(File):
"Do not edit this section, if you want to update the Dynamo graph!" "Do not edit this section, if you want to update the Dynamo graph!"
]) ])
# Double escape path: # Calculate relative path, change to forward slash
dyn_path_string = str(dynamo_file.realpath) dyn_path_string = os.path.relpath(dynamo_file.filepath, self.dirpath)
if "\\" in dyn_path_string: if "\\" in dyn_path_string:
dyn_path_string = dyn_path_string.replace("\\", "\\\\") dyn_path_string = dyn_path_string.replace("\\", "/")
self.header_data = { self.header_data = {
"dyn2py_version": METADATA["Version"], "dyn2py_version": METADATA["Version"],
@@ -541,8 +548,16 @@ class PythonFile(File):
# Open if it's the first time: # Open if it's the first time:
if not dynamo_file: if not dynamo_file:
dynamo_file = DynamoFile( cwd = pathlib.Path(os.getcwd()).resolve()
pathlib.Path(self.header_data["dyn_path"])) # Change to pythonfiles' dir:
os.chdir(self.dirpath)
dynpath = os.path.realpath(self.header_data["dyn_path"])
logging.debug(f"Resolved path: {dynpath}")
# Change back to the original path:
os.chdir(cwd)
dynamo_file = DynamoFile(pathlib.Path(dynpath))
# Check if uuid is ok: # Check if uuid is ok:
if not dynamo_file.uuid == self.header_data["dyn_uuid"]: if not dynamo_file.uuid == self.header_data["dyn_uuid"]:

View File

@@ -3,7 +3,7 @@ import argparse
import pathlib import pathlib
LOGLEVELS = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"] LOGLEVELS = ["HEADLESS", "CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"]
DEFAULT_LOGLEVEL = "INFO" DEFAULT_LOGLEVEL = "INFO"
FILTERS = ["py", "dyn"] FILTERS = ["py", "dyn"]

27
pre-commit Normal file
View File

@@ -0,0 +1,27 @@
#!/bin/sh
# Create a list of files from staged files:
mapfile -t NEW_FILES <<<$(git diff --name-only --cached)
# Go through staged files:
for f in "${NEW_FILES[@]}"; do
# Export python files, only from Dynamo files.
# On Windows line ending is always CRLF, so remove CR with tr.
mapfile -t PY_FILES <<<$(dyn2py --force --filter dyn --loglevel HEADLESS "$f" | tr -d "\r")
# Check if something was exported:
if [[ "${PY_FILES[@]}" ]]; then
# Go through exported files:
for p in "${PY_FILES[@]}"; do
# Check if file exists:
if [ -f "$p" ]; then
# Stage file:
git add "$p"
fi
done
fi
done

View File

@@ -34,3 +34,6 @@ dyn2py = "dyn2py:__command_line"
[build-system] [build-system]
requires = ["setuptools", "wheel"] requires = ["setuptools", "wheel"]
[tool.setuptools]
packages = ["dyn2py"]