initial push with clean and rebuild commands

This commit is contained in:
2020-07-19 20:42:58 -04:00
commit df25294055
10 changed files with 519 additions and 0 deletions

92
ForlornOutcast.uproject Normal file
View File

@@ -0,0 +1,92 @@
{
"FileVersion": 3,
"EngineAssociation": "4.25",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "ForlornOutcast",
"Type": "Runtime",
"LoadingPhase": "Default",
"AdditionalDependencies": [
"Engine",
"CoreUObject",
"UFSM",
"FlockingBehaviourSystem",
"NavigationSystem",
"AIModule"
]
},
{
"Name": "ForlornOutcastEditor",
"Type": "Editor",
"LoadingPhase": "PostEngineInit"
}
],
"Plugins": [
{
"Name": "ChaosNiagara",
"Enabled": true
},
{
"Name": "NiagaraExtras",
"Enabled": true
},
{
"Name": "Niagara",
"Enabled": true
},
{
"Name": "ApexDestruction",
"Enabled": true
},
{
"Name": "UFSM",
"Enabled": true,
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/195d90d8cedf4b478a92036c059e2374"
},
{
"Name": "FlockingBehaviourSystem",
"Enabled": true,
"MarketplaceURL": "https://www.unrealengine.com/marketplace/en-US/slug/flocking-behaviour-system-ideal-for-simulation-of-birds-fish-bees-and-more"
},
{
"Name": "SteamVR",
"Enabled": false,
"SupportedTargetPlatforms": [
"Win32",
"Win64",
"Linux",
"Mac"
]
},
{
"Name": "SaveExtension",
"Enabled": true,
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/91084f43b68047ac8da6fc88a7467936"
},
{
"Name": "RiderLink",
"Enabled": false
},
{
"Name": "BlockoutToolsPlugin",
"Enabled": true,
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/d337b97aca8947a893526964e179acfd"
},
{
"Name": "NodeGraphAssistant",
"Enabled": true,
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/d9baaaeadeaf41dcb52b3f6e134e9514"
},
{
"Name": "OculusVR",
"Enabled": false,
"SupportedTargetPlatforms": [
"Win32",
"Win64",
"Android"
]
}
]
}

50
engine/compile.go Normal file
View File

