moonsharp-devs/moonsharp

Sync Unity code files Powershell script version

admalledd opened this issue · 4 comments

Some people asked for maybe a more windows-friendly version of the sync projects script. Couldn't hash out a .bat version off hand quickly, but this should work on any currently supported windows OS (powershell 4.0+)

As a PATCH because work is still figuring out how this whole "github" thing works. Got OK to continue publishing as PATCH for now though even though it is un-fun for all of us.

From f7c4fc68923e2cde1c89fc45073a1a2d31665c6f
Author: Eric Driggers <EricDriggers@toppanmerrill.com>
Subject: [PATCH] powershell version of sync_unity_projects.ps1


---
diff --git a/src/sync_unity_projects.ps1 b/src/sync_unity_projects.ps1
--- /dev/null
+++ b/src/sync_unity_projects.ps1
#Quick and dirty port of `rsync_unity_projects.sh` to powershell
# Thus keep some/most of the semantics of that instead of more native posh style/formatting
# means updates/sync is easier if the other script changes.

# `echo`, `rm`, `mkdir` are all powershell aliases (ish) or wrappers built in to modern posh hosts
#  For this I am assuming "reasonably" up to date powershell of 4+, since win7/win8 usage is so low or no longer supported.
#  They do require better quoting though on spacing.

$BASE_DIR="$PSScriptRoot"

# -- DO NOT CHANGE ORDER OTHERWISE WE RISK COPY OVERS...

echo "Cleaning..."
echo "... Unity4"
rm -R $BASE_DIR/Unity/MoonSharp/Assets/Tests
rm -R $BASE_DIR/Unity/MoonSharp/Assets/Plugins/MoonSharp/Interpreter
rm -R $BASE_DIR/Unity/MoonSharp/Assets/Plugins/MoonSharp/Debugger
mkdir $BASE_DIR/Unity/MoonSharp/Assets/Tests
mkdir $BASE_DIR/Unity/MoonSharp/Assets/Plugins/MoonSharp/Interpreter
mkdir $BASE_DIR/Unity/MoonSharp/Assets/Plugins/MoonSharp/Debugger


echo "Copying files..."


#NB: the biggest diff from shell, no rsync so we use posh-native Copy-Item stuff.
# Reminder that order of files/copies is important for reasons.
function betterCopy ($RootPath, $DestPath) {
    #Ignore generated files under `obj/`, per old rsync only .cs files were copied so simplifies the search
    $srcFiles = get-childitem -Recurse -Path $RootPath -Include "*.cs" | ? {$_.FullName -notmatch "\\obj\\"}
    #powershell's copy-item does NOT like doing a destination file-tree without effort.
    #  So instead use a pipeline object and convert/mask the destination output path param.
    #  KB: https://devblogs.microsoft.com/scripting/learn-about-using-powershell-value-binding-by-property-name/
    #  KB: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/copy-item
    $srcFiles | % {
        $copyOper = [pscustomobject]@{ Path=$_.FullName; Destination=$($_.FullName.Replace($RootPath,$DestPath))}
        $null = New-Item -Path  $copyOper.Destination -Type File -Force #Forces file tree creation at least.
        $copyOper | Copy-Item -Force
    }
}


echo "... Unity - interpreter"
betterCopy "$BASE_DIR\MoonSharp.Interpreter" "$BASE_DIR\Unity\MoonSharp\Assets\Plugins\MoonSharp\Interpreter"

echo "... Unity - vscode debugger..."
betterCopy "$BASE_DIR\MoonSharp.VsCodeDebugger" "$BASE_DIR\Unity\MoonSharp\Assets\Plugins\MoonSharp\Debugger"

echo "... Unity - unit tests..."
betterCopy "$BASE_DIR\MoonSharp.Interpreter.Tests" "$BASE_DIR\Unity\MoonSharp\Assets\Tests"

