Files
crosslangextras/Tesses.CrossLang.BuildEssentials/src/buildtool.tcross

329 lines
12 KiB
Plaintext

func Tesses.CrossLang.BuildTool(pm)
{
func copyFile(src,dest)
{
var src = FS.Local.OpenFile(src,"rb");
var dest = FS.Local.OpenFile(dest, "wb");
src.CopyTo(dest);
src.Close();
dest.Close();
}
return {
DirectoriesCompiled = [],
GetPackageDependencies = (this,name,version,dir)=>{
var dep = pm.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
};
},
BuildProject = (this,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")
outputDir = 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")
{
//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);
outFile.Close();
subdir.Close();
return null;
}
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";
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
{
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 dict = {};
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
});
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;
}
};
}