mirror of
https://onedev.site.tesses.net/crosslang/crosslangextras
synced 2026-02-09 01:25:46 +00:00
390 lines
14 KiB
Plaintext
390 lines
14 KiB
Plaintext
/^ The CrossLang BuildTool (use the function BuildProject) ^/
|
|
class Tesses.CrossLang.BuildTool
|
|
{
|
|
/^ Construct the build tool with Package Manager ^/
|
|
public BuildTool(pm)
|
|
{
|
|
this.PackageManager = pm;
|
|
}
|
|
|
|
private copyFile(src,dest)
|
|
{
|
|
var srcStrm = FS.Local.OpenFile(src,"rb");
|
|
var destStrm = FS.Local.OpenFile(dest, "wb");
|
|
srcStrm.CopyTo(destStrm);
|
|
srcStrm.Close();
|
|
destStrm.Close();
|
|
}
|
|
/^ Whether debug is enabled ^/
|
|
public Debug = false;
|
|
/^ Package Manager Object ^/
|
|
public PackageManager;
|
|
/^ Directories compiled ^/
|
|
public DirectoriesCompiled = [];
|
|
/^ Get the dependencies (don't use this directly unless you know what you are doing) ^/
|
|
public GetPackageDependencies(name, version, dir)
|
|
{
|
|
var dep = this.PackageManager.GetPackage(name,version);
|
|
if(TypeOf(dep) == "Null") throw $"Package {name} with version {version} does not exist";
|
|
|
|
|
|
var pkgPath = dir / $"{name}-{version}.crvm";
|
|
|
|
var strm = FS.Local.OpenFile(pkgPath,"wb");
|
|
|
|
strm.WriteBlock(dep,0,dep.Count);
|
|
strm.Close();
|
|
var strm = FS.Local.OpenFile(pkgPath,"rb");
|
|
|
|
|
|
var package = VM.LoadExecutable(strm);
|
|
strm.Close();
|
|
|
|
var deps = [];
|
|
|
|
each(var dep : package.Dependencies)
|
|
{
|
|
deps.Add(this.GetPackageDependencies(dep.Name, dep.Version, dir));
|
|
}
|
|
each(var pkg : package.Tools)
|
|
{
|
|
dep.Add(this.GetPackageDependencies(dep.Name, dep.Version, dir));
|
|
}
|
|
|
|
return {
|
|
Name = name,
|
|
Version = version,
|
|
Info = Json.Decode(package.Info),
|
|
Dependencies = deps,
|
|
Output = pkgPath
|
|
};
|
|
}
|
|
/^ Build the project in the directory projectDirectory ^/
|
|
public BuildProject(projectDirectory)
|
|
{
|
|
var dir = FS.MakeFull(projectDirectory);
|
|
var dirStr = dir.ToString();
|
|
|
|
|
|
|
|
|
|
each(var item : this.DirectoriesCompiled)
|
|
{
|
|
if(item.Path == dirStr) return item.Data;
|
|
}
|
|
|
|
var crossConf = dir / "cross.json";
|
|
if(FS.Local.FileExists(crossConf))
|
|
{
|
|
var configData = Json.Decode(FS.ReadAllText(FS.Local,crossConf));
|
|
var info = {type = "console"};
|
|
var name = "out";
|
|
var version = "1.0.0.0-prod";
|
|
var outputDir = "bin";
|
|
var objDir = "obj";
|
|
var srcDir = "src";
|
|
var resDir = "res";
|
|
var compTime = "none";
|
|
var icon = "";
|
|
if(TypeOf(configData.compTime) != "Undefined")
|
|
compTime = configData.compTime;
|
|
|
|
if(compTime == "full" && !this.AllowFullCompTime)
|
|
throw {
|
|
Type="CompTimeException",
|
|
Message="Failed to build due to having insecure comptime, use --allow-insecure-comptime if using the shell when building if you trust the program.",
|
|
ToString=(this)=>$"{this.Type} on line: {this.Line} {this.Message}"
|
|
};
|
|
|
|
if(TypeOf(configData.name) != "Undefined")
|
|
name = configData.name;
|
|
|
|
if(TypeOf(configData.version) != "Undefined")
|
|
version = configData.version;
|
|
if(TypeOf(configData.bin_directory) != "Undefined")
|
|
outputDir = configData.bin_directory;
|
|
|
|
if(TypeOf(configData.obj_directory) != "Undefined")
|
|
objDir = configData.obj_directory;
|
|
if(TypeOf(configData.source_directory) != "Undefined")
|
|
srcDir = configData.source_directory;
|
|
if(TypeOf(configData.resource_directory) != "Undefined")
|
|
resDir = configData.resource_directory;
|
|
if(TypeOf(configData.info) != "Undefined")
|
|
info = configData.info;
|
|
if(TypeOf(configData.icon) != "Undefined")
|
|
icon = configData.icon;
|
|
|
|
|
|
|
|
FS.Local.CreateDirectory(dir / outputDir);
|
|
|
|
if(TypeOf(info.type) == "String" && info.type == "template" || info.type == "archive")
|
|
{
|
|
|
|
//vfs, strm, name, version, info
|
|
var subdir = new SubdirFilesystem(FS.Local,dir);
|
|
var output = $"{name}-{version}.crvm";
|
|
var outFile = FS.Local.OpenFile(dir / outputDir / output,"wb");
|
|
|
|
if(TypeOf(info.template_ignored_files) != "Undefined")
|
|
{
|
|
var ignored = "";
|
|
each(var item : info.template_ignored_files)
|
|
{
|
|
ignored += $"{item}\n";
|
|
}
|
|
FS.WriteAllText(FS.Local, dir / ".crossarchiveignore", ignored);
|
|
}
|
|
FS.CreateArchive(subdir, outFile, name, version, Json.Encode(info),icon == "" ? "" : (/resDir/icon).ToString());
|
|
outFile.Close();
|
|
subdir.Close();
|
|
return {
|
|
Name = name,
|
|
Version = version,
|
|
Info = info,
|
|
Dependencies = [],
|
|
Output = dir / outputDir / output
|
|
};
|
|
}
|
|
|
|
FS.Local.CreateDirectory(dir / objDir / "packages");
|
|
|
|
FS.Local.CreateDirectory(dir/resDir);
|
|
|
|
var dependencies = [];
|
|
if(TypeOf(configData.project_dependencies) == "List")
|
|
{
|
|
each(var dep : configData.project_dependencies)
|
|
{
|
|
if(Path.FromString(dep).IsRelative())
|
|
{
|
|
dependencies.Add(this.BuildProject((dir / dep)));
|
|
}
|
|
else
|
|
dependencies.Add(this.BuildProject(dep));
|
|
}
|
|
}
|
|
var sources = [];
|
|
if(TypeOf(configData.dependencies) == "List")
|
|
{
|
|
each(var dep : configData.dependencies)
|
|
{
|
|
dependencies.Add(this.GetPackageDependencies(dep.name,dep.version,dir / objDir / "packages"));
|
|
}
|
|
}
|
|
|
|
|
|
each(var item : this.DirectoriesCompiled)
|
|
{
|
|
if(item.Path == dirStr) return item.Data;
|
|
}
|
|
|
|
|
|
func walk_for_compiling(item,dir2)
|
|
{
|
|
if(item.Info.type == "compile_tool")
|
|
{
|
|
var newDir = dir / objDir / $"{item.Name}-{item.Version}";
|
|
FS.Local.CreateDirectory(newDir);
|
|
var newFile = newDir / $"{item.Name}-{item.Version}.crvm";
|
|
|
|
this.copyFile(item.Output, newFile);
|
|
each(var item2 : item.Dependencies)
|
|
{
|
|
walk_for_compiling(item2, newDir);
|
|
}
|
|
//we need to load this
|
|
var env = VM.CreateEnvironment({});
|
|
env.RegisterEverything();
|
|
env.LockRegister();
|
|
|
|
env.LoadFileWithDependencies(FS.Local,newFile);
|
|
env.GetDictionary().RunTool({
|
|
Project = new SubdirFilesystem(FS.Local, dir),
|
|
ProjectInfo = info,
|
|
GeneratedSource = sources,
|
|
Config = this.Config
|
|
});
|
|
}
|
|
else
|
|
{
|
|
this.copyFile(item.Output, dir2 / $"{item.Name}-{item.Version}.crvm");
|
|
each(var item2 : item.Dependencies)
|
|
{
|
|
walk_for_compiling(item2, dir2);
|
|
}
|
|
}
|
|
}
|
|
|
|
var file_deps = [];
|
|
var file_tools = [];
|
|
|
|
each(var dep : dependencies)
|
|
{
|
|
if(dep.Info.type == "lib")
|
|
{
|
|
file_deps.Add({
|
|
Name = dep.Name,
|
|
Version = dep.Version
|
|
});
|
|
}
|
|
else if(dep.Info.type == "compile_tool")
|
|
{
|
|
|
|
file_tools.Add({
|
|
Name = dep.Name,
|
|
Version = dep.Version
|
|
});
|
|
}
|
|
walk_for_compiling(dep,dir / outputDir);
|
|
}
|
|
|
|
|
|
func walk_for_source(sourceDir)
|
|
{
|
|
each(var file : FS.Local.EnumeratePaths(sourceDir))
|
|
{
|
|
if(FS.Local.RegularFileExists(file) && file.GetExtension()==".tcross")
|
|
{
|
|
var src = {
|
|
FileName = file.ToString(),
|
|
Source = FS.ReadAllText(FS.Local, file)
|
|
};
|
|
sources.Add(src);
|
|
}
|
|
else if(FS.Local.DirectoryExists(file))
|
|
{
|
|
walk_for_source(file);
|
|
}
|
|
}
|
|
}
|
|
|
|
walk_for_source(dir / srcDir);
|
|
|
|
|
|
var output = $"{name}-{version}.crvm";
|
|
var outFile = FS.Local.OpenFile(dir / outputDir / output,"wb");
|
|
|
|
|
|
var compTimeEnv = null;
|
|
|
|
if(compTime != "none")
|
|
{
|
|
//dir / outputDir;
|
|
|
|
|
|
|
|
var exec = Env.GetRealExecutablePath("git");
|
|
var git_hash = "";
|
|
var git_tag = "";
|
|
if(FS.Local.FileExists(exec))
|
|
{
|
|
var process = new Process();
|
|
process.FileName = exec.ToString();
|
|
process.Arguments = ["rev-parse","HEAD"];
|
|
process.RedirectStandardInput = true;
|
|
process.RedirectStandardOutput = true;
|
|
process.WorkingDirectory = dirStr;
|
|
if(process.Start())
|
|
{
|
|
var memStrm = new MemoryStream(true);
|
|
process.StandardOutput.CopyTo(memStrm);
|
|
git_hash = memStrm.GetBytes().ToString().Split("\n")[0];
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
var dict = {
|
|
BuildTime = {
|
|
Git = {
|
|
Hash = git_hash,
|
|
Tag = git_tag
|
|
}
|
|
}
|
|
};
|
|
compTimeEnv = VM.CreateEnvironment(dict);
|
|
|
|
|
|
|
|
|
|
switch(compTime)
|
|
{
|
|
case "secure_file":
|
|
compTimeEnv.RegisterConsole();
|
|
compTimeEnv.RegisterClass();
|
|
compTimeEnv.RegisterCrypto();
|
|
compTimeEnv.RegisterDictionary();
|
|
compTimeEnv.RegisterJson();
|
|
compTimeEnv.RegisterRoot();
|
|
compTimeEnv.RegisterIO(false);
|
|
|
|
dict.FS.Local = new SubdirFilesystem(FS.Local,dir);
|
|
|
|
break;
|
|
case "full":
|
|
compTimeEnv.RegisterEverything();
|
|
break;
|
|
default:
|
|
//secure
|
|
compTimeEnv.RegisterConsole();
|
|
compTimeEnv.RegisterClass();
|
|
compTimeEnv.RegisterCrypto();
|
|
compTimeEnv.RegisterDictionary();
|
|
compTimeEnv.RegisterJson();
|
|
compTimeEnv.RegisterRoot();
|
|
compTimeEnv.RegisterIO(false);
|
|
|
|
break;
|
|
}
|
|
compTimeEnv.LockRegister();
|
|
each(var dep : file_deps)
|
|
{
|
|
compTimeEnv.LoadFileWithDependencies(FS.Local,dir/outputDir/$"{dep.Name}-{dep.Version}.crvm");
|
|
}
|
|
}
|
|
|
|
|
|
var result = VM.Compile({
|
|
Name = name,
|
|
Version = version,
|
|
Sources = sources,
|
|
Info = Json.Encode(info),
|
|
Icon = icon,
|
|
Tools = file_tools,
|
|
ResourceFileSystem = new SubdirFilesystem(FS.Local, dir / resDir),
|
|
Dependencies = file_deps,
|
|
Output = outFile,
|
|
CompTime = compTimeEnv,
|
|
Debug = this.Debug
|
|
});
|
|
|
|
outFile.Close();
|
|
if(!result.Success)
|
|
{
|
|
throw result.Reason;
|
|
}
|
|
|
|
var myData = {
|
|
Name = name,
|
|
Version = version,
|
|
Info = info,
|
|
Output = dir / outputDir / output,
|
|
Dependencies = dependencies
|
|
};
|
|
this.DirectoriesCompiled.Add({
|
|
Path = dirStr,
|
|
Data = myData
|
|
});
|
|
|
|
return myData;
|
|
}
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|