1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Added support for Setup program in managed packages

This commit is contained in:
Brian Fiete 2024-10-24 14:59:34 -04:00
parent c12c1bf9f9
commit 76c58b3ed0
4 changed files with 179 additions and 43 deletions

View file

@ -515,6 +515,8 @@ namespace IDE
public bool mAutoDelete = true; public bool mAutoDelete = true;
public bool mCanceled; public bool mCanceled;
public bool mIsTargetRun; public bool mIsTargetRun;
public bool mDone;
public bool mSmartOutput;
public ~this() public ~this()
{ {
@ -545,6 +547,14 @@ namespace IDE
mCanceled = true; mCanceled = true;
mProcess.Kill(0, .KillChildren); mProcess.Kill(0, .KillChildren);
} }
public void Release()
{
if (!mDone)
mAutoDelete = true;
else
delete this;
}
} }
List<ExecutionInstance> mExecutionInstances = new List<ExecutionInstance>() ~ DeleteContainerAndItems!(_); List<ExecutionInstance> mExecutionInstances = new List<ExecutionInstance>() ~ DeleteContainerAndItems!(_);
public int32 mHotIndex = 0; public int32 mHotIndex = 0;
@ -3307,7 +3317,7 @@ namespace IDE
case .Git(let url, let ver): case .Git(let url, let ver):
var checkPath = scope String(); var checkPath = scope String();
if (mPackMan.CheckLock(projectName, checkPath)) if (mPackMan.CheckLock(projectName, checkPath, var projectFailed))
{ {
projectFilePath = scope:: String(checkPath); projectFilePath = scope:: String(checkPath);
} }
@ -8979,7 +8989,7 @@ namespace IDE
const int cArgFileThreshold = 0x2000 - 1; const int cArgFileThreshold = 0x2000 - 1;
public ExecutionQueueCmd QueueRun(String fileName, String args, String workingDir, ArgsFileKind argsFileKind = .None) public ExecutionQueueCmd QueueRun(StringView fileName, StringView args, StringView workingDir, ArgsFileKind argsFileKind = .None)
{ {
var executionQueueCmd = new ExecutionQueueCmd(); var executionQueueCmd = new ExecutionQueueCmd();
executionQueueCmd.mFileName = new String(fileName); executionQueueCmd.mFileName = new String(fileName);
@ -8988,7 +8998,7 @@ namespace IDE
if (fileName.Length + args.Length + 1 > cArgFileThreshold) if (fileName.Length + args.Length + 1 > cArgFileThreshold)
{ {
// Only use UTF16 if we absolutely need to // Only use UTF16 if we absolutely need to
if ((argsFileKind == .UTF16WithBom) && (!args.HasMultibyteChars())) if ((argsFileKind == .UTF16WithBom) && (!args.HasMultibyteChars))
executionQueueCmd.mUseArgsFile = .UTF8; executionQueueCmd.mUseArgsFile = .UTF8;
else else
executionQueueCmd.mUseArgsFile = argsFileKind; executionQueueCmd.mUseArgsFile = argsFileKind;
@ -9132,11 +9142,11 @@ namespace IDE
NoWait = 8, NoWait = 8,
} }
public ExecutionInstance DoRun(String inFileName, String args, String workingDir, ArgsFileKind useArgsFile, Dictionary<String, String> envVars = null, String stdInData = null, RunFlags runFlags = .None, String reference = null) public ExecutionInstance DoRun(StringView inFileName, StringView args, StringView workingDir, ArgsFileKind useArgsFile, Dictionary<String, String> envVars = null, String stdInData = null, RunFlags runFlags = .None, String reference = null)
{ {
//Debug.Assert(executionInstance == null); //Debug.Assert(executionInstance == null);
String fileName = scope String(inFileName ?? ""); String fileName = scope String(inFileName);
QuoteIfNeeded(fileName); QuoteIfNeeded(fileName);
ProcessStartInfo startInfo = scope ProcessStartInfo(); ProcessStartInfo startInfo = scope ProcessStartInfo();
@ -9330,6 +9340,9 @@ namespace IDE
{ {
for (var str in executionInstance.mDeferredOutput) for (var str in executionInstance.mDeferredOutput)
{ {
if (executionInstance.mSmartOutput)
OutputLineSmart(str);
else
OutputLine(str); OutputLine(str);
delete str; delete str;
} }
@ -9406,6 +9419,7 @@ namespace IDE
if (isDone) if (isDone)
{ {
mExecutionInstances.RemoveAt(0); mExecutionInstances.RemoveAt(0);
executionInstance.mDone = true;
if (executionInstance.mAutoDelete) if (executionInstance.mAutoDelete)
delete executionInstance; delete executionInstance;
} }

View file

@ -3209,6 +3209,26 @@ namespace IDE.ui
} }
}); });
item = menu.AddItem("Clear Managed Cache");
item.mDisabled = (projectItem == null) || (!gApp.mPackMan.IsPathManaged(projectItem.mProject.mProjectDir));
item.mOnMenuItemSelected.Add(new (item) =>
{
var projectItem = GetSelectedProjectItem();
if (projectItem != null)
{
let project = projectItem.mProject;
String hash = scope .();
if (gApp.mPackMan.GetManagedHash(project.mProjectDir, hash))
{
gApp.[Friend]SaveWorkspaceLockData(true);
gApp.CloseOldBeefManaged();
if (gApp.mPackMan.mCleanHashSet.TryAdd(hash, var entryPtr))
*entryPtr = new .(hash);
gApp.[Friend]ReloadWorkspace();
}
}
});
item = menu.AddItem("Lock Project"); item = menu.AddItem("Lock Project");
if (projectItem.mProject.mLocked) if (projectItem.mProject.mLocked)
item.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check); item.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check);

