Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
282 commits
Select commit Hold shift + click to select a range
4d27e6d
feat: `Turtle.get_Symbol` ( Fixes #19 )
Jul 23, 2025
0c7ece8
feat: `Turtle.get_Symbol` ( Fixes #19 )
Jul 23, 2025
caa1909
feat: `Turtle.L()` ( Fixes #20 )
Jul 23, 2025
8f23851
feat: `Turtle.L()` ( Fixes #20 )
Jul 23, 2025
3768ff4
feat: `Turtle.SierpinskiTriangle()` ( Fixes #21 )
Jul 23, 2025
c8ed7d6
feat: `Turtle.SierpinskiTriangle()` ( Fixes #21 )
Jul 23, 2025
c9b7834
feat: Turtle module scaffolding ( Fixes #1 )
Jul 23, 2025
c2ed332
feat: Turtle method chaining ( Fixes #22 )
Jul 24, 2025
edea6ef
feat: Turtle method chaining ( Fixes #22 )
Jul 24, 2025
a689c70
feat: `Turtle.HilbertCurve()` ( Fixes #23 )
Jul 24, 2025
66c8634
feat: `Turtle.HilbertCurve()` ( Fixes #23 )
Jul 24, 2025
d6a8b1b
feat: `Turtle` default display ( Fixes #24 )
Jul 24, 2025
1b59ef7
feat: `Turtle` default display ( Fixes #24 )
Jul 24, 2025
330c5df
feat: `Turtle` default display ( Fixes #24 )
Jul 24, 2025
6049cb4
fix: Fixing Turtle method chaining ( Fixes #22 )
Jul 24, 2025
e0f7b70
fix: Fixing Turtle method chaining ( Fixes #22 )
Jul 24, 2025
d3a4e32
fix: `Turtle.get_Points`
Jul 24, 2025
ffa9a95
fix: `Turtle.get_Points`
Jul 24, 2025
e012ff3
feat: Turtle tests ( Fixes #25 )
Jul 24, 2025
e7ec9ea
feat: `Turtle.get/set_PatternAnimation ( Fixes #26 )
Jul 24, 2025
7d5e502
feat: `Turtle.get/set_PatternAnimation ( Fixes #26 )
Jul 24, 2025
e9e0a48
feat: `Turtle.get/set_PatternTransform` ( Fixes #27 )
Jul 24, 2025
36f107a
feat: `Turtle.get/set_PatternTransform` ( Fixes #27 )
Jul 24, 2025
8bef1f2
feat: `Turtle.get_Pattern` transform and animation updates ( Fixes #2…
Jul 24, 2025
b400de9
feat: `Turtle.get_Pattern` transform and animation updates ( Fixes #2…
Jul 24, 2025
1d44475
fix: Fixing Turtle StrokeWidth ( Fixes #16 )
Jul 24, 2025
8970257
fix: Fixing Turtle StrokeWidth ( Fixes #16 )
Jul 24, 2025
579899e
feat: `Turtle.Polygon()` ( Fixes #29 )
Jul 24, 2025
1b52bf8
Merge branch 'new-turtle' of https://github.com/PowerShellWeb/Turtle …
Jul 24, 2025
388b17d
feat: `Turtle.get/set_ViewBox` ( Fixes #30 )
Jul 24, 2025
47ffb6b
feat: `Turtle.get/set_ViewBox` ( Fixes #30 )
Jul 24, 2025
c9bc960
feat: `Turtle.KochCurve` ( Fixes #28 )
Jul 24, 2025
568570f
feat: `Turtle.KochCurve` ( Fixes #28 )
Jul 24, 2025
73013a1
feat: `Turtle.KochCurve` ( Fixes #28 )
Jul 24, 2025
3740c06
feat: `Turtle.ViewBox` ( Fixes #30 )
Jul 24, 2025
17ab67d
feat: `Turtle.ViewBox` ( Fixes #30 )
Jul 24, 2025
fb9dea4
feat: `Turtle.get_PathElement` ( Fixes #32 )
Jul 24, 2025
caeabd1
feat: `Turtle.get_PathElement` ( Fixes #32 )
Jul 24, 2025
d74cf2d
feat: `Turtle.get_PathElement` ( Fixes #32 )
Jul 24, 2025
7894bca
feat: `Turtle.get_Mask/PatternMask` ( Fixes #33, Fixes #34 )
Jul 24, 2025
4e071f1
feat: `Turtle.get_Mask/PatternMask` ( Fixes #33, Fixes #34 )
Jul 24, 2025
92cd4a7
feat: `Turtle.TwinDragonCurve` ( Fixes #35 )
Jul 24, 2025
b30e336
feat: `Turtle.TwinDragonCurve` ( Fixes #35 )
Jul 24, 2025
a49eb70
feat: `Turtle.TwinDragonCurve` ( Fixes #35 )
Jul 24, 2025
3d6c430
fix: Explicitly clearing position ( Fixes #30 )
Jul 24, 2025
0487a54
fix: Explicitly clearing position ( Fixes #30 )
Jul 24, 2025
aa156ce
fix: Explicitly clearing position ( Fixes #30 )
Jul 24, 2025
9187d69
feat: `Turtle.TerDragonCurve` ( Fixes #36 )
Jul 24, 2025
15d9161
feat: `Turtle.TerDragonCurve` ( Fixes #36 )
Jul 24, 2025
d99e697
feat: `Turtle.TerDragonCurve` ( Fixes #36 )
Jul 24, 2025
768689c
feat: `Turtle.TerDragonCurve` ( Fixes #36 )
Jul 24, 2025
cc3e08e
feat: `Turtle.BoxFractal` ( Fixes #37 )
Jul 24, 2025
c5b9bb1
feat: `Turtle.BoxFractal` ( Fixes #37 )
Jul 24, 2025
638ad76
feat: `Turtle.KochSnowflake` ( Fixes #38 )
Jul 24, 2025
153cda7
feat: `Turtle.KochSnowflake` ( Fixes #38 )
Jul 24, 2025
36bb4d6
feat: `Turtle.SierpinskiCurve` ( Fixes #39 )
Jul 25, 2025
4c8a55e
feat: `Turtle.SierpinskiCurve` ( Fixes #39 )
Jul 25, 2025
5652186
feat: `Turtle.SierpinskiArrowheadCurve` ( Fixes #40 )
Jul 25, 2025
0cc63de
feat: `Turtle.SierpinskiArrowheadCurve` ( Fixes #40 )
Jul 25, 2025
77d9f24
feat: `Turtle.SierpinskiSquareCurve` ( Fixes #41 )
Jul 25, 2025
2f32dc8
feat: `Turtle.SierpinskiSquareCurve` ( Fixes #41 )
Jul 25, 2025
6143abd
feat: `Turtle.get_AnimateMotion` ( Fixes #42 )
Jul 25, 2025
8ac0356
feat: `Turtle.get_AnimateMotion` ( Fixes #42 )
Jul 25, 2025
26217ec
feat: `Turtle.get/set_AnimateMotionDuration` ( Fixes #43 )
Jul 25, 2025
08bd950
feat: `Turtle.get/set_AnimateMotionDuration` ( Fixes #43 )
Jul 25, 2025
d4e9e7d
feat: New-Turtle ( Fixes #44 )
Jul 26, 2025
ff2c055
feat: `Turtle.get/set_IsPenUp` ( Fixes #45 )
Jul 26, 2025
3194cad
feat: `Turtle.get/set_IsPenUp` ( Fixes #45 )
Jul 26, 2025
032ea26
feat: `Turtle.PenUp/PenDown()` ( Fixes #46 )
Jul 26, 2025
840bf9c
feat: `Turtle.PenUp/PenDown()` ( Fixes #46 )
Jul 26, 2025
45eaa2f
feat: `Turtle.PenUp/PenDown()` ( Fixes #46 )
Jul 26, 2025
67170c2
feat: `Turtle.PenUp/PenDown()` ( Fixes #46 )
Jul 26, 2025
38591a3
feat: `Turtle.Left/Right()` ( Fixes #47 )
Jul 26, 2025
e5e9ebe
feat: `Turtle.Left/Right()` ( Fixes #47 )
Jul 26, 2025
2f00b1a
fix: Renaming `.L` to `.LSystem`, so `.L` can mean `.Left` ( Fixes #2…
Jul 26, 2025
5100100
fix: Renaming `.L` to `.LSystem`, so `.L` can mean `.Left` ( Fixes #2…
Jul 26, 2025
9fffe73
feat: Improving Turtle.Heading performance ( Fixes #4 )
Jul 26, 2025
2b8f77f
fix: `Turtle.get_Stroke` defaulting to currentColor ( Fixes #15 )
Jul 26, 2025
6e60f45
fix: Turtle coordinate properties ( Fixes #48 )
Jul 26, 2025
ad17a11
fix: Turtle coordinate properties ( Fixes #48 )
Jul 26, 2025
846c088
feat: `Turtle.Jump()` ( Fixes #50 )
Jul 27, 2025
d1c5bc8
feat: `Turtle.Jump()` ( Fixes #50 )
Jul 27, 2025
e2ab331
feat: `Turtle.Jump()` ( Fixes #50 )
Jul 27, 2025
bd43773
feat: `Move-Turtle` ( Fixes #51 )
Jul 27, 2025
bba0bc4
feat: `Save-Turtle` ( Fixes #52 )
Jul 28, 2025
19d6b6d
feat: `Turtle.KochIsland()` ( Fixes #49 )
Jul 28, 2025
c5c687e
feat: `Turtle.KochIsland()` ( Fixes #49 )
Jul 28, 2025
b5d6706
feat: `Turtle.get/set_Fill` ( Fixes #54 )
Jul 28, 2025
2c93459
feat: `Turtle.get/set_Fill` ( Fixes #54 )
Jul 28, 2025
c07ecda
feat: `Turtle.get/set_Fill` ( Fixes #54 )
Jul 28, 2025
e9cb9fd
feat: `Turtle.PenColor()` ( Fixes #56 )
Jul 28, 2025
16e5b9b
feat: `Turtle.PenColor()` ( Fixes #56 )
Jul 28, 2025
d136f6f
feat: `Turtle.FillColor()` ( Fixes #55 )
Jul 28, 2025
69590fe
feat: `Turtle.FillColor()` ( Fixes #55 )
Jul 28, 2025
cef0f8d
feat: `Turtle.get/set_PathAttribute` ( Fixes #57 )
Jul 28, 2025
fe80d7d
feat: `Turtle.get/set_PathAttribute` ( Fixes #57 )
Jul 28, 2025
3b9faba
fix: `Turtle.BoxFractal` ( Fixes #37 )
Jul 28, 2025
76aa1f4
fix: `Turtle.BoxFractal` ( Fixes #37 )
Jul 28, 2025
7c96234
feat: `Turtle.get_Canvas` ( Fixes #58 )
Jul 28, 2025
ac01ae7
feat: `Turtle.get_Canvas` ( Fixes #58 )
Jul 28, 2025
391b350
feat: `Turtle.get_PNG` ( Fixes #59 )
Jul 28, 2025
133dec2
feat: `Turtle.get_PNG` ( Fixes #59 )
Jul 28, 2025
08c1d0f
feat: `Turtle.get_JPEG` ( Fixes #60 )
Jul 28, 2025
198c5e9
feat: `Turtle.get_JPEG` ( Fixes #60 )
Jul 28, 2025
64de3b2
feat: `Turtle.get_WEBP` ( Fixes #61 )
Jul 28, 2025
33d70d1
feat: `Turtle.get_WEBP` ( Fixes #61 )
Jul 28, 2025
f1edeff
test: Adding rasterization test
StartAutomating Jul 28, 2025
e87a52f
test: Adding rasterization test
StartAutomating Jul 28, 2025
57fbf75
feat: `Turtle.Circle()` ( Fixes #53 )
Jul 28, 2025
6927e37
feat: `Turtle.Circle()` ( Fixes #53 )
Jul 28, 2025
c2598e9
feat: `Turtle.get_ClipPath` ( Fixes #62 )
Jul 28, 2025
667530c
feat: `Turtle.get_ClipPath` ( Fixes #62 )
Jul 28, 2025
786b491
feat: `Turtle.get_OffsetPath` ( Fixes #63 )
Jul 28, 2025
6d2d556
feat: `Turtle.get_OffsetPath` ( Fixes #63 )
Jul 28, 2025
67f7c13
feat: `Turtle.Star` ( Fixes #64 )
Jul 28, 2025
6271b60
feat: `Turtle.Star` ( Fixes #64 )
Jul 28, 2025
7062f2e
feat: `Set-Turtle` ( Fixes #65 )
Jul 28, 2025
d2ef538
feat: Turtle Action ( Fixes #66 )
Jul 28, 2025
9e5a5f5
test: Testing GitHub Action ( re #66 )
Jul 28, 2025
e7988b3
test: Testing GitHub Action ( re #66 )
Jul 28, 2025
abd01bd
test: Testing GitHub Action ( re #66 )
Jul 28, 2025
d8ebabc
test: Testing GitHub Action ( re #66 )
Jul 28, 2025
935775a
feat: Turtle Action ( Fixes #66 )
Jul 28, 2025
cd87869
feat: Turtle Action ( Fixes #66 )
Jul 28, 2025
c8048d1
feat: Turtle Action ( Fixes #66 )
Jul 28, 2025
cad534c
docs: Adding New-Turtle example ( Fixes #44 )
Jul 28, 2025
5750d2b
feat: `Turtle.Flower()` ( Fixes #67 )
Jul 28, 2025
45a8ba2
feat: `Turtle.Flower()` ( Fixes #67 )
Jul 28, 2025
7a2165a
docs: `Turtle.get_Symbol` ( Fixes #19 )
Jul 28, 2025
652fb44
docs: `Turtle.get_Symbol` ( Fixes #19 )
Jul 28, 2025
ab0f197
docs: `Turtle.get_Symbol` ( Fixes #19 )
Jul 28, 2025
b912154
docs: `Turtle.get_Symbol` ( Fixes #19 )
Jul 28, 2025
7cfebb9
docs: `Turtle.get_Steps` ( Fixes #8 )
Jul 28, 2025
c20f9f7
docs: `Turtle.get_Steps` ( Fixes #8 )
Jul 28, 2025
b286771
docs: `Turtle.LSystem` docs ( Fixes #20 )
Jul 28, 2025
6fab35c
docs: `Turtle.LSystem` docs ( Fixes #20 )
Jul 28, 2025
4f2c0a4
feat: `Turtle.PeanoCurve()` ( Fixes #68 )
Jul 28, 2025
8808f3b
feat: `Turtle.PeanoCurve()` ( Fixes #68 )
Jul 28, 2025
9f2e882
feat: `Turtle.PeanoCurve()` ( Fixes #68 )
Jul 28, 2025
dc244f5
feat: `Turtle.GosperCurve()` ( Fixes #69 )
Jul 28, 2025
3ecd893
feat: `Turtle.GosperCurve()` ( Fixes #69 )
Jul 28, 2025
9199f59
docs: BoxFractal.turtle.ps1 example ( re #66 )
Jul 28, 2025
327ac01
docs: BoxFractal.turtle.ps1 example ( re #66 )
Jul 28, 2025
f13cd88
docs: BoxFractal.turtle.ps1 example ( re #66 )
Jul 28, 2025
2ca26a9
docs: BoxFractal.turtle.ps1 example ( re #66 )
Jul 28, 2025
4294506
docs: BoxFractal.turtle.ps1 example ( re #66 )
Jul 28, 2025
eecd96a
docs: BoxFractal.turtle.ps1 example ( re #66 )
Jul 28, 2025
ecac70f
feat: `Save-Turtle` ( Fixes #52 )
Jul 28, 2025
111b0c3
docs: Turtle CODE_OF_CONDUCT.md ( Fixes #70 )
Jul 28, 2025
6a86873
docs: Turtle CONTRIBUTING.md ( Fixes #71 )
Jul 28, 2025
c6ee38c
docs: Turtle SECURITY.md ( Fixes #72 )
Jul 28, 2025
c13fb47
docs: Turtle FUNDING.yml ( Fixes #73 )
Jul 28, 2025
b7a1f6d
docs: CODE_OF_CONDUCT/SECURITY ( Fixes #72, Fixes #70 )
Jul 28, 2025
a21c103
docs: `Set-Turtle` ( Fixes #65 )
Jul 28, 2025
f8449dd
feat: `Turtle.Goto()` ( Fixes #74 )
Jul 28, 2025
b71ef0f
feat: `Turtle.Goto()` ( Fixes #74 )
Jul 28, 2025
cec445f
docs: Documenting Turtle.set_Steps ( Fixes #8 )
Jul 28, 2025
2c2a856
docs: Documenting Turtle.set_Steps ( Fixes #8 )
Jul 28, 2025
92ec325
docs: Documenting Turtle.set_Steps ( Fixes #8 )
Jul 28, 2025
efa14c4
feat: `Turtle.Backward()` ( Fixes #75 )
Jul 28, 2025
659f0d2
feat: `Turtle.Backward()` ( Fixes #75 )
Jul 28, 2025
8ae52fd
feat: `Turtle.Teleport()` ( Fixes #76 )
StartAutomating Jul 28, 2025
e3a6070
feat: `Turtle.Teleport()` ( Fixes #76 )
Jul 28, 2025
07d8d42
feat: Aliasing LineTo to GoTo and MoveTo to Teleport ( Fixes #74, Fix…
Jul 28, 2025
e83c558
feat: Aliasing LineTo to GoTo and MoveTo to Teleport ( Fixes #74, Fix…
Jul 28, 2025
75d2d53
feat: Get-Turtle ( Fixes #77 )
Jul 28, 2025
7ef2fd1
feat: `Turtle.get/set_BackgroundColor` ( Fixes #78 )
Jul 29, 2025
5563616
feat: `Turtle.get/set_BackgroundColor` ( Fixes #78 )
Jul 29, 2025
d293713
feat: `Turtle.get_DataURL` ( Fixes #79 )
Jul 29, 2025
1cb4ed7
feat: `Turtle.get_DataURL` ( Fixes #79 )
Jul 29, 2025
89a9d17
feat: `Turtle.get_PatternDataURL` ( Fixes #80 )
Jul 29, 2025
3da03b6
feat: `Turtle.get_PatternDataURL` ( Fixes #80 )
Jul 29, 2025
61506f4
docs: Endless Sierpinski animation
Jul 29, 2025
8a0f7f2
docs: Endless Sierpinski animation
Jul 29, 2025
ccb9151
docs: Adding README
Jul 29, 2025
330b895
docs: Adding README.md
Jul 29, 2025
6dcc911
docs: Updating README.md
Jul 29, 2025
0a49a41
docs: Updating README.md
Jul 29, 2025
ce8d44f
docs: Updating README.md
Jul 29, 2025
94b1789
docs: Updating README.md
Jul 29, 2025
5e76690
fix: `Turtle.get_Stroke` defaulting to currentcolor ( Fixes #15 )
Jul 29, 2025
507e636
fix: `Turtle.get_Stroke` defaulting to currentcolor ( Fixes #15 )
Jul 29, 2025
8c07c05
fix: `Turtle.get_Stroke` defaulting to currentcolor ( Fixes #15 )
Jul 29, 2025
628d0ad
fix: `Turtle.get_StrokeWidth` defaulting to 1% ( Fixes #16 )
Jul 29, 2025
f17736f
fix: `Turtle.get_StrokeWidth` defaulting to 1% ( Fixes #16 )
Jul 29, 2025
46e59fa
fix: `Turtle.get_StrokeWidth` defaulting to 1% ( Fixes #16 )
Jul 29, 2025
29eb175
fix: `Turtle.get_StrokeWidth` defaulting to 1% ( Fixes #16 )
Jul 29, 2025
9a43bf6
fix: `Turtle.get_StrokeWidth` defaulting to 1% ( Fixes #16 )
Jul 29, 2025
30f9709
fix: `Turtle.get_StrokeWidth` defaulting to 1% ( Fixes #16 )
Jul 29, 2025
dffc918
fix: `Turtle.get_StrokeWidth` defaulting to 1% ( Fixes #16 )
Jul 29, 2025
a8665f0
fix: `Turtle.get_StrokeWidth` defaulting to 1% ( Fixes #16 )
Jul 29, 2025
70b9dbd
docs: Updating README.md
Jul 29, 2025
ef03615
fix: `Turtle.get_StrokeWidth` defaulting to .5% ( Fixes #16 )
Jul 29, 2025
73be32a
fix: `Turtle.get_StrokeWidth` defaulting to .5% ( Fixes #16 )
Jul 29, 2025
e5aea47
fix: `Turtle.get_StrokeWidth` defaulting to .5% ( Fixes #16 )
Jul 29, 2025
f0ce513
fix: `Turtle.get_StrokeWidth` defaulting to .5% ( Fixes #16 )
Jul 29, 2025
a733124
fix: `Turtle.get_StrokeWidth` defaulting to .5% ( Fixes #16 )
Jul 29, 2025
c16bfd7
fix: `Turtle.get_StrokeWidth` defaulting to .5% ( Fixes #16 )
Jul 29, 2025
90b02ef
fix: `Turtle.get_StrokeWidth` defaulting to .5% ( Fixes #16 )
Jul 29, 2025
0bd318c
fix: `Turtle.get_StrokeWidth` defaulting to .5% ( Fixes #16 )
Jul 29, 2025
ea4aa76
docs: Updating README.md
Jul 29, 2025
24c05ad
fix: `Turtle.get_StrokeWidth` defaulting to .25% ( Fixes #16 )
Jul 29, 2025
8bd26ee
fix: `Turtle.get_StrokeWidth` defaulting to .25% ( Fixes #16 )
Jul 29, 2025
e611e11
fix: `Turtle.get_StrokeWidth` defaulting to .25% ( Fixes #16 )
Jul 29, 2025
02edd51
fix: `Turtle.get_StrokeWidth` defaulting to .25% ( Fixes #16 )
Jul 29, 2025
9a1d5d4
fix: `Turtle.get_StrokeWidth` defaulting to .25% ( Fixes #16 )
Jul 29, 2025
4a52066
fix: `Turtle.get_StrokeWidth` defaulting to .25% ( Fixes #16 )
Jul 29, 2025
bee25f1
fix: `Turtle.get_StrokeWidth` defaulting to .25% ( Fixes #16 )
Jul 29, 2025
466679f
docs: Updating README.md
Jul 29, 2025
b8d571b
docs: Updating README.md
Jul 29, 2025
999dbf8
docs: Updating README.md
Jul 29, 2025
38ad8ef
docs: Updating README.md
Jul 29, 2025
f85b881
docs: Updating README.md
Jul 29, 2025
5e31e8d
docs: Updating README.md
Jul 29, 2025
0ee1a65
docs: Updating README.md
Jul 29, 2025
7b980ef
docs: Updating README.md
Jul 29, 2025
9d6f5bc
docs: Improving EndlessSierpinski example
StartAutomating Jul 29, 2025
e350f1d
docs: Improving EndlessSierpinski example
Jul 29, 2025
fdd4c27
docs: Adding EndlessBoxFractal example
StartAutomating Jul 29, 2025
a3ac4bb
docs: Adding EndlessBoxFractal example
Jul 29, 2025
d647660
docs: Adding EndlessHilbert example
StartAutomating Jul 29, 2025
01f0d40
docs: Adding EndlessHilbert example
StartAutomating Jul 29, 2025
e0fa7be
docs: Adding EndlessHilbert example
Jul 29, 2025
9ea1ab9
docs: Adding EndlessSnowflake example
StartAutomating Jul 29, 2025
96e7dea
docs: Adding EndlessSnowflake example
Jul 29, 2025
330543a
docs: README.md.ps1
Jul 29, 2025
7c85711
docs: README.md.ps1
Jul 29, 2025
b601fb9
feat: `Turtle.MooreCurve()` ( Fixes #81 )
StartAutomating Jul 29, 2025
6bfc188
feat: `Turtle.MooreCurve()` ( Fixes #81 )
Jul 29, 2025
c39d5bc
feat: `Turtle.MooreCurve()` ( Fixes #81 )
StartAutomating Jul 29, 2025
96d083f
feat: `Turtle.MooreCurve()` ( Fixes #81 )
Jul 29, 2025
3092f76
docs: Describing L Systems in Turtle
StartAutomating Jul 29, 2025
5a7f4f6
docs: Improving README
StartAutomating Jul 29, 2025
1fa5abf
docs: Adding more examples to README
StartAutomating Jul 29, 2025
6c650fe
docs: Documenting GitHub Action
StartAutomating Jul 29, 2025
db9fff7
fix: `Turtle.set_PathAttribute` concurrency fix ( Fixes #57 )
StartAutomating Jul 29, 2025
3a39a7b
fix: `Turtle.set_PathAttribute` concurrency fix ( Fixes #57 )
Jul 29, 2025
d87020d
fix: `Turtle.set_PatternAnimation` ease of use ( Fixes #26 )
StartAutomating Jul 29, 2025
49b46c9
fix: `Turtle.set_PatternAnimation` ease of use ( Fixes #26 )
StartAutomating Jul 29, 2025
368c561
fix: `Turtle.set_PatternAnimation` ease of use ( Fixes #26 )
Jul 29, 2025
ce32521
docs: Updating EndlessSnowflake to use dictionary animations
StartAutomating Jul 29, 2025
50784f1
docs: Updating EndlessSnowflake to use dictionary animations
Jul 29, 2025
af48e65
docs: Updating README
StartAutomating Jul 29, 2025
d7e0f67
docs: Updating README
StartAutomating Jul 29, 2025
55fb151
docs: Updating README
StartAutomating Jul 29, 2025
701f15d
docs: Updating README
StartAutomating Jul 29, 2025
704a2b4
release: Updating Module Manifest
StartAutomating Jul 29, 2025
694a1f4
feat: `Turtle.get/set_PathClass` ( Fixes #82 )
StartAutomating Jul 29, 2025
c3275d3
feat: `Turtle.get/set_PathClass` ( Fixes #82 )
Jul 29, 2025
87d511e
chore: Adding CNAME
StartAutomating Jul 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: [StartAutomating]
502 changes: 502 additions & 0 deletions .github/workflows/BuildTurtle.yml

Large diffs are not rendered by default.

351 changes: 351 additions & 0 deletions Build/GitHub/Actions/TurtleAction.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,351 @@
<#
.Synopsis
GitHub Action for Turtle
.Description
GitHub Action for Turtle. This will:

* Import Turtle
* If `-Run` is provided, run that script
* Otherwise, unless `-SkipScriptFile` is passed, run all *.Turtle.ps1 files beneath the workflow directory
* If any `-ActionScript` was provided, run scripts from the action path that match a wildcard pattern.

If you will be making changes using the GitHubAPI, you should provide a -GitHubToken
If none is provided, and ENV:GITHUB_TOKEN is set, this will be used instead.
Any files changed can be outputted by the script, and those changes can be checked back into the repo.
Make sure to use the "persistCredentials" option with checkout.
#>

param(
# A PowerShell Script that uses Turtle.
# Any files outputted from the script will be added to the repository.
# If those files have a .Message attached to them, they will be committed with that message.
[string]
$Run,

# If set, will not process any files named *.Turtle.ps1
[switch]
$SkipScriptFile,

# A list of modules to be installed from the PowerShell gallery before scripts run.
[string[]]
$InstallModule,

# If provided, will commit any remaining changes made to the workspace with this commit message.
[string]
$CommitMessage,

# If provided, will checkout a new branch before making the changes.
# If not provided, will use the current branch.
[string]
$TargetBranch,

# The name of one or more scripts to run, from this action's path.
[string[]]
$ActionScript,

# The github token to use for requests.
[string]
$GitHubToken = '{{ secrets.GITHUB_TOKEN }}',

# The user email associated with a git commit. If this is not provided, it will be set to the [email protected].
[string]
$UserEmail,

# The user name associated with a git commit.
[string]
$UserName,

# If set, will not push any changes made to the repository.
# (they will still be committed unless `-NoCommit` is passed)
[switch]
$NoPush,

# If set, will not commit any changes made to the repository.
# (this also implies `-NoPush`)
[switch]
$NoCommit
)

$ErrorActionPreference = 'continue'
"::group::Parameters" | Out-Host
[PSCustomObject]$PSBoundParameters | Format-List | Out-Host
"::endgroup::" | Out-Host

$gitHubEventJson = [IO.File]::ReadAllText($env:GITHUB_EVENT_PATH)
$gitHubEvent =
if ($env:GITHUB_EVENT_PATH) {
$gitHubEventJson | ConvertFrom-Json
} else { $null }
"::group::Parameters" | Out-Host
$gitHubEvent | Format-List | Out-Host
"::endgroup::" | Out-Host


$anyFilesChanged = $false
$ActionModuleName = 'Turtle'
$actorInfo = $null


$checkDetached = git symbolic-ref -q HEAD
if ($LASTEXITCODE) {
"::warning::On detached head, skipping action" | Out-Host
exit 0
}

function InstallActionModule {
param([string]$ModuleToInstall)
$moduleInWorkspace = Get-ChildItem -Path $env:GITHUB_WORKSPACE -Recurse -File |
Where-Object Name -eq "$($moduleToInstall).psd1" |
Where-Object {
$(Get-Content $_.FullName -Raw) -match 'ModuleVersion'
}
if (-not $moduleInWorkspace) {
$availableModules = Get-Module -ListAvailable
if ($availableModules.Name -notcontains $moduleToInstall) {
Install-Module $moduleToInstall -Scope CurrentUser -Force -AcceptLicense -AllowClobber
}
Import-Module $moduleToInstall -Force -PassThru | Out-Host
} else {
Import-Module $moduleInWorkspace.FullName -Force -PassThru | Out-Host
}
}
function ImportActionModule {
#region -InstallModule
if ($InstallModule) {
"::group::Installing Modules" | Out-Host
foreach ($moduleToInstall in $InstallModule) {
InstallActionModule -ModuleToInstall $moduleToInstall
}
"::endgroup::" | Out-Host
}
#endregion -InstallModule

if ($env:GITHUB_ACTION_PATH) {
$LocalModulePath = Join-Path $env:GITHUB_ACTION_PATH "$ActionModuleName.psd1"
if (Test-path $LocalModulePath) {
Import-Module $LocalModulePath -Force -PassThru | Out-String
} else {
throw "Module '$ActionModuleName' not found"
}
} elseif (-not (Get-Module $ActionModuleName)) {
throw "Module '$ActionModuleName' not found"
}

"::notice title=ModuleLoaded::$ActionModuleName Loaded from Path - $($LocalModulePath)" | Out-Host
if ($env:GITHUB_STEP_SUMMARY) {
"# $($ActionModuleName)" |
Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
}
}
function InitializeAction {
#region Custom
#endregion Custom

# Configure git based on the $env:GITHUB_ACTOR
if (-not $UserName) { $UserName = $env:GITHUB_ACTOR }
if (-not $actorID) { $actorID = $env:GITHUB_ACTOR_ID }
$actorInfo =
if ($GitHubToken -notmatch '^\{{2}' -and $GitHubToken -notmatch '\}{2}$') {
Invoke-RestMethod -Uri "https://api.github.com/user/$actorID" -Headers @{ Authorization = "token $GitHubToken" }
} else {
Invoke-RestMethod -Uri "https://api.github.com/user/$actorID"
}

if (-not $UserEmail) { $UserEmail = "[email protected]" }
git config --global user.email $UserEmail
git config --global user.name $actorInfo.name

# Pull down any changes
git pull | Out-Host

if ($TargetBranch) {
"::notice title=Expanding target branch string $targetBranch" | Out-Host
$TargetBranch = $ExecutionContext.SessionState.InvokeCommand.ExpandString($TargetBranch)
"::notice title=Checking out target branch::$targetBranch" | Out-Host
git checkout -b $TargetBranch | Out-Host
git pull | Out-Host
}
}

function InvokeActionModule {
$myScriptStart = [DateTime]::Now
$myScript = $ExecutionContext.SessionState.PSVariable.Get("Run").Value
if ($myScript) {
Invoke-Expression -Command $myScript |
. ProcessOutput |
Out-Host
return
}
$myScriptTook = [Datetime]::Now - $myScriptStart
$MyScriptFilesStart = [DateTime]::Now

$myScriptList = @()
$shouldSkip = $ExecutionContext.SessionState.PSVariable.Get("SkipScriptFile").Value
if ($shouldSkip) {
return
}
$scriptFiles = @(
Get-ChildItem -Recurse -Path $env:GITHUB_WORKSPACE |
Where-Object Name -Match "\.$($ActionModuleName)\.ps1$"
if ($ActionScript) {
if ($ActionScript -match '^\s{0,}/' -and $ActionScript -match '/\s{0,}$') {
$ActionScriptPattern = $ActionScript.Trim('/').Trim() -as [regex]
if ($ActionScriptPattern) {
$ActionScriptPattern = [regex]::new($ActionScript.Trim('/').Trim(), 'IgnoreCase,IgnorePatternWhitespace', [timespan]::FromSeconds(0.5))
Get-ChildItem -Recurse -Path $env:GITHUB_ACTION_PATH |
Where-Object { $_.Name -Match "\.$($ActionModuleName)\.ps1$" -and $_.FullName -match $ActionScriptPattern }
}
} else {
Get-ChildItem -Recurse -Path $env:GITHUB_ACTION_PATH |
Where-Object Name -Match "\.$($ActionModuleName)\.ps1$" |
Where-Object FullName -Like $ActionScript
}
}
) | Select-Object -Unique
$scriptFiles |
ForEach-Object -Begin {
if ($env:GITHUB_STEP_SUMMARY) {
"## $ActionModuleName Scripts" |
Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
}
} -Process {
$myScriptList += $_.FullName.Replace($env:GITHUB_WORKSPACE, '').TrimStart('/')
$myScriptCount++
$scriptFile = $_
if ($env:GITHUB_STEP_SUMMARY) {
"### $($scriptFile.Fullname -replace [Regex]::Escape($env:GITHUB_WORKSPACE))" |
Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
}
$scriptCmd = $ExecutionContext.SessionState.InvokeCommand.GetCommand($scriptFile.FullName, 'ExternalScript')
foreach ($requiredModule in $CommandInfo.ScriptBlock.Ast.ScriptRequirements.RequiredModules) {
if ($requiredModule.Name -and
(-not $requiredModule.MaximumVersion) -and
(-not $requiredModule.RequiredVersion)
) {
InstallActionModule $requiredModule.Name
}
}
Push-Location $scriptFile.Directory.Fullname
$scriptFileOutputs = . $scriptCmd
$scriptFileOutputs |
. ProcessOutput |
Out-Host
Pop-Location
}

$MyScriptFilesTook = [Datetime]::Now - $MyScriptFilesStart
$SummaryOfMyScripts = "$myScriptCount $ActionModuleName scripts took $($MyScriptFilesTook.TotalSeconds) seconds"
$SummaryOfMyScripts |
Out-Host
if ($env:GITHUB_STEP_SUMMARY) {
$SummaryOfMyScripts |
Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
}
#region Custom
#endregion Custom
}

function OutError {
$anyRuntimeExceptions = $false
foreach ($err in $error) {
$errParts = @(
"::error "
@(
if ($err.InvocationInfo.ScriptName) {
"file=$($err.InvocationInfo.ScriptName)"
}
if ($err.InvocationInfo.ScriptLineNumber -ge 1) {
"line=$($err.InvocationInfo.ScriptLineNumber)"
if ($err.InvocationInfo.OffsetInLine -ge 1) {
"col=$($err.InvocationInfo.OffsetInLine)"
}
}
if ($err.CategoryInfo.Activity) {
"title=$($err.CategoryInfo.Activity)"
}
) -join ','
"::"
$err.Exception.Message
if ($err.CategoryInfo.Category -eq 'OperationStopped' -and
$err.CategoryInfo.Reason -eq 'RuntimeException') {
$anyRuntimeExceptions = $true
}
) -join ''
$errParts | Out-Host
if ($anyRuntimeExceptions) {
exit 1
}
}
}

function PushActionOutput {
if ($anyFilesChanged) {
"::notice::$($anyFilesChanged) Files Changed" | Out-Host
}
if ($CommitMessage -or $anyFilesChanged) {
if ($CommitMessage) {
Get-ChildItem $env:GITHUB_WORKSPACE -Recurse |
ForEach-Object {
$gitStatusOutput = git status $_.Fullname -s
if ($gitStatusOutput) {
git add $_.Fullname
}
}

git commit -m $ExecutionContext.SessionState.InvokeCommand.ExpandString($CommitMessage)
}

$checkDetached = git symbolic-ref -q HEAD
if (-not $LASTEXITCODE -and -not $NoPush -and -not $noCommit) {
if ($TargetBranch -and $anyFilesChanged) {
"::notice::Pushing Changes to $targetBranch" | Out-Host
git push --set-upstream origin $TargetBranch
} elseif ($anyFilesChanged) {
"::notice::Pushing Changes" | Out-Host
git push
}
"Git Push Output: $($gitPushed | Out-String)"
} else {
"::notice::Not pushing changes (on detached head)" | Out-Host
$LASTEXITCODE = 0
exit 0
}
}
}

filter ProcessOutput {
$out = $_
$outItem = Get-Item -Path $out -ErrorAction Ignore
if (-not $outItem -and $out -is [string]) {
$out | Out-Host
if ($env:GITHUB_STEP_SUMMARY) {
"> $out" | Out-File -Append -FilePath $env:GITHUB_STEP_SUMMARY
}
return
}
$fullName, $shouldCommit =
if ($out -is [IO.FileInfo]) {
$out.FullName, (git status $out.Fullname -s)
} elseif ($outItem) {
$outItem.FullName, (git status $outItem.Fullname -s)
}
if ($shouldCommit -and -not $NoCommit) {
"$fullName has changed, and should be committed" | Out-Host
git add $fullName
if ($out.Message) {
git commit -m "$($out.Message)" | Out-Host
} elseif ($out.CommitMessage) {
git commit -m "$($out.CommitMessage)" | Out-Host
} elseif ($gitHubEvent.head_commit.message) {
git commit -m "$($gitHubEvent.head_commit.message)" | Out-Host
}
$anyFilesChanged = $true
}
$out
}

. ImportActionModule
. InitializeAction
. InvokeActionModule
. PushActionOutput
. OutError
18 changes: 18 additions & 0 deletions Build/GitHub/Jobs/BuildTurtle.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@{
"runs-on" = "ubuntu-latest"
if = '${{ success() }}'
steps = @(
@{
name = 'Check out repository'
uses = 'actions/checkout@main'
},
'RunEZOut' # ,
@{
name = 'Run Turtle (on branch)'
if = '${{github.ref_name != ''main''}}'
uses = './'
id = 'TurtleAction'
}
# 'BuildAndPublishContainer'
)
}
10 changes: 10 additions & 0 deletions Build/GitHub/Steps/PublishTestResults.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@{
name = 'PublishTestResults'
uses = 'actions/upload-artifact@main'
with = @{
name = 'PesterResults'
path = '**.TestResults.xml'
}
if = '${{always()}}'
}

10 changes: 10 additions & 0 deletions Build/Turtle.GitHubAction.PSDevOps.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#requires -Module PSDevOps
Import-BuildStep -SourcePath (
Join-Path $PSScriptRoot 'GitHub'
) -BuildSystem GitHubAction

$PSScriptRoot | Split-Path | Push-Location

New-GitHubAction -Name "TurtlePower" -Description 'Turtles in a PowerShell' -Action TurtleAction -Icon chevron-right -OutputPath .\action.yml

Pop-Location
Loading
Loading