@@ -0,0 +1,50 @@
package engine
import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"golang.org/x/sys/windows/registry"
)
func findUnrealVersionPath(version string) (string, error) {
//Attempting to build project files programattically
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\EpicGames\Unreal Engine\`+version, registry.QUERY_VALUE)
if err != nil {
return "", err
}
defer k.Close()
s, _, err := k.GetStringValue("InstalledDirectory") //Pulling the (Default) value which has the path
if err != nil {
return "", err
}
return s, nil
}
func buildProject(version string, projectABSPath string) error {
unrealVersionPath, err := findUnrealVersionPath(version)
if err != nil {
fmt.Printf("Unable to find the path to Unreal Engine version %s, please build project files manually: %s ", version, err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
unrealVersionPath = unrealVersionPath + string(filepath.Separator) + "Engine" + string(filepath.Separator) + "Build" + string(filepath.Separator) + "BatchFiles" + string(filepath.Separator) + "Build.bat"
checkPath(unrealVersionPath) // Verifying path, will exit if fail
fmt.Println("Using Unreal Engine Path: ", unrealVersionPath)
// Manually building up the commmand
buildArgs := []string{"Development", "Win64", "-Project=" + projectABSPath, "-TargetType=Editor", "-Progress", "-NoEngineChanges", "-NoHotReloadFromIDE"}
buildFilesCMD := exec.Command(unrealVersionPath, buildArgs...)
// Making sure we write the output of the command to the command prompt
out := io.Writer(os.Stdout)
buildFilesCMD.Stdout = out
// finally running the command
err = buildFilesCMD.Run()
if err != nil {
return err
}
return nil
}

98
engine/engine.go Normal file
View File

@@ -0,0 +1,98 @@
package engine
import (
"bufio"
"fmt"
"os"
"path/filepath"
)
var version = "4.25" //Need to manually set the UEVersion, don't know how to guess this
// RebuildProject is the main function to clean up the project, generate files and build
func RebuildProject(riderEnabled bool, doBuild bool) {
_, err := os.Getwd()
if err != nil {
fmt.Println("Unable to get working dir, returned error: ", err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
projectFile, err := os.Stat("ForlornOutcast.uproject")
if err != nil {
if os.IsNotExist(err) {
fmt.Println("unable to locate project file, are you in the right directory?")
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
} else {
fmt.Println("Unknown error when trying to open ForlornOutcast.uproject... exiting")
}
}
fmt.Println("Found project file... continuing ")
projectABSPath, err := filepath.Abs("ForlornOutcast.uproject")
if err != nil {
fmt.Println("Unable to generate absolute file path to project file: ", err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
checkPath(projectABSPath) // Verifying path, will exit if fail
fmt.Println("Using Project Absolute Path: ", projectABSPath)
// Setting the folders to remove //remove.go
folderRemove := []string{".vs", "Binaries", "Intermediate", "Saved"}
fmt.Println("Removing Folders...")
err = removeFolders(folderRemove)
if err != nil {
fmt.Println(err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
// Setting the files to remove //remove.go
fileRemove := []string{"ForlornOutcast.sln"}
fmt.Println("Removing Files...")
err = removeFiles(fileRemove)
if err != nil {
fmt.Println(err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
// Editing the .uproject file //jsonEdit.go
err = editProjectFile(projectFile, riderEnabled)
if err != nil {
fmt.Printf("Error reading/modifying project file: %s", err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
fmt.Println("Project file has been modified as requested")
// Generating the vs files //generateFiles.go
err = generateFiles(projectABSPath)
if err != nil {
fmt.Println("Unable to generate project files, please generate project files manually: ", err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
fmt.Println("Project Files should have been generated...")
if !doBuild {
fmt.Println("Finished, press <enter> to exit!")
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
// Building the project //compile.go
err = buildProject(version, projectABSPath)
if err != nil {
fmt.Println("Unable to build project, please build the project manually: ", err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
fmt.Println("Finished, press <enter> to exit!")
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
// checkPath is a generic function to just verify file exists
func checkPath(path string) {
_, err := os.Stat(path)
if err != nil {
fmt.Printf("Path for file %s does not appear to be correct, error: %s exiting...", path, err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
}

50
engine/generateFiles.go Normal file
View File

@@ -0,0 +1,50 @@
package engine
import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"strings"
"golang.org/x/sys/windows/registry"
)
func findUnrealPath() (string, error) {
//Attempting to generate project files programattically
k, err := registry.OpenKey(registry.CLASSES_ROOT, `Unreal.ProjectFile\DefaultIcon`, registry.QUERY_VALUE)
if err != nil {
return "", err
}
defer k.Close()
s, _, err := k.GetStringValue("") //Pulling the (Default) value which has the path
if err != nil {
return "", err
}
s = strings.Trim(s, "\"") //Trim the quotes from around the string
return s, nil
}
func generateFiles(projectFileABSPath string) error {
// find the path to versionswitcher which is not in a specific unreal version directory since it needs to switch between versions
unrealExPath, err := findUnrealPath()
if err != nil {
fmt.Println("Unable to find the path to Unreal engine, please generate project files manually: ", err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
checkPath(unrealExPath) // Verifying path, will exit if fail
fmt.Println("Using Unreal Engine Path: ", unrealExPath)
generateArgs := []string{"/projectfiles", projectFileABSPath}
generateFilesCMD := exec.Command(unrealExPath, generateArgs...)
// var stdBuffer bytes.Buffer
// mw := io.MultiWriter(os.Stdout, &stdBuffer)
out := io.Writer(os.Stdout)
generateFilesCMD.Stdout = out
err = generateFilesCMD.Run()
if err != nil {
return err
}
return nil
}

64
engine/jsonEdit.go Normal file
View File

@@ -0,0 +1,64 @@
package engine
import (
"encoding/json"
"io/ioutil"
"os"
)
// This is the entire JSON File Struct so we can modify it as needed
type unrealProjectJSON struct {
FileVersion int `json:"FileVersion"`
EngineAssociation string `json:"EngineAssociation"`
Category string `json:"Category"`
Description string `json:"Description"`
Modules []struct {
Name string `json:"Name"`
Type string `json:"Type"`
LoadingPhase string `json:"LoadingPhase"`
AdditionalDependencies []string `json:"AdditionalDependencies,omitempty"`
} `json:"Modules"`
Plugins []struct {
Name string `json:"Name"`
Enabled bool `json:"Enabled"`
MarketplaceURL string `json:"MarketplaceURL,omitempty"`
SupportedTargetPlatforms []string `json:"SupportedTargetPlatforms,omitempty"`
} `json:"Plugins"`
}
func editProjectFile(projectFile os.FileInfo, enableRider bool) error {
byteValue, err := ioutil.ReadFile(projectFile.Name())
if err != nil {
return err
}
var projectStruct unrealProjectJSON
json.Unmarshal([]byte(byteValue), &projectStruct)
for i, plugin := range projectStruct.Plugins {
if plugin.Name == "OculusVR" {
projectStruct.Plugins[i].Enabled = false
}
if plugin.Name == "SteamVR" {
projectStruct.Plugins[i].Enabled = false
}
if plugin.Name == "RiderLink" {
if enableRider {
projectStruct.Plugins[i].Enabled = true
} else {
projectStruct.Plugins[i].Enabled = false
}
}
}
file, err := json.MarshalIndent(projectStruct, "", "\t")
if err != nil {
return err
}
err = ioutil.WriteFile(projectFile.Name(), file, 0644)
if err != nil {
return err
}
return nil
}

39
engine/remove.go Normal file
View File

@@ -0,0 +1,39 @@
package engine
import (
"bufio"
"fmt"
"os"
)
func removeFolders(folders []string) error {
for _, folder := range folders {
if err := os.RemoveAll(folder); err != nil {
if os.IsNotExist(err) { //If it doesn't exist that is fine, we would delete it anyway
continue
} else {
fmt.Printf("Error removing %s folder, error: %s exiting...", folder, err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
}
fmt.Println("Removed Folder: ", folder)
}
return nil
}
func removeFiles(files []string) error {
for _, file := range files {
if err := os.Remove(file); err != nil {
if os.IsNotExist(err) { //If it doesn't exist that is fine, we would delete it anyway
continue
} else {
fmt.Printf("Error removing %s file, error: %s exiting...", file, err)
bufio.NewReader(os.Stdin).ReadBytes('\n')
os.Exit(1)
}
}
fmt.Println("Removed file: ", file)
}
return nil
}

13
go.mod Normal file
View File

@@ -0,0 +1,13 @@
module github.com/deranjer/ForlornProjectManager
go 1.14
require (
github.com/c-bata/go-prompt v0.2.3
github.com/mattn/go-colorable v0.1.7 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/mattn/go-tty v0.0.3 // indirect
github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 // indirect
github.com/tidwall/sjson v1.1.1 // indirect
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae
)

32
go.sum Normal file
View File

@@ -0,0 +1,32 @@
github.com/c-bata/go-prompt v0.2.3 h1:jjCS+QhG/sULBhAaBdjb2PlMRVaKXQgn+4yzaauvs2s=
github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI=
github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 h1:pd4YKIqCB0U7O2I4gWHgEUA2mCEOENmco0l/bM957bU=
github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03/go.mod h1:Z9+Ul5bCbBKnbCvdOWbLqTHhJiYV414CURZJba6L8qA=
github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc=
github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8=
github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/sjson v1.1.1 h1:7h1vk049Jnd5EH9NyzNiEuwYW4b5qgreBbqRC19AS3U=
github.com/tidwall/sjson v1.1.1/go.mod h1:yvVuSnpEQv5cYIrO+AT6kw4QVfd5SDZoGIS7/5+fZFs=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

BIN
main.exe Normal file

Binary file not shown.

81
main.go Normal file
View File

@@ -0,0 +1,81 @@
package main
import (
"fmt"
"os"
"strings"
prompt "github.com/c-bata/go-prompt"
"github.com/deranjer/ForlornProjectManager/engine"
)
func executor(in string) {
in = strings.TrimSpace(in)
blocks := strings.Split(in, " ")
switch blocks[0] {
case "exit":
fmt.Println("Exiting!")
os.Exit(0)
case "rebuild":
if len(blocks) > 1 {
fmt.Println("Subcommand is: ", blocks[1])
switch blocks[1] {
case "--rider":
fmt.Println("Enabling rider plugin when cleaning")
engine.RebuildProject(true, true)
}
} else {
fmt.Println("Cleaning project with default settings...")
engine.RebuildProject(false, true)
}
case "clean":
if len(blocks) > 1 {
fmt.Println("Flag is: ", blocks[1])
switch blocks[1] {
case "--rider":
fmt.Println("Enabling rider plugin when cleaning")
engine.RebuildProject(true, false)
}
} else {
fmt.Println("Cleaning project with default settings...")
engine.RebuildProject(false, false)
}
case "help":
fmt.Println("Use 'clean' or 'rebuild' with the optional flag '--rider' if you need the rider plugin enabled.")
fmt.Println("Example Usage: 'clean --rider' or 'rebuild --rider'.")
case "post", "put", "patch":
if len(blocks) < 2 {
fmt.Println("please set request body.")
return
}
default:
fmt.Println("Sorry, I don't understand")
}
}
func completer(in prompt.Document) []prompt.Suggest {
s := []prompt.Suggest{
{Text: "rebuild", Description: "cleans the project folder and regenerates all files, then builds"},
{Text: "clean", Description: "only cleans the project folder and regenerates files, no build"},
{Text: "help", Description: "Shows the help for Unreal Project Manager"},
{Text: "exit", Description: "Exit the program"},
{Text: "--rider", Description: "FLAG: Enables the rider plugin after 'clean' or 'rebuild'"},
}
return prompt.FilterHasPrefix(s, in.GetWordBeforeCursor(), true)
}
func main() {
fmt.Println("Welcome to the Unreal Project Manager, run 'clean' to run a basic clean/regenerate or 'rebuild' to do a full rebuild.")
fmt.Println("Make sure Unreal and Visual Studio are closed, this cannot run if they are open.")
fmt.Println("NOTE: By default the rider plugin is disabled on rebuild user '--rider' flag to enable it on build or clean")
fmt.Println("Type 'help' to display the full information")
p := prompt.New(
executor,
completer,
prompt.OptionPrefix(">>> "),
//prompt.OptionParser()
)
p.Run()
}