diff --git a/Tesses.CrossLang.Shell/src/build.tcross b/Tesses.CrossLang.Shell/src/build.tcross new file mode 100644 index 0000000..ccb912b --- /dev/null +++ b/Tesses.CrossLang.Shell/src/build.tcross @@ -0,0 +1,48 @@ +func Tesses.CrossLang.Shell.Build(dd) +{ + var offline=false; + var allowFullCompTime=false; + var buildPath = "."; + if(dd.Arguments.Count > 1) + { + buildPath = dd.Arguments[1]; + } + each(var flag : dd.Flags) + { + if(flag == "offline") + { + offline = true; + } + if(flag == "allow-insecure-comptime") + { + allowFullCompTime=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("allow-insecure-comptime: Allow full comptime"); + 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.AllowFullCompTime = allowFullCompTime; + bt.BuildProject(buildPath); + +} \ No newline at end of file diff --git a/Tesses.CrossLang.Shell/src/debug.tcross b/Tesses.CrossLang.Shell/src/debug.tcross new file mode 100644 index 0000000..fbabcab --- /dev/null +++ b/Tesses.CrossLang.Shell/src/debug.tcross @@ -0,0 +1,197 @@ +func Tesses.CrossLang.Shell.Debug(dd) +{ + 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 debug [run-flags-and-options] program-arguments..."); + Console.WriteLine("USAGE: crosslang debug [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.RegisterOnError((ctx)=>{ + if(ctx.IsBreakpoint) + { + Console.WriteLine($"Breakpoint {ctx.Breakpoint.Data} hit at: {ctx.Breakpoint.Filename}:{ctx.Breakpoint.Line}"); + } + else if(TypeOf(ctx.Exception) == "Dictionary") + { + Console.WriteLine($"Exception at: {ctx.Exception.Filename}:{ctx.Exception.Line}"); + Console.WriteLine(ctx.Exception); + } + else { + Console.WriteLine("thrown {ctx.Exception}"); + } + GC.BarrierBegin(); + while(true) + { + Console.Write("dbg> "); + var input = Console.ReadLine(); + if(input == "continue") + { + break; + } + else if(input.StartsWith("getvar ")) + { + var varName = input.Substring(7); + var val = ctx.Environment.GetVariable(varName); + Console.Write($"{TypeOf(val)} "); + if(TypeIsString(val)) + Console.WriteLine(val.Escape()); + else + Console.WriteLine(val); + } + else if(input.StartsWith("eval ")) + { + var evalText = input.Substring(5); + ctx.Environment.Eval(evalText); + } + else if(input == "lsroot") + { + var root = ctx.Environment.GetRootEnvironment(); + func printItems(r,name) + { + each(var item : Dictionary.Items(r)) + { + switch(TypeOf(item.Value)) + { + case "Dictionary": + printItems(item.Value,$"{name}{item.Key}."); + break; + case "String": + Console.WriteLine($"{name}{item.Key} = {item.Value.Escape()}"); + break; + case "Closure": + case "ExternalMethod": + if(item.Value.documentation.Length > 0) + { + Console.WriteLine($"/^{item.Value.Documentation}^/"); + + } + { + Console.Write($"func {name}{item.Key}("); + var first=true; + each(var arg : item.Value.Arguments) + { + if(!first) Console.Write($", {arg}"); + else + Console.Write(arg); + first=false; + } + + Console.WriteLine(")"); + } + break; + default: + Console.Write($"{name}{item.Key} = "); + Console.WriteLine(item.Value); + break; + } + } + } + + printItems(root.GetDictionary(),""); + } + else if(input == "lsvar") + { + var curVersion = ctx.Environment; + + + Console.WriteLine("======================"); + while(TypeOf(curVersion) != "RootEnvironment") + { + each(var item : Dictionary.Items(curVersion.GetDictionary())) + { + Console.Write($"{TypeOf(item.Value)} {item.Key} = "); + if(TypeIsString(item.Value)) + Console.WriteLine(item.Value.Escape(true)); + else + Console.WriteLine(item.Value); + } + + curVersion = curVersion.GetParentEnvironment(); + + Console.WriteLine("======================"); + } + } + else if(input == "help") + { + Console.WriteLine("getvar : prints variable"); + Console.WriteLine("eval : eval code in environment"); + Console.WriteLine("lsvar: get variables (not root environment)"); + Console.WriteLine("lsroot: get variables on root environment"); + Console.WriteLine("continue: continue executing"); + } + + } + GC.BarrierEnd(); + return ctx.IsBreakpoint; + }); + env.RegisterEverything(); + env.LockRegister(); + + env.LoadFileWithDependencies(FS.Local,output); + var myArgs = [output.ToString()]; + for(var i = 1; i < dd.Arguments.Count; i++) + { + myArgs.Add(dd.Arguments[i]); + } + + return env.GetDictionary().main(myArgs); +} \ No newline at end of file diff --git a/Tesses.CrossLang.Shell/src/default.tcross b/Tesses.CrossLang.Shell/src/default.tcross new file mode 100644 index 0000000..18cdcc8 --- /dev/null +++ b/Tesses.CrossLang.Shell/src/default.tcross @@ -0,0 +1,22 @@ +func Tesses.CrossLang.Shell.Default(dd) +{ + 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"); + Console.WriteLine("update-shell: update the shell"); //this command is handled by runtime so we don't have to implement it here + return 0; +} \ No newline at end of file diff --git a/Tesses.CrossLang.Shell/src/new.tcross b/Tesses.CrossLang.Shell/src/new.tcross new file mode 100644 index 0000000..18f27ce --- /dev/null +++ b/Tesses.CrossLang.Shell/src/new.tcross @@ -0,0 +1,125 @@ +func Tesses.CrossLang.Shell.New(dd) +{ + func newHelp() + { + Console.WriteLine($"crosslang new [FLAGS] [directory_for_project]"); + Console.WriteLine("FLAGS"); + Console.WriteLine("--help: Shows this help"); + Console.WriteLine("--list: Lists all templates"); + Console.WriteLine("--list-json: List all templates (as json)"); + 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 = Env.CrossLangConfig / "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 == "list-json") + { + var items = []; + each(var item : FS.Local.EnumeratePaths(dir)) + { + items.Add(Tesses.CrossLang.GetNameAndDescriptionJson(item)); + } + Console.WriteLine(items); + 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 = new 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 = []; + + func mutateDir(dir) + { + each(var f : projectDir.EnumeratePaths(dir)) + { + if(projectDir.RegularFileExists(f) && f.GetExtension() == ".tcross") + { + filesToMutate.Add(f); + } + else if(projectDir.DirectoryExists(f)) + { + mutateDir(f); + } + } + } + mutateDir(srcDir); + + each(var ent : filesToMutate) + { + if(projectDir.RegularFileExists(ent)) + { + var src = FS.ReadAllText(projectDir, ent); + + src = src.Replace("%PROJECT_NAME%",projectPath.GetFileName()); + 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; + } + } +} diff --git a/Tesses.CrossLang.Shell/src/run.tcross b/Tesses.CrossLang.Shell/src/run.tcross new file mode 100644 index 0000000..fb4ec3e --- /dev/null +++ b/Tesses.CrossLang.Shell/src/run.tcross @@ -0,0 +1,85 @@ +func Tesses.CrossLang.Shell.Run(dd) +{ + var offline=false; + var buildPath = "."; + var nobuild=false; + var allowFullCompTime=false; + var output=""; + each(var flag : dd.Flags) + { + if(flag == "offline") + { + offline = true; + } + else if(flag == "allow-insecure-comptime") + { + allowFullCompTime=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("allow-insecure-comptime: Allow full comptime"); + Console.WriteLine("nobuild: don't build, just run"); + 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("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; + bt.AllowFullCompTime = allowFullCompTime; + output = bt.BuildProject(buildPath).Output; + } + var env = VM.CreateEnvironment({}); + env.RegisterEverything(); + env.LockRegister(); + + env.LoadFileWithDependencies(FS.Local,output); + var myArgs = [output.ToString()]; + for(var i = 1; i < dd.Arguments.Count; i++) + { + myArgs.Add(dd.Arguments[i]); + } + return env.GetDictionary().main(myArgs); +} \ No newline at end of file diff --git a/Tesses.CrossLang.Shell/src/s b/Tesses.CrossLang.Shell/src/s new file mode 100644 index 0000000..d05a567 --- /dev/null +++ b/Tesses.CrossLang.Shell/src/s @@ -0,0 +1,424 @@ + + + else if(commandName == "install-console") + { + //crosslang install-console ConsoleApp --version=1.0.0.0-prod [--outdir=DIR] + } + 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 + } + + if(commandName == "install-tool") + { + //crosslang install-tool Tesses.CrossLang.Tool.SomeTool --version=1.0.0.0-prod + var toolsDir = Env.CrossLangConfig / "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 = Env.CrossLangConfig / "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 + + if(dd.Arguments.Length > 1) + { + + var name = dd.Arguments[1]; + var version = null; + each(var opt : dd.Options) + { + if(opt.Key == "version") + version = opt.Value; + } + if(!FS.Local.FileExists("cross.json")) + { + Console.WriteLine("The current directory does not have a project"); + return 1; + } + + if(version == null) + { + var pm = Tesses.CrossLang.PackageManager(); + version = pm.GetLatest(name); + } + if(version == null) + { + Console.WriteLine("Could not get version"); + return 1; + } + else + { + var data = Json.Decode(FS.ReadAllText(FS.Local,"cross.json")); + if(TypeOf(data.dependencies) != "List") data.dependencies=[]; + data.dependencies.Add({name,version}); + FS.WriteAllText(FS.Local,"cross.json",Json.Encode(data,true)); + } + } + + } + else if(commandName == "upload-package") + { + //crosslang upload-package [--host=HOST --token=TOKEN] [--session=NAME] [PACKAGE_FILE] + var host=null; + var token=null; + var session=null; + var package=null; + var nobuild=false; + each(var option : dd.Options) + { + if(option.Key == "host") + { + host = option.Value; + } + if(option.Key == "token") + { + token = option.Value; + } + if(option.Key == "session") + { + session = option.Value; + } + } + if(dd.Arguments.Length > 1) + { + package = dd.Arguments[1]; + } + else { + if(nobuild) + { + throw {Type="NotImplementedException", Message="nobuild on upload-package is not implemented",ToString=(this)=>$"{this.Type} on line: {this.Line}: {this.Message}"}; + } + else { + + var pm = Tesses.CrossLang.PackageManager(); + pm.Offline = false; + var bt = Tesses.CrossLang.BuildTool(pm); + bt.Config = ""; + bt.AllowFullCompTime = false; + package = bt.BuildProject(".").Output; + } + } + + if(TypeOf(host) != "String" || TypeOf(token) != "String") + { + if(FS.Local.FileExists(Env.CrossLangConfig / "auth.json")) + { + var json = Json.Decode(FS.ReadAllText(FS.Local,Env.CrossLangConfig / "auth.json")); + if(json.Length == 0) + { + Console.WriteLine("The auth.json file is empty, use crosslang login to login"); + return 1; + } + else if(json.Length == 1) + { + host = json[0].host; + token = json[0].token; + } + else { + if(TypeOf(session) != "String") + { + Console.WriteLine("Multiple entries in auth.json file, session is ambiguous."); + Console.WriteLine("Sessions:"); + each(var item : json) + { + Console.WriteLine($"{item.name}: {item.host}"); + } + return 1; + } + else { + var found=false; + each(var item : json) + { + if(item.name == session) + { + found=true; + host = item.host; + token = item.token; + break; + } + } + if(!found) { + Console.WriteLine($"Could not find session with name: {session}"); + return 1; + } + } + } + } + else { Console.WriteLine("No auth.json file, use crosslang login to login"); return 1;} + } + + if(TypeOf(host) != "String" || TypeOf(token) != "String") + { + Console.WriteLine("You are not logged in, use crosslang login to login"); + return 1; + } + var strm = FS.Local.OpenFile(package,"rb"); + if(strm == null) + { + Console.WriteLine("Could not open file"); + return 1; + } + var req = { + Method="PUT", + RequestHeaders = [ + {Key= "Authorization",Value=$"Bearer {token}"} + ], + Body = Net.Http.StreamHttpRequestBody(strm,"application/crvm") + }; + var http = Net.Http.MakeRequest($"{host.TrimEnd('/')}/api/v1/upload",req); + + + if(http.StatusCode == 204) + { + Console.WriteLine("Uploaded package successfully"); + } + else if(http.ResponseHeaders.TryGetFirst("Content-Type") == "application/json") + { + var json = Json.Decode(http.ReadAsString()); + Console.WriteLine($"Failed to upload package, {json.reason.TrimEnd('.')}."); + } + else { + Console.WriteLine($"Failed to upload package."); + } + strm.Close(); + } + else if(commandName == "login") + { + //crosslang login local https://cpkg.tesseslanguage.com/ + //crosslang login [NAME] [HOST] [TOKEN] + + } + else if(commandName == "configdir") + { + Console.WriteLine(Env.CrossLangConfig); + } \ No newline at end of file