Hey @admalledd, I modified some of the functionality and added a check for OS because the -match function in your code wasn't cross-platform compatible. The top $objPath = is a ternary on the OS, and later I modded the shorthand to standard, just because it's a best practice style, I also removed some repetition of the file paths.

#Quick and dirty port of `rsync_unity_projects.sh` to powershell
# Thus keep some/most of the semantics of that instead of more native posh style/formatting
# means updates/sync is easier if the other script changes.

# `rm`, `mkdir` are all powershell aliases (ish) or wrappers built in to modern posh hosts
#  For this I am assuming "reasonably" up to date powershell of 4+, since win7/win8 usage is so low or no longer supported.
#  They do require better quoting though on spacing.

$BASE_DIR="$PSScriptRoot"

$objPath = @{ $true = "/obj/"; $false = "\\obj\\" }[ $IsMacOs -or $IsLinux ]

# -- DO NOT CHANGE ORDER OTHERWISE WE RISK COPY OVERS...

Write-Output "Cleaning..."
Write-Output "... Unity4"
$Paths = @(
    "$BASE_DIR/Unity/MoonSharp/Assets/Tests",
    "$BASE_DIR/Unity/MoonSharp/Assets/Plugins/MoonSharp/Interpreter",
    "$BASE_DIR/Unity/MoonSharp/Assets/Plugins/MoonSharp/Debugger"
)

$Paths | ForEach-Object { rm -R $_ }
$Paths | ForEach-Object { mkdir $_ }

Write-Output "Copying files..."
#NB: the biggest diff from shell, no rsync so we use posh-native Copy-Item stuff.
# Reminder that order of files/copies is important for reasons.
function betterCopy ($RootPath, $DestPath) {
    #Ignore generated files under `obj/`, per old rsync only .cs files were copied so simplifies the search
    $srcFiles = get-childitem -Recurse -Path $RootPath -Include "*.cs" | Where-Object {$_.FullName -notmatch $objPath}
    #powershell's copy-item does NOT like doing a destination file-tree without effort.
    #  So instead use a pipeline object and convert/mask the destination output path param.
    #  KB: https://devblogs.microsoft.com/scripting/learn-about-using-powershell-value-binding-by-property-name/
    #  KB: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/copy-item
    $srcFiles | ForEach-Object {
        $copyOper = [pscustomobject]@{ Path=$_.FullName; Destination=$($_.FullName.Replace($RootPath,$DestPath))}
        $null = New-Item -Path  $copyOper.Destination -Type File -Force #Forces file tree creation at least.
        $copyOper | Copy-Item -Force
    }
}


Write-Output "... Unity - interpreter"
betterCopy "$BASE_DIR\MoonSharp.Interpreter" "$BASE_DIR/Unity/MoonSharp/Assets/Tests"
Write-Output "... Unity - vscode debugger..."
betterCopy "$BASE_DIR\MoonSharp.VsCodeDebugger" "$BASE_DIR/Unity/MoonSharp/Assets/Plugins/MoonSharp/Interpreter"
Write-Output "... Unity - unit tests..."
betterCopy "$BASE_DIR\MoonSharp.Interpreter.Tests" "$BASE_DIR/Unity/MoonSharp/Assets/Plugins/MoonSharp/Debugger"

Also noted that the current repo version here:

Never considered cross-platform support things so of course I missed those things. Ran it through our Linter though for a different revision. Like I said, first thingy was hacky quick port because someone mentioned/asked.

You messed up the target folders on your last few lines. Also, if the obj-directory-filter bit can be simplified by noting that -match (and friends like the case insensitive inverse -inotmatch) is regex and "just put both in" as a regex OR obj(\\|/). I will continue to consider any platform that does not use \ or / as the directory char to be wrong and unreasonable to support.

Since paths are blarg, and you moved them into an array, might as go fully and do an array of From/To pairs. Purged most of the "trying to keep similar to the bash version" comments since we certainly departed far enough that if some one is poking this we should require they know what powershell is and test this instead of hoping they can infer.

