add prebuild to build tool
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
bin
|
||||
obj
|
||||
.DS_Store
|
||||
@@ -1,2 +1,3 @@
|
||||
bin
|
||||
obj
|
||||
.DS_Store
|
||||
@@ -1,2 +1,3 @@
|
||||
bin
|
||||
obj
|
||||
.DS_Store
|
||||
@@ -1,2 +1,3 @@
|
||||
bin
|
||||
obj
|
||||
.DS_Store
|
||||
@@ -117,9 +117,10 @@ class Tesses.CrossLang.BuildTool
|
||||
|
||||
|
||||
|
||||
|
||||
FS.Local.CreateDirectory(dir / outputDir);
|
||||
|
||||
if(TypeOf(info.type) == "String" && info.type == "template" || info.type == "archive")
|
||||
if(TypeOf(info.type) == "String" && (info.type == "template" || info.type == "archive"))
|
||||
{
|
||||
|
||||
//vfs, strm, name, version, info
|
||||
@@ -149,9 +150,14 @@ class Tesses.CrossLang.BuildTool
|
||||
}
|
||||
|
||||
FS.Local.CreateDirectory(dir / objDir / "packages");
|
||||
FS.Local.CreateDirectory(dir / objDir / "res");
|
||||
|
||||
FS.Local.CreateDirectory(dir/resDir);
|
||||
|
||||
const svfs = new Tesses.CrossLang.SharedViewFilesystem();
|
||||
svfs.AddFS(new SubdirFilesystem(FS.Local, dir / resDir));
|
||||
svfs.AddFS(new SubdirFilesystem(FS.Local, dir / objDir / "res"));
|
||||
|
||||
var dependencies = [];
|
||||
if(TypeOf(configData.project_dependencies) == "List")
|
||||
{
|
||||
@@ -201,7 +207,9 @@ class Tesses.CrossLang.BuildTool
|
||||
|
||||
env.LoadFileWithDependencies(FS.Local,newFile);
|
||||
env.GetDictionary().RunTool({
|
||||
ProjectDirectory = dir,
|
||||
Project = new SubdirFilesystem(FS.Local, dir),
|
||||
ProjectJson = configData,
|
||||
ProjectInfo = info,
|
||||
GeneratedSource = sources,
|
||||
Config = this.Config
|
||||
@@ -220,6 +228,62 @@ class Tesses.CrossLang.BuildTool
|
||||
var file_deps = [];
|
||||
var file_tools = [];
|
||||
|
||||
if(TypeIsList(configData.prebuild))
|
||||
{
|
||||
//do the prebuild things
|
||||
|
||||
each(var job : configData.prebuild)
|
||||
{
|
||||
if(TypeIsDictionary(job))
|
||||
{
|
||||
if(TypeIsString(job.condition))
|
||||
{
|
||||
if(!VM.Eval($"return {job.condition};"))
|
||||
continue;
|
||||
}
|
||||
var workdir = dir;
|
||||
if(TypeIsString(job.workdir))
|
||||
workdir /= job.workdir;
|
||||
if(TypeIsList(job.commands))
|
||||
each(var cmd : job.commands)
|
||||
{
|
||||
if(TypeIsList(cmd) && cmd.Length > 0)
|
||||
{
|
||||
const name = cmd[0];
|
||||
const path = Env.GetRealExecutablePath(name).ToString();
|
||||
cmd.RemoveAt(0);
|
||||
var p= Process.Start({
|
||||
FileName = path,
|
||||
Arguments = cmd,
|
||||
WorkingDirectory = workdir
|
||||
});
|
||||
const result = p.Join();
|
||||
if(result != 0)
|
||||
throw $"process: {name}, did not indicate success: {result}";
|
||||
}
|
||||
}
|
||||
|
||||
if(TypeIsList(job.res))
|
||||
{
|
||||
each(var reso : job.res)
|
||||
{
|
||||
if(TypeIsString(reso))
|
||||
{
|
||||
svfs.AddFS(new SubdirFilesystem(FS.Local, dir / reso));
|
||||
}
|
||||
else if(TypeIsDictionary(reso) && TypeIsString(reso.src) && TypeOfString(reso.dest))
|
||||
{
|
||||
const mountable = new MountableFilesystem(new Filesystem({}));
|
||||
mountable.Mount(reso.dest,new SubdirFilesystem(FS.Local, dir / reso.src));
|
||||
svfs.AddFS(mountable);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
each(var dep : dependencies)
|
||||
{
|
||||
if(dep.Info.type == "lib")
|
||||
@@ -243,6 +307,7 @@ class Tesses.CrossLang.BuildTool
|
||||
|
||||
func walk_for_source(sourceDir)
|
||||
{
|
||||
if(FS.Local.DirectoryExists(sourceDir))
|
||||
each(var file : FS.Local.EnumeratePaths(sourceDir))
|
||||
{
|
||||
if(FS.Local.RegularFileExists(file) && file.GetExtension()==".tcross")
|
||||
@@ -355,7 +420,7 @@ class Tesses.CrossLang.BuildTool
|
||||
Info = Json.Encode(info),
|
||||
Icon = icon,
|
||||
Tools = file_tools,
|
||||
ResourceFileSystem = new SubdirFilesystem(FS.Local, dir / resDir),
|
||||
ResourceFileSystem = svfs,
|
||||
Dependencies = file_deps,
|
||||
Output = outFile,
|
||||
CompTime = compTimeEnv,
|
||||
@@ -379,7 +444,6 @@ class Tesses.CrossLang.BuildTool
|
||||
Path = dirStr,
|
||||
Data = myData
|
||||
});
|
||||
|
||||
return myData;
|
||||
}
|
||||
return null;
|
||||
|
||||
65
Tesses.CrossLang.BuildEssentials/src/sharedviewfs.tcross
Normal file
65
Tesses.CrossLang.BuildEssentials/src/sharedviewfs.tcross
Normal file
@@ -0,0 +1,65 @@
|
||||
func New.Tesses.CrossLang.SharedViewFilesystem()
|
||||
{
|
||||
const fileSystems = [];
|
||||
func enumeratePaths (path) {
|
||||
var found = [];
|
||||
|
||||
each(var fs : fileSystems)
|
||||
{
|
||||
if(fs.DirectoryExists(path))
|
||||
{
|
||||
each(var ent : fs.EnumeratePaths(path))
|
||||
{
|
||||
const name = ent.GetFileName();
|
||||
if(found.Contains(name)) continue;
|
||||
found.Add(name);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
const fs_dict = {
|
||||
OpenFile = (path, mode) => {
|
||||
if(mode == "r" || mode == "rb")
|
||||
{
|
||||
each(var fs : fileSystems)
|
||||
{
|
||||
if(fs.FileExists(path))
|
||||
return fs.OpenFile(path,mode);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
EnumeratePaths = enumeratePaths,
|
||||
RegularFileExists = (path) => {
|
||||
each(var fs : fileSystems)
|
||||
{
|
||||
if(fs.RegularFileExists(path)) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
FileExists = (path) => {
|
||||
each(var fs : fileSystems)
|
||||
{
|
||||
if(fs.FileExists(path)) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
DirectoryExists = (path) => {
|
||||
each(var fs : fileSystems)
|
||||
{
|
||||
if(fs.DirectoryExists(path)) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
AddFS = (fs)=>{
|
||||
fileSystems.Add(fs);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return new Filesystem(fs_dict);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ func Tesses.CrossLang.Shell.Default(dd)
|
||||
if(flag == "version")
|
||||
{
|
||||
Console.WriteLine($"VM version: {VM.RuntimeVersion}");
|
||||
Console.WriteLine($"Bytecode version: {VM.BytecodeVersion}");
|
||||
Console.WriteLine($"Shell version: {main.File.Version}");
|
||||
Console.WriteLine($"Args version: {Tesses.CrossLang.Args.File.Version}");
|
||||
Console.WriteLine($"BuildTool version: {Tesses.CrossLang.BuildTool.File.Version}");
|
||||
@@ -15,6 +16,7 @@ func Tesses.CrossLang.Shell.Default(dd)
|
||||
Console.WriteLine("COMMANDS:");
|
||||
Console.WriteLine("new: create new project");
|
||||
Console.WriteLine("build: build a project");
|
||||
Console.WriteLine("test: test a project");
|
||||
Console.WriteLine("run: run a project");
|
||||
Console.WriteLine("debug: debug a project");
|
||||
Console.WriteLine("install-console: install a console application");
|
||||
|
||||
@@ -80,6 +80,9 @@ func main(args)
|
||||
case "publish":
|
||||
return Tesses.CrossLang.Shell.Publish(dd);
|
||||
break;
|
||||
case "test":
|
||||
return Tesses.CrossLang.Shell.Test(dd);
|
||||
break;
|
||||
default:
|
||||
return Tesses.CrossLang.Shell.Default(dd);
|
||||
}
|
||||
|
||||
386
Tesses.CrossLang.Shell/src/test.tcross
Normal file
386
Tesses.CrossLang.Shell/src/test.tcross
Normal file
@@ -0,0 +1,386 @@
|
||||
class ExpectObj {
|
||||
private inverted=false;
|
||||
private currentSpec;
|
||||
private currentTest;
|
||||
private left;
|
||||
public getNot() {
|
||||
this.inverted = !this.inverted;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ExpectObj(currentTest,currentSpec,left)
|
||||
{
|
||||
this.currentTest = currentTest;
|
||||
this.currentSpec = currentSpec;
|
||||
this.left = left;
|
||||
}
|
||||
public ToBe(right)
|
||||
{
|
||||
if(this.inverted)
|
||||
{
|
||||
this.SetRes(this.left != right, $"{this.left} is equal to {this.right}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
this.SetRes(this.left == right, $"{this.left} is not equal to {right}");
|
||||
}
|
||||
}
|
||||
public LessThan(right)
|
||||
{
|
||||
if(this.inverted)
|
||||
{
|
||||
this.SetRes(!(this.left < right), $"{this.left} is less than {this.right}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
this.SetRes(this.left < right, $"{this.left} is not less than {right}");
|
||||
}
|
||||
}
|
||||
public GreaterThan(right)
|
||||
{
|
||||
if(this.inverted)
|
||||
{
|
||||
this.SetRes(!(this.left > right), $"{this.left} is greater than {this.right}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
this.SetRes(this.left > right, $"{this.left} is not greater than {right}");
|
||||
}
|
||||
}
|
||||
|
||||
private SetRes(succeeded, failmsg)
|
||||
{
|
||||
if(!succeeded)
|
||||
{
|
||||
this.currentTest.success = false;
|
||||
this.currentSpec.pass=false;
|
||||
this.currentSpec.reason = failmsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Tesses.CrossLang.Shell.Test(dd)
|
||||
{
|
||||
var offline=false;
|
||||
var buildPath = ".";
|
||||
var nobuild=false;
|
||||
var allowFullCompTime=false;
|
||||
var output="";
|
||||
var debug = false;
|
||||
each(var flag : dd.Flags)
|
||||
{
|
||||
if(flag == "debug")
|
||||
{
|
||||
debug = true;
|
||||
}
|
||||
else if(flag == "offline")
|
||||
{
|
||||
offline = true;
|
||||
}
|
||||
else if(flag == "allow-insecure-comptime")
|
||||
{
|
||||
allowFullCompTime=true;
|
||||
}
|
||||
else if(flag == "help")
|
||||
{
|
||||
Console.WriteLine("USAGE: crosslang test [run-flags-and-options] program-arguments...");
|
||||
Console.WriteLine("USAGE: crosslang test [run-flags-and-options] -- program-arguments-and-options...");
|
||||
Console.WriteLine("FLAGS:");
|
||||
Console.WriteLine("offline: build with no internet (don't fetch files)");
|
||||
Console.WriteLine("allow-insecure-comptime: Allow full comptime");
|
||||
Console.WriteLine("nobuild: don't build, just run");
|
||||
Console.WriteLine("debug: emit line info into executable");
|
||||
Console.WriteLine("help: this help");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("OPTIONS:");
|
||||
Console.WriteLine("conf=CONFIGSTRING: specify a conf string for compile_tool(s), is the property Config");
|
||||
return 0;
|
||||
}
|
||||
else if(flag == "nobuild")
|
||||
{
|
||||
nobuild=true;
|
||||
}
|
||||
}
|
||||
var conf = "";
|
||||
each(var option : dd.Options)
|
||||
{
|
||||
if(option.Key == "conf")
|
||||
{
|
||||
conf = option.Value;
|
||||
}
|
||||
}
|
||||
if(nobuild)
|
||||
{
|
||||
if(FS.Local.FileExists("cross.json"))
|
||||
{
|
||||
var proj = Json.Decode(FS.ReadAllText(FS.Local, "cross.json"));
|
||||
var nameVer = $"{proj.name}-{proj.version}.crvm";
|
||||
var buildDir = TypeOf(proj.bin_directory) == "String" ? proj.bin_directory : "bin";
|
||||
|
||||
output =./buildDir/nameVer;
|
||||
if(!FS.Local.FileExists(output))
|
||||
{
|
||||
Console.WriteLine($"ERROR: file {output} does not exist.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("ERROR: could not find project.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var pm = new Tesses.CrossLang.PackageManager();
|
||||
pm.Offline = offline;
|
||||
var bt = new Tesses.CrossLang.BuildTool(pm);
|
||||
bt.Config = conf;
|
||||
bt.Debug = debug;
|
||||
bt.AllowFullCompTime = allowFullCompTime;
|
||||
output = bt.BuildProject(buildPath).Output;
|
||||
|
||||
}
|
||||
|
||||
return Tesses.CrossLang.Shell.RunTestSuite(output);
|
||||
}
|
||||
|
||||
|
||||
|
||||
func Tesses.CrossLang.Shell.RunTestSuite(execFile)
|
||||
{
|
||||
var configData = Json.Decode(FS.ReadAllText(FS.Local,"cross.json")) ?? {};
|
||||
var testDir = configData.test_directory ?? "tests";
|
||||
var sources = [];
|
||||
func walk_for_source(sourceDir)
|
||||
{
|
||||
if(FS.Local.DirectoryExists(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(testDir);
|
||||
const strm = new MemoryStream(true);
|
||||
var result = VM.Compile({
|
||||
Name = "/test/",
|
||||
Version = "1.0.0.0-prod",
|
||||
Sources = sources,
|
||||
Dependencies = [], //they are loaded for us
|
||||
Output = strm,
|
||||
CompTime = compTimeEnv,
|
||||
Debug = this.Debug
|
||||
});
|
||||
if(result.Success)
|
||||
{
|
||||
const RED = "\e[0;91m";
|
||||
|
||||
const GREEN = "\e[0;92m";
|
||||
const YELLOW = "\e[;93m";
|
||||
const NC = "\e[0m";
|
||||
|
||||
strm.Seek(0,0);
|
||||
|
||||
var vmFile = VM.LoadExecutable(strm);
|
||||
strm.GetBytes().Resize(0);
|
||||
|
||||
var env = VM.CreateEnvironment({});
|
||||
env.RegisterEverything();
|
||||
env.LockRegister();
|
||||
|
||||
env.LoadFileWithDependencies(FS.Local,execFile);
|
||||
var failed = 0;
|
||||
var total = 0;
|
||||
var currentTest = null;
|
||||
var currentSpec = null;
|
||||
func Test(name, cb)
|
||||
{
|
||||
total++;
|
||||
currentTest = {
|
||||
success = true,
|
||||
specs = []
|
||||
};
|
||||
testLists.Add(currentTest);
|
||||
try {
|
||||
cb();
|
||||
if(!currentTest.success)
|
||||
{
|
||||
failed++;
|
||||
|
||||
Console.WriteLine($"[{RED}FAILED{NC}] {name}");
|
||||
each(var s : currentTest.specs)
|
||||
{
|
||||
if(s.todo)
|
||||
{
|
||||
Console.WriteLine($"\t[{YELLOW}TODO{NC}] {s.name}");
|
||||
}
|
||||
else if(s.pass)
|
||||
{
|
||||
Console.WriteLine($"\t[{GREEN}PASS{NC}] {s.name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"\t[{RED}FAILED{NC}] {s.name}");
|
||||
Console.WriteLine($"\t\tReason: {s.reason}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Console.WriteLine($"[{GREEN}PASS{NC}] {name}");
|
||||
each(var s : currentTest.specs)
|
||||
{
|
||||
if(s.todo)
|
||||
{
|
||||
Console.WriteLine($"\t[{YELLOW}TODO{NC}] {s.name}");
|
||||
}
|
||||
else if(s.pass)
|
||||
{
|
||||
Console.WriteLine($"\t[{GREEN}PASS{NC}] {s.name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch(ex)
|
||||
{
|
||||
Console.WriteLine($"[{RED}EXCEPTION{NC}] {name}");
|
||||
Console.WriteLine($"\tReason: {ex}");
|
||||
each(var s : currentTest.specs)
|
||||
{
|
||||
if(s.todo)
|
||||
{
|
||||
Console.WriteLine($"\t[{YELLOW}TODO{NC}] {s.name}");
|
||||
}
|
||||
else if(s.pass)
|
||||
{
|
||||
Console.WriteLine($"\t[{GREEN}PASS{NC}] {s.name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"\t[{RED}FAILED{NC}] {s.name}");
|
||||
Console.WriteLine($"\t\tReason: {s.reason}");
|
||||
}
|
||||
}
|
||||
failed++;
|
||||
}
|
||||
|
||||
currentTest = null;
|
||||
}
|
||||
func SpecToDo(name)
|
||||
{
|
||||
|
||||
if(TypeIsDictionary(currentSpec))
|
||||
{
|
||||
throw "Must not be in Spec";
|
||||
}
|
||||
if(TypeIsDictionary(currentTest))
|
||||
{
|
||||
currentTest.specs.Add({
|
||||
todo = true,
|
||||
name
|
||||
});
|
||||
}
|
||||
else {
|
||||
throw "Must be within Test(\"My test name\",()=>{});";
|
||||
}
|
||||
}
|
||||
func Spec(name,cb)
|
||||
{
|
||||
if(TypeIsDictionary(currentSpec))
|
||||
{
|
||||
throw "Must not be in Spec";
|
||||
}
|
||||
if(TypeIsDictionary(currentTest))
|
||||
{
|
||||
currentSpec = {
|
||||
name
|
||||
};
|
||||
currentTest.specs.Add(currentSpec);
|
||||
|
||||
cb();
|
||||
|
||||
currentSpec.pass ??= true;
|
||||
currentSpec = null;
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
throw "Must be within Test(\"My test name\",()=>{});";
|
||||
}
|
||||
}
|
||||
func Expect(val)
|
||||
{
|
||||
if(TypeIsDictionary(currentTest) && TypeIsDictionary(currentSpec))
|
||||
{
|
||||
return new ExpectObj(currentTest,currentSpec,val);
|
||||
}
|
||||
else {
|
||||
|
||||
throw "Must be within Spec(\"My spec name\",()=>{});";
|
||||
}
|
||||
}
|
||||
func Assert(val, failmsg)
|
||||
{
|
||||
if(TypeIsDictionary(currentTest) && TypeIsDictionary(currentSpec))
|
||||
{
|
||||
if(val)
|
||||
else
|
||||
{
|
||||
currentSpec.pass=false;
|
||||
currentSpec.reason = failmsg;
|
||||
currentTest.success=false;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
throw "Must be within Spec(\"My spec name\",()=>{});";
|
||||
}
|
||||
}
|
||||
env.SetVariable("Test", Test);
|
||||
env.SetVariable("Spec", Spec);
|
||||
env.SetVariable("SpecToDo", SpecToDo);
|
||||
env.SetVariable("Expect", Expect);
|
||||
env.SetVariable("Assert",Assert);
|
||||
|
||||
const beginTime = DateTime.Now;
|
||||
try {
|
||||
env.LoadFile(vmFile);
|
||||
|
||||
|
||||
} catch(ex) {
|
||||
Console.WriteLine($"[{RED}EXCEPTION{NC}] {ex}");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
if(failed == 0)
|
||||
{
|
||||
Console.WriteLine($"Tests {GREEN}passed{NC} in {(DateTime.Now-beginTime).ToString(true)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Console.WriteLine($"Tests {RED}failed{NC} in {(DateTime.Now-beginTime).ToString(true)}");
|
||||
}
|
||||
Console.WriteLine($"Passed: {total-failed}");
|
||||
Console.WriteLine($"Failed: {failed}");
|
||||
Console.WriteLine($"Total: {total}");
|
||||
return failed > 0 ? 1 : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -202,6 +202,7 @@ export async function createTemplate()
|
||||
if(project_name)
|
||||
{
|
||||
const dir = join(getDocumentsFolder(),"CrossLangProjects",project_name);
|
||||
mkdirSync(join(getDocumentsFolder(),"CrossLangProjects"));
|
||||
mkdirSync(dir);
|
||||
|
||||
await readCommandToEnd("crosslang",["new",templateName,dir]);
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
},
|
||||
{
|
||||
"name": "keyword.control.crosslang",
|
||||
"match": "\\b(if|else|while|for|do|return|each|in|break|try|catch|finally|defer|enumerable|yield|switch|case|default|await|breakpoint|throw)\\b"
|
||||
"match": "\\b(if|else|while|for|do|return|each|in|break|continue|try|catch|finally|defer|enumerable|yield|switch|case|default|await|breakpoint|throw)\\b"
|
||||
},
|
||||
{
|
||||
"name": "keyword.crosslang",
|
||||
|
||||
Reference in New Issue
Block a user