View file

@ -432,7 +432,7 @@ namespace IDE.ui
public bool mLoadFailed; public bool mLoadFailed;
String mOldVerLoadCmd ~ delete _; String mOldVerLoadCmd ~ delete _;
HTTPRequest mOldVerHTTPRequest ~ delete _; HTTPRequest mOldVerHTTPRequest ~ delete _;
IDEApp.ExecutionInstance mOldVerLoadExecutionInstance ~ { if (_ != null) _.mAutoDelete = true; }; IDEApp.ExecutionInstance mOldVerLoadExecutionInstance ~ _?.Release();
SourceFindTask mSourceFindTask ~ delete _; SourceFindTask mSourceFindTask ~ delete _;
HoverResolveTask mHoverResolveTask ~ delete _; HoverResolveTask mHoverResolveTask ~ delete _;
bool mWantsFastClassify; bool mWantsFastClassify;

View file

@ -19,7 +19,8 @@ namespace IDE.util
None, None,
FindVersion, FindVersion,
Clone, Clone,
Checkout Checkout,
Setup
} }
public Kind mKind; public Kind mKind;
@ -30,6 +31,7 @@ namespace IDE.util
public String mHash ~ delete _; public String mHash ~ delete _;
public String mPath ~ delete _; public String mPath ~ delete _;
public GitManager.GitInstance mGitInstance ~ _?.ReleaseRef(); public GitManager.GitInstance mGitInstance ~ _?.ReleaseRef();
public IDEApp.ExecutionInstance mExecInstance ~ _?.Release();
public ~this() public ~this()
{ {
@ -41,6 +43,7 @@ namespace IDE.util
public bool mInitialized; public bool mInitialized;
public String mManagedPath ~ delete _; public String mManagedPath ~ delete _;
public bool mFailed; public bool mFailed;
public HashSet<String> mCleanHashSet = new .() ~ DeleteContainerAndItems!(_);
public void Fail(StringView error) public void Fail(StringView error)
{ {
@ -53,6 +56,26 @@ namespace IDE.util
} }
} }
public bool IsPathManaged(StringView path)
{
if (path.IsEmpty)
return false;
if (String.IsNullOrEmpty(mManagedPath))
return false;
if (path.Length < mManagedPath.Length)
return false;
return Path.Equals(mManagedPath, path.Substring(0, mManagedPath.Length));
}
public bool GetManagedHash(StringView path, String outHash)
{
StringView subView = path.Substring(mManagedPath.Length + 1);
if (subView.Length < 40)
return false;
outHash.Append(subView.Substring(0, 40));
return true;
}
public bool CheckInit() public bool CheckInit()
{ {
if ((gApp.mWorkspace.mProjectLoadState != .Preparing) && (mWorkItems.IsEmpty)) if ((gApp.mWorkspace.mProjectLoadState != .Preparing) && (mWorkItems.IsEmpty))
@ -79,8 +102,10 @@ namespace IDE.util
outPath.AppendF($"{mManagedPath}/{hash}"); outPath.AppendF($"{mManagedPath}/{hash}");
} }
public bool CheckLock(StringView projectName, String outPath) public bool CheckLock(StringView projectName, String outPath, out bool failed)
{ {
failed = false;
if (!CheckInit()) if (!CheckInit())
return false; return false;
@ -96,12 +121,19 @@ namespace IDE.util
switch (lock) switch (lock)
{ {
case .Git(let url, let tag, let hash): case .Git(let url, let tag, let hash):
if (mCleanHashSet.Contains(hash))
return false;
var path = GetPath(url, hash, .. scope .()); var path = GetPath(url, hash, .. scope .());
var managedFilePath = scope $"{path}/BeefManaged.toml"; var managedFilePath = scope $"{path}/BeefManaged.toml";
if (File.Exists(managedFilePath)) if (File.Exists(managedFilePath))
{ {
StructuredData sd = scope .();
sd.Load(managedFilePath).IgnoreError();
outPath.Append(path); outPath.Append(path);
outPath.Append("/BeefProj.toml"); outPath.Append("/BeefProj.toml");
if (!sd.GetBool("Setup"))
gApp.OutputErrorLine(scope $"Project '{projectName}' previous failed setup. Clean managed cache to try again.");
return true; return true;
} }
default: default:
@ -110,10 +142,15 @@ namespace IDE.util
return false; return false;
} }
public void CloneCompleted(StringView projectName, StringView url, StringView tag, StringView hash, StringView path) public void CloneCompleted(StringView projectName, StringView url, StringView tag, StringView hash, StringView path, bool writeFile, bool setupComplete)
{ {
if (mCleanHashSet.GetAndRemoveAlt(hash) case .Ok(let val))
delete val;
gApp.mWorkspace.SetLock(projectName, .Git(new .(url), new .(tag), new .(hash))); gApp.mWorkspace.SetLock(projectName, .Git(new .(url), new .(tag), new .(hash)));
if (writeFile)
{
StructuredData sd = scope .(); StructuredData sd = scope .();
sd.CreateNew(); sd.CreateNew();
sd.Add("FileVersion", 1); sd.Add("FileVersion", 1);
@ -121,10 +158,39 @@ namespace IDE.util
sd.Add("GitURL", url); sd.Add("GitURL", url);
sd.Add("GitTag", tag); sd.Add("GitTag", tag);
sd.Add("GitHash", hash); sd.Add("GitHash", hash);
sd.Add("Setup", setupComplete);
var tomlText = sd.ToTOML(.. scope .()); var tomlText = sd.ToTOML(.. scope .());
var managedFilePath = scope $"{path}/BeefManaged.toml"; var managedFilePath = scope $"{path}/BeefManaged.toml";
File.WriteAllText(managedFilePath, tomlText).IgnoreError(); File.WriteAllText(managedFilePath, tomlText).IgnoreError();
} }
}
public void RunSetupProject(StringView projectName, StringView url, StringView tag, StringView hash, StringView path)
{
if (!CheckInit())
return;
String beefBuildPath = scope $"{gApp.mInstallDir}BeefBuild.exe";
String args = scope $"-run";
var execInst = gApp.DoRun(beefBuildPath, args, path, .None);
execInst?.mAutoDelete = false;
execInst?.mSmartOutput = true;
WorkItem workItem = new .();
workItem.mKind = .Setup;
workItem.mProjectName = new .(projectName);
workItem.mURL = new .(url);
workItem.mTag = new .(tag);
workItem.mHash = new .(hash);
workItem.mPath = new .(path);
workItem.mExecInstance = execInst;
mWorkItems.Add(workItem);
/*cmd.mDoneEvent.Add(new (success) =>
{
int a = 123;
});*/
}
public void GetWithHash(StringView projectName, StringView url, StringView tag, StringView hash) public void GetWithHash(StringView projectName, StringView url, StringView tag, StringView hash)
{ {
@ -135,6 +201,8 @@ namespace IDE.util
var urlPath = Path.GetDirectoryPath(destPath, .. scope .()); var urlPath = Path.GetDirectoryPath(destPath, .. scope .());
Directory.CreateDirectory(urlPath).IgnoreError(); Directory.CreateDirectory(urlPath).IgnoreError();
if (Directory.Exists(destPath)) if (Directory.Exists(destPath))
{
if (!mCleanHashSet.ContainsAlt(hash))
{ {
var managedFilePath = scope $"{destPath}/BeefManaged.toml"; var managedFilePath = scope $"{destPath}/BeefManaged.toml";
if (File.Exists(managedFilePath)) if (File.Exists(managedFilePath))
@ -147,14 +215,14 @@ namespace IDE.util
gApp.OutputLine($"Git selecting library '{projectName}' tag '{tag}' at {hash.Substring(0, 7)}"); gApp.OutputLine($"Git selecting library '{projectName}' tag '{tag}' at {hash.Substring(0, 7)}");
} }
CloneCompleted(projectName, url, tag, hash, destPath); CloneCompleted(projectName, url, tag, hash, destPath, false, false);
ProjectReady(projectName, destPath); ProjectReady(projectName, destPath);
return; return;
} }
}
String tempDir = new $"{destPath}__{(int32)Internal.GetTickCountMicro():X}"; String tempDir = new $"{destPath}__{(int32)Internal.GetTickCountMicro():X}";
//if (Directory.DelTree(destPath) case .Err)
if (Directory.Move(destPath, tempDir) case .Err) if (Directory.Move(destPath, tempDir) case .Err)
{ {
delete tempDir; delete tempDir;
@ -272,16 +340,31 @@ namespace IDE.util
// First handle active git items // First handle active git items
for (var workItem in mWorkItems) for (var workItem in mWorkItems)
{ {
bool removeItem = false;
if (workItem.mGitInstance == null) if (workItem.mGitInstance == null)
continue; {
switch (workItem.mKind)
if (!workItem.mGitInstance.mDone) {
case .Setup:
if ((workItem.mExecInstance == null) || (workItem.mExecInstance.mDone))
{
bool success = workItem.mExecInstance?.mExitCode == 0;
String projPath = Path.GetAbsolutePath("../", workItem.mPath, .. scope .());
CloneCompleted(workItem.mProjectName, workItem.mURL, workItem.mTag, workItem.mHash, projPath, true, success);
if (success)
ProjectReady(workItem.mProjectName, projPath);
else
gApp.OutputErrorLine(scope $"Failed to setup project '{workItem.mProjectName}' located at '{projPath}'");
removeItem = true;
}
default:
}
}
else if (!workItem.mGitInstance.mDone)
{ {
executingGit = true; executingGit = true;
continue;
} }
else if (!workItem.mGitInstance.mFailed)
if (!workItem.mGitInstance.mFailed)
{ {
switch (workItem.mKind) switch (workItem.mKind)
{ {
@ -343,22 +426,41 @@ namespace IDE.util
case .Clone: case .Clone:
Checkout(workItem.mProjectName, workItem.mURL, workItem.mPath, workItem.mTag, workItem.mHash); Checkout(workItem.mProjectName, workItem.mURL, workItem.mPath, workItem.mTag, workItem.mHash);
case .Checkout: case .Checkout:
CloneCompleted(workItem.mProjectName, workItem.mURL, workItem.mTag, workItem.mHash, workItem.mPath);
ProjectReady(workItem.mProjectName, workItem.mPath);
if (gApp.mVerbosity >= .Normal) if (gApp.mVerbosity >= .Normal)
gApp.OutputLine($"Git cloning library '{workItem.mProjectName}' done."); gApp.OutputLine($"Git cloning library '{workItem.mProjectName}' done.");
String setupPath = scope $"{workItem.mPath}/Setup";
/*if (workItem.mProjectName == "BeefProj0")
{
setupPath.Set("C:/proj/BeefProj0/Setup");
}*/
if (Directory.Exists(setupPath))
{
RunSetupProject(workItem.mProjectName, workItem.mURL, workItem.mTag, workItem.mHash, setupPath);
}
else
{
CloneCompleted(workItem.mProjectName, workItem.mURL, workItem.mTag, workItem.mHash, workItem.mPath, true, true);
ProjectReady(workItem.mProjectName, workItem.mPath);
}
default: default:
} }
removeItem = true;
} }
else else
{ {
Fail(scope $"Failed to retrieve project '{workItem.mProjectName}' at '{workItem.mURL}'"); Fail(scope $"Failed to retrieve project '{workItem.mProjectName}' at '{workItem.mURL}'");
removeItem = true;
} }
if (removeItem)
{
@workItem.Remove(); @workItem.Remove();
delete workItem; delete workItem;
} }
}
if (!executingGit) if (!executingGit)
{ {