Files
crosslangextras/Tesses.CrossLang.Shell/src/main.tcross
2025-03-28 22:11:17 -05:00

531 lines
20 KiB
Plaintext

func main(args)
{
var dd = Tesses.CrossLang.Args(args);
if(dd.Arguments.Count > 0)
{
var commandName = dd.Arguments[0];
if(commandName == "args")
{
each(var arg : dd.Arguments)
{
Console.WriteLine(arg);
}
}
else if(commandName == "build")
{
var offline=false;
var buildPath = ".";
if(dd.Arguments.Count > 1)
{
buildPath = dd.Arguments[1];
}
each(var flag : dd.Flags)
{
if(flag == "offline")
{
offline = true;
}
if(flag == "help")
{
Console.WriteLine("USAGE: crosslang build [build-flags-and-options]");
Console.WriteLine("FLAGS:");
Console.WriteLine("offline: build with no internet (don't fetch files)");
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;
}
}
var conf = "";
each(var option : dd.Options)
{
if(option.Key == "conf")
{
conf = option.Value;
}
}
var pm = Tesses.CrossLang.PackageManager();
pm.Offline = offline;
var bt = Tesses.CrossLang.BuildTool(pm);
bt.Config = conf;
bt.BuildProject(buildPath);
}
else if(commandName == "run")
{
var offline=false;
var buildPath = ".";
var nobuild=false;
var output="";
each(var flag : dd.Flags)
{
if(flag == "offline")
{
offline = true;
}
else if(flag == "help")
{
Console.WriteLine("USAGE: crosslang run [run-flags-and-options] program-arguments...");
Console.WriteLine("USAGE: crosslang run [run-flags-and-options] -- program-arguments-and-options...");
Console.WriteLine("FLAGS:");
Console.WriteLine("offline: build with no internet (don't fetch files)");
Console.WriteLine("help: this help");
Console.WriteLine("nobuild: don't build, just run");
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("config.json"))
{
var proj = Json.Decode(FS.ReadAllText(FS.Local, "config.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 = Tesses.CrossLang.PackageManager();
pm.Offline = offline;
var bt = Tesses.CrossLang.BuildTool(pm);
bt.Config = conf;
output = bt.BuildProject(buildPath).Output;
}
var env = VM.CreateEnvironment({});
env.RegisterEverything();
env.LockRegister();
env.LoadFileWithDependencies(FS.Local,output);
var myArgs = [output];
for(var i = 1; i < dd.Arguments.Count; i++)
{
myArgs.Add(dd.Arguments[i]);
}
return env.GetDictionary().main(myArgs);
}
else if(commandName == "new")
{
func newHelp()
{
Console.WriteLine($"crosslang new [FLAGS] <template_name> [directory_for_project]");
Console.WriteLine("FLAGS");
Console.WriteLine("--help: Shows this help");
Console.WriteLine("--list: Lists all templates");
Console.WriteLine("ARGUMENTS:");
Console.WriteLine("template_name: The name of the template");
Console.WriteLine("directory_for_project: The directory for the project, defaults to current directory");
}
var dir = FS.MakeFull(Env.Config) / "Tesses" / "CrossLang" / "Templates";
each(var flag : dd.Flags)
{
if(flag == "list")
{
Console.WriteLine("List of templates:");
each(var item : FS.Local.EnumeratePaths(dir))
{
Console.WriteLine(Tesses.CrossLang.GetNameAndDescription(item));
}
return 0;
}
else if(flag == "help")
{
newHelp();
return 1;
}
}
if(dd.Arguments.Count < 2)
{
newHelp();
return 1;
}
else
{
var templateFile = dir / $"{dd.Arguments[1]}.crvm";
if(FS.Local.RegularFileExists(templateFile))
{
var projectPath = ".";
if(dd.Arguments.Count > 2) projectPath = dd.Arguments[2];
projectPath = FS.MakeFull(projectPath);
FS.Local.CreateDirectory(projectPath);
var projectDir = FS.SubdirFilesystem(FS.Local, projectPath);
var strm = FS.Local.OpenFile(templateFile,"rb");
var res = FS.ExtractArchive(strm,projectDir);
strm.Close();
if(!projectDir.RegularFileExists("/cross.json"))
{
Console.WriteLine("Could not find /cross.json in template");
return 1;
}
var jsonText = FS.ReadAllText(projectDir, "/cross.json");
var proj = Json.Decode(jsonText);
proj.name = projectPath.GetFileName();
proj.version = "1.0.0.0-prod";
var old_info = proj.info;
proj.info = old_info.template_info;
proj.dependencies = old_info.template_project_dependencies;
var srcDir = proj.source_directory;
if(TypeOf(srcDir) == "Undefined") srcDir = "/src";
var filesToMutate = old_info.template_extra_text_ftles;
if(TypeOf(filesToMutate) == "Undefined") filesToMutate = [];
each(var f : projectDir.EnumeratePaths(srcDir))
{
if(projectDir.RegularFileExists(f) && f.GetExtension() == ".tcross")
{
filesToMutate.Add(f);
}
}
each(var ent : filesToMutate)
{
if(projectDir.RegularFileExists(ent))
{
var src = FS.ReadAllText(projectDir, ent);
var src = src.Replace("%PROJECT_NAME%",projectPath.GetFileName());
var src = src.Replace("%TEMPLATE_PROJECT_NAME%","%PROJECT_NAME");
FS.WriteAllText(projectDir, ent, src);
}
}
FS.WriteAllText(projectDir, "/cross.json", Json.Encode(proj,true));
projectDir.Close();
return 0;
}
else
{
Console.WriteLine($"Error could not find template {templateFile}");
return 1;
}
}
}
else if(commandName == "install-console")
{
//crosslang install-console
}
else if(commandName == "install-app")
{
//crosslang install-app
}
else if(commandName == "install-template")
{
//crosslang install-template Tesses.CrossLang.Template.Console --version=1.0.0.0-prod
}
else if(commandName == "install-tool")
{
//crosslang install-tool Tesses.CrossLang.Tool.SomeTool --version=1.0.0.0-prod
var toolsDir = Path.FromString(Env.Config) / "Tesses" / "CrossLang" / "Tools";
var offline=false;
var buildPath = ".";
var nobuild=false;
var output=.;
each(var flag : dd.Flags)
{
if(flag == "offline")
{
offline = true;
}
else if(flag == "help")
{
Console.WriteLine("USAGE: crosslang install-tool [flags-and-options]");
Console.WriteLine("USAGE: crosslang install-tool [PackageName] [flags-and-options]");
Console.WriteLine("FLAGS:");
Console.WriteLine("offline: build with no internet (don't fetch files)");
Console.WriteLine("help: this help");
Console.WriteLine("nobuild: don't build, just install (irrelevant if you specify a PackageName)");
Console.WriteLine();
Console.WriteLine("OPTIONS:");
Console.WriteLine("conf=CONFIGSTRING: specify a conf string for compile_tool(s), is the property Config (irrelevant if you specify a PackageName)");
Console.WriteLine("version=1.0.0.0-prod: specify the package version (irrelevant if you don't specify a PackageName)");
Console.WriteLine();
Console.WriteLine("ARGUMENTS:");
Console.WriteLine("PackageName: the package name of a tool you want to download and install, if not specified we install the tool from the current directory");
return 0;
}
else if(flag == "nobuild")
{
nobuild=true;
}
}
if(dd.Arguments.Length == 1)
{
var conf = "";
each(var option : dd.Options)
{
if(option.Key == "conf")
{
conf = option.Value;
}
}
if(FS.Local.FileExists("cross.json"))
{
var proj = Json.Decode(FS.ReadAllText(FS.Local,"cross.json"));
var name = TypeOf(proj.info.toolname) == "String" ? proj.info.toolname : proj.name;
if(proj.info.type != "tool")
{
Console.WriteLine("The project is not a tool");
return 1;
}
if(TypeOf(name) != "String")
{
Console.WriteLine("The tool does not have a name");
return 1;
}
var toolDir = toolsDir / name;
FS.Local.CreateDirectory(toolDir);
var toolFile = toolDir / name + ".crvm";
if(nobuild)
{
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.");
return 1;
}
}
else
{
var pm = Tesses.CrossLang.PackageManager();
pm.Offline = offline;
var bt = Tesses.CrossLang.BuildTool(pm);
bt.Config = conf;
output = bt.BuildProject(buildPath).Output;
}
func CopyCRVM(src,dest)
{
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();
Console.WriteLine($"{src} -> {dest}");
}
if(FS.Local.FileExists(dest)) return;
copyFile(src,dest);
var srcStrm = FS.Local.OpenFile(src,"rb");
var crvm = VM.LoadExecutable(srcStrm);
srcStrm.Close();
each(var dep : crvm.Dependencies)
{
var name = $"{dep.Name}-{dep.Version.ToString()}.crvm";
CopyCRVM(src.GetParent()/name, dest.GetParent()/name);
}
}
CopyCRVM(output,toolFile);
return 0;
}
else
{
Console.WriteLine("The current directory does not have a project");
return 1;
}
}
}
else if(commandName == "console")
{
//crosslang console myfavoriteapp
}
else if(commandName == "tool")
{
var dir = FS.MakeFull(Env.Config) / "Tesses" / "CrossLang" / "Tools";
if(dd.Arguments.Length == 1)
{
Console.WriteLine("List of tools:");
each(var item : FS.Local.EnumeratePaths(dir))
{
Console.WriteLine(Tesses.CrossLang.GetNameAndDescription(item / item.GetFileName() + ".crvm"));
}
return 0;
}
}
else if(commandName == "tool-test")
{
var pm = Tesses.CrossLang.PackageManager();
pm.Offline = false;
var bt = Tesses.CrossLang.BuildTool(pm);
var proj=bt.BuildProject(".");
var output = proj.Output;
var env = VM.CreateEnvironment({});
env.RegisterEverything();
env.LockRegister();
env.LoadFileWithDependencies(FS.Local,output);
var myArgs = [];
for(var i = 1; i < dd.Arguments.Count; i++)
{
myArgs.Add(dd.Arguments[i]);
}
return env.GetDictionary().RunTool({
Arguments=myArgs,
Options = dd.Options,
Flags = dd.Flags,
ToolName = proj.Info.toolname
});
}
else if(commandName == "add-project")
{
//crosslang add-project /path/to/project
if(dd.Arguments.Count > 1)
{
var dep = dd.Arguments[1];
if(FS.Local.DirectoryExists(dep))
{
var path = Path.FromString(dep) / "cross.json";
var pathStr = FS.MakeFull(dep).CollapseRelativeParents().ToString();
if(FS.Local.FileExists(path))
{
if(FS.Local.FileExists("cross.json"))
{
var f = FS.ReadAllText(FS.Local,"cross.json");
var json = Json.Decode(f);
if(TypeOf(json.project_dependencies) == "List")
{
each(var item : json.project_dependencies)
{
var _path = FS.MakeFull(item).CollapseRelativeParents().ToString();
if(_path == pathStr)
{
Console.WriteLine($"The project {dep} already exists in cross.json.");
return 0;
}
}
json.project_dependencies.Add(dep);
}
else
{
json.project_dependencies = [dep];
}
Console.WriteLine($"Added project {dep} to cross.json.");
FS.WriteAllText(FS.Local, "cross.json", Json.Encode(json,true));
return 0;
}
else
{
Console.WriteLine("The current directory does not have a project");
return 1;
}
}
else
{
Console.WriteLine($"The project file {path} does not exist");
return 1;
}
}
else
{
Console.WriteLine("The project directory does not exist");
return 1;
}
}
return 1;
}
else if(commandName == "add-dependency")
{
//crosslang add-dependency Tesses.CrossLang.Markup --version=1.0.0.0-prod
}
else if(commandName == "upload-package")
{
//crosslang upload-package [PACKAGE_NAME]
}
else if(commandName == "configdir")
{
Console.WriteLine(Tesses.CrossLang.ConfigDir);
}
}
else
{
each(var flag : dd.Flags)
{
if(flag == "version")
{
Console.WriteLine($"VM version: {VM.RuntimeVersion}");
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}");
return 0;
}
}
Console.WriteLine($"USAGE: crosslang COMMAND [command-arguments]");
Console.WriteLine("COMMANDS:");
Console.WriteLine("new: create new project");
Console.WriteLine("build: build a project");
Console.WriteLine("run: run a project");
Console.WriteLine("configdir: print the config directory");
return 0;
}
return 0;
}