-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
411 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
package server | ||
|
||
import ( | ||
"bytes" | ||
"embed" | ||
"fmt" | ||
"html/template" | ||
"net/http" | ||
"sort" | ||
"strings" | ||
|
||
. "github.com/criteo/command-launcher/internal/backend" | ||
"github.com/criteo/command-launcher/internal/command" | ||
) | ||
|
||
type Server struct { | ||
backend *Backend | ||
} | ||
|
||
//go:embed static | ||
var fs embed.FS | ||
|
||
//go:embed templates | ||
var templates embed.FS | ||
|
||
func (server *Server) IndexHandler(w http.ResponseWriter, r *http.Request) { | ||
index, _ := fs.ReadFile("static/index.html") | ||
w.Write(index) | ||
} | ||
|
||
type Command struct { | ||
FullName string | ||
Group string | ||
Name string | ||
Package string | ||
Registry string | ||
Short string | ||
Long string | ||
Examples []command.ExampleEntry | ||
Flags []command.Flag | ||
SubCmds []*Command | ||
} | ||
|
||
type CommandIndex struct { | ||
Commands []*Command | ||
} | ||
|
||
func (server *Server) CommandIndexHandler(w http.ResponseWriter, r *http.Request) { | ||
repos := (*(server.backend)).AllRepositories() | ||
cmdMap := map[string]*Command{} | ||
|
||
for _, repo := range repos { | ||
pkgs := repo.InstalledPackages() | ||
for _, pkg := range pkgs { | ||
cmds := pkg.Commands() | ||
for _, cmd := range cmds { | ||
if cmd.Name() == "__setup__" { | ||
continue | ||
} | ||
if cmd.Group() == "" { // this is top level command | ||
// add group command | ||
if groupCmd, ok := cmdMap[cmd.FullName()]; !ok { | ||
groupCmd = &Command{ | ||
FullName: cmd.FullName(), | ||
Group: cmd.Group(), | ||
Name: cmd.Name(), | ||
Package: pkg.Name(), | ||
Registry: repo.Name(), | ||
SubCmds: []*Command{}, | ||
} | ||
cmdMap[cmd.FullName()] = groupCmd | ||
} | ||
} else { // this is a sub command | ||
// get the group command full name | ||
groupCmdFullName := fmt.Sprintf("%s@@%s@%s", cmd.Group(), pkg.Name(), repo.Name()) | ||
if groupCmd, ok := cmdMap[groupCmdFullName]; !ok { | ||
groupCmd = &Command{ | ||
FullName: groupCmdFullName, | ||
Group: "", | ||
Name: cmd.Group(), | ||
Package: pkg.Name(), | ||
Registry: repo.Name(), | ||
SubCmds: []*Command{ | ||
&Command{ | ||
FullName: cmd.FullName(), | ||
Group: cmd.Group(), | ||
Name: cmd.Name(), | ||
Package: pkg.Name(), | ||
Registry: repo.Name(), | ||
SubCmds: []*Command{}, | ||
}, | ||
}, | ||
} | ||
cmdMap[groupCmdFullName] = groupCmd | ||
} else { | ||
groupCmd.SubCmds = append(groupCmd.SubCmds, &Command{ | ||
FullName: cmd.FullName(), | ||
Group: cmd.Group(), | ||
Name: cmd.Name(), | ||
Package: pkg.Name(), | ||
Registry: repo.Name(), | ||
SubCmds: []*Command{}, | ||
}) | ||
} | ||
|
||
} | ||
} | ||
} | ||
} | ||
|
||
// load the template | ||
tmpl_text, _ := templates.ReadFile("templates/cmd_index.html") | ||
tmpl, _ := template.New("command_index").Parse(string(tmpl_text)) | ||
|
||
groups := make([]*Command, 0, len(cmdMap)) | ||
for _, cmd := range cmdMap { | ||
groups = append(groups, cmd) | ||
} | ||
|
||
sort.Slice(groups, func(i, j int) bool { | ||
// return fmt.Sprintf("%s@%s", groups[i].Package, groups[i].Registry) < fmt.Sprintf("%s@%s", groups[j].Package, groups[j].Registry) | ||
return groups[i].FullName < groups[j].FullName | ||
}) | ||
|
||
var tpl bytes.Buffer | ||
tmpl.Execute(&tpl, CommandIndex{Commands: groups}) | ||
|
||
html_wrapper, _ := templates.ReadFile("templates/html_wrapper.html") | ||
content := strings.ReplaceAll(string(html_wrapper), "#INPUT#", tpl.String()) | ||
w.Write([]byte(content)) | ||
} | ||
|
||
func (server *Server) CommandHandler(w http.ResponseWriter, r *http.Request) { | ||
fullName := strings.TrimPrefix(r.URL.Path, "/command/") | ||
fmt.Println(r.URL.Path, fullName) | ||
cmd, _ := (*(server.backend)).FindCommandByFullName(fullName) | ||
|
||
tmpl_text, _ := templates.ReadFile("templates/command.html") | ||
tmpl, _ := template.New("command").Parse(string(tmpl_text)) | ||
command := Command{ | ||
FullName: cmd.FullName(), | ||
Group: cmd.Group(), | ||
Name: cmd.Name(), | ||
Package: cmd.PackageName(), | ||
Registry: cmd.RepositoryID(), | ||
Short: cmd.ShortDescription(), | ||
Long: cmd.LongDescription(), | ||
Examples: cmd.Examples(), | ||
Flags: cmd.Flags(), | ||
} | ||
|
||
tmpl.Execute(w, command) | ||
} | ||
|
||
func (server *Server) HealthHandler(w http.ResponseWriter, r *http.Request) { | ||
w.Write([]byte("OK")) | ||
} | ||
|
||
// Implement the serve funcation in default backend | ||
func Serve(backend *Backend, port int) error { | ||
server := Server{backend: backend} | ||
|
||
http.HandleFunc("/", server.CommandIndexHandler) | ||
http.HandleFunc("/test", server.CommandIndexHandler) | ||
http.HandleFunc("/command/", server.CommandHandler) | ||
http.HandleFunc("/health", server.HealthHandler) | ||
return http.ListenAndServe(fmt.Sprintf(":%d", port), nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Command Launcher</title> | ||
<link rel="stylesheet" href="https://unpkg.com/mvp.css"> | ||
</head> | ||
<body> | ||
<main> | ||
<nav> | ||
<ul> | ||
<li><a href="/">Commands</a></li> | ||
<li>Registries</li> | ||
<li>Packages</li> | ||
</ul> | ||
</nav> | ||
<article> | ||
<h1>Index</h1> | ||
<div> | ||
<b>moab:</b> | ||
<a href="#moab-init">init</a> | ||
<a href="#moab-build">build</a> | ||
</div> | ||
<div> | ||
<b>doc:</b> | ||
<a href="#moab-init">html</a> | ||
<a href="#moab-build">confluence</a> | ||
</div> | ||
</article> | ||
|
||
<article> | ||
<command> | ||
<hr> | ||
<h2 id="moab-init">moab init <a href="#moab-init" style="text-decoration:none">🔗</a></h2> | ||
<p><sup>full name:init@moab@moab@dropin</sup><sup>package:moab</sup><sup>registry:dropin</sup></p> | ||
<p>Initiate a moab workspace</p> | ||
<details> | ||
<summary>Examples</summary> | ||
<div> | ||
<h4>Initiate a java moab workspace and checkout one repository</h4> | ||
<pre><samp>moab init java software-factory/example-projects</samp></pre> | ||
</div> | ||
</details> | ||
<details> | ||
<summary>Try it out</summary> | ||
<form> | ||
<label for="work-dir">work directory<sup>required</sup></label> | ||
<label><small><em>Which directory the command will run from</em></small></label> | ||
<input id="work-dir" type="text" name="work-dir" value="/Users/b.hou/.cdt"> | ||
|
||
<label for="moab-name">moab name<sup>required</sup></label> | ||
<label><small><em>MOAB name: java or csharp</em></small></label> | ||
<input id="moab-name" type="text" name="moab-name" value="java"> | ||
<label for="args">repositories</label> | ||
<label><small><em>repositories to checkout</em></small></label> | ||
<textarea id="args" name="args" rows="4" cols="50"></textarea> | ||
<label for="exclude-ide">exclude-ide</label> | ||
<label><small><em>do not prepare ide</em></small></label> | ||
<input id="exclude-ide" type="checkbox" name="exclude-ide"><b>enable</b></input> | ||
<br> | ||
<button type="submit">Run</button> | ||
</form> | ||
<div>Output</div> | ||
<pre><samp> | ||
npm install -g @command-launcher/cli | ||
another line | ||
$ls -la | ||
. | ||
.. | ||
.git | ||
</samp></pre> | ||
</details> | ||
</command> | ||
<command> | ||
<hr> | ||
<h2 id="moab-build">moab build</h2> | ||
<p><sup>package:moab</sup><sup>registry:dropin</sup></p> | ||
<p>Build all the projects in current folder</p> | ||
<details> | ||
<summary>Examples</summary> | ||
<div> | ||
<h4>Initiate a java moab workspace and checkout one repository</h4> | ||
<pre><samp>moab init java software-factory/example-projects</samp></pre> | ||
</div> | ||
</details> | ||
<details> | ||
<summary>Try it out</summary> | ||
<form> | ||
<label for="moab-name">moab name<sup>required</sup></label> | ||
<input id="moab-name" type="text" name="moab-name" value="java"> | ||
<label for="args">repositories</label> | ||
<textarea id="args" name="args" rows="4" cols="50"></textarea> | ||
<input id="exclude-ide" type="checkbox" name="exclude-ide"><b>exclude-ide</b></input> | ||
<br> | ||
<button type="submit">Run</button> | ||
</form> | ||
<div>Output</div> | ||
<pre><samp> | ||
npm install -g @command-launcher/cli | ||
another line | ||
$ls -la | ||
. | ||
.. | ||
.git | ||
</samp></pre> | ||
</details> | ||
</command> | ||
</article> | ||
</main> | ||
<footer> | ||
</footer> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<article> | ||
<h1>Index</h1> | ||
{{range .Commands}} | ||
<div> | ||
<sup>Registry: {{.Registry}}</sup><sup>Package: {{.Package}}</sup><br><br> | ||
<a href="/command/{{.FullName}}">{{.Group}} {{.Name}}</a><br> | ||
{{range .SubCmds}} | ||
<a href="/command/{{.FullName}}">{{.Group}} {{.Name}}</a><br> | ||
{{end}} | ||
<br><br> | ||
</div> | ||
{{end}} | ||
</article> |
Oops, something went wrong.