Let me know how this works on non windows powershell? We rarely use powershell cross platform here (preferring python for xplat, or more specifically *nix and win scripts here don't mix if at all possible) and so our linter/helper stuff is near useless, let alone that I have zero systems to test on.

#Powershell version of `rsync_unity_projects.sh`

$BASE_DIR="$PSScriptRoot"

$Paths = @(
    @{From=([IO.Path]::Combine($BASE_DIR,"MoonSharp.Interpreter.Tests")) ;To=([IO.Path]::Combine($BASE_DIR,"Unity","MoonSharp","Assets","Tests"))},
    @{From=([IO.Path]::Combine($BASE_DIR,"MoonSharp.VsCodeDebugger")) ;To=([IO.Path]::Combine($BASE_DIR,"Unity","MoonSharp","Assets","Plugins","MoonSharp","Debugger"))},
    @{From=([IO.Path]::Combine($BASE_DIR,"MoonSharp.Interpreter")) ;To=([IO.Path]::Combine($BASE_DIR,"Unity","MoonSharp","Assets","Plugins","MoonSharp","Interpreter"))}
)
Write-Output "Cleaning..."
Write-Output "... Unity4"

$Paths | ForEach-Object { rm -R $_.To -ErrorAction Continue}
$Paths | ForEach-Object { mkdir $_.To -ErrorAction Continue}

Write-Output "Copying files..."
#NB: the biggest diff from shell, no rsync so we use posh-native Copy-Item stuff.
# Reminder that order of files/copies is important for reasons.
function betterCopy ($Operation) {
    $RootPath = $Operation.From
    $DestPath = $Operation.To
    #Ignore generated files under `obj/`, per old rsync only .cs files were copied so simplifies the search
    $srcFiles = get-childitem -Recurse -Path $RootPath -Include "*.cs" | Where-Object {$_.FullName -inotmatch "obj(\\|/)"}
    #powershell's copy-item does NOT like doing a destination file-tree without effort.
    #  So instead use a pipeline object and convert/mask the destination output path param.
    #  KB: https://devblogs.microsoft.com/scripting/learn-about-using-powershell-value-binding-by-property-name/
    #  KB: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/copy-item
    $srcFiles | ForEach-Object {
        $copyOper = [pscustomobject]@{ Path=$_.FullName; Destination=$($_.FullName.Replace($RootPath,$DestPath))}
        $null = New-Item -Path  $copyOper.Destination -Type File -Force #Forces file tree creation at least.
        $copyOper | Copy-Item -Force
    }
}

#Note reverses order of deletes

Write-Output "... Unity - interpreter"
betterCopy $Paths[2]
Write-Output "... Unity - vscode debugger..."
betterCopy $Paths[1]
Write-Output "... Unity - unit tests..."
betterCopy $Paths[0]

Hah, sorry about the folders on the last three lines; I had actually been using the array and was toying with the idea of from/to pairs but shrugged it off and pasted and replaced the $paths access by index back with the filename in the comment field here, obviously reversing them! Woops.

This looks good, the simplification of the regex is much better than the ternary solution I pasted - I like them because they are fun to write, but you are correct in that they are not simple and they possibly are super-hard to read.

Ran this just fine from my side, I'll drop a pull request as soon as I'm able (probably tomorrow)

Its not that I don't like the ternary, its more that it checked for OS stuffs, but then elsewhere (in the whole paths setups) we were using / and thus mixing. Powershell can/should handle it fine (clearly did on my machine at least) but better to tell it "here, YOU figure it out". Also I tend to love regex more than is probably healthy.

The "Readability" note is more on that we have certainly gone fully to the powershell dark side ^(we have cookies) and we might as well go fully (and thus the [IO.Path]::Combine() stuff) if we are saying "sure, maybe this is usable on non windows too, but then if you want to edit this to add/tweak new paths you probably should know what powershell is a bit"