mirror of
https://github.com/NotAShelf/nix-evaluator-stats.git
synced 2026-05-08 08:25:13 +00:00
add cli
This commit is contained in:
parent
5af2457177
commit
7697319a4d
11 changed files with 76 additions and 103 deletions
2
cli/.gitignore
vendored
Normal file
2
cli/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
dist/
|
||||||
|
cli
|
||||||
3
cli/go.mod
Normal file
3
cli/go.mod
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
module cli
|
||||||
|
|
||||||
|
go 1.26.1
|
||||||
53
cli/main.go
Normal file
53
cli/main.go
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
b64 "encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"log"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
_ "embed"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed all:dist
|
||||||
|
var website embed.FS
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
fileOrStringArgs := os.Args[1:]
|
||||||
|
if len(fileOrStringArgs) != 1 {
|
||||||
|
log.Fatal("To many Arguments Provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
fileOrString := fileOrStringArgs[0]
|
||||||
|
var base64 string
|
||||||
|
if _, err := os.Stat(fileOrString); err == nil {
|
||||||
|
|
||||||
|
data, err := os.ReadFile(fileOrString)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to read File", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
base64 = b64.StdEncoding.EncodeToString(data)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
base64 = b64.StdEncoding.EncodeToString([]byte(fileOrString))
|
||||||
|
}
|
||||||
|
public, err := fs.Sub(website, "dist")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fs := http.FileServerFS(public)
|
||||||
|
http.Handle("/", fs)
|
||||||
|
|
||||||
|
port := 10000 + rand.Intn(55000)
|
||||||
|
fmt.Printf("Stats available at http://localhost:%d/?file=%s\n", port, base64)
|
||||||
|
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(port), nil))
|
||||||
|
}
|
||||||
|
|
@ -66,6 +66,12 @@ analysis you may compare two _named_ analyses at a time.
|
||||||
> UI bugs or areas where UI polish is very clearly missing. Please crate an
|
> UI bugs or areas where UI polish is very clearly missing. Please crate an
|
||||||
> issue if the generated graph or the site UI looks off. Thanks :)
|
> issue if the generated graph or the site UI looks off. Thanks :)
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
1. Create the JSON export or display the text in terminal and pass it into the cli
|
||||||
|
|
||||||
|
Kongratz it creates a Temp server with a link to ur benchmark visualization
|
||||||
|
|
||||||
#### Snapshots
|
#### Snapshots
|
||||||
|
|
||||||
Snapshots are an "experimental" (just means they're new and unpolished) feature
|
Snapshots are an "experimental" (just means they're new and unpolished) feature
|
||||||
|
|
@ -90,6 +96,9 @@ $ pnpm run dev
|
||||||
|
|
||||||
# Build a static site
|
# Build a static site
|
||||||
$ pnpm run build
|
$ pnpm run build
|
||||||
|
|
||||||
|
# Build the cli
|
||||||
|
$ pnpm run build:cli
|
||||||
```
|
```
|
||||||
|
|
||||||
If submitting pull requests, please ensure that format (`pnpm run fmt`) and lint
|
If submitting pull requests, please ensure that format (`pnpm run fmt`) and lint
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
"fmt": "prettier --write .",
|
"fmt": "prettier --write .",
|
||||||
"build": "pnpm -r --filter '!@ns/web' build && pnpm -F @ns/web build",
|
"build": "pnpm -r --filter '!@ns/web' build && pnpm -F @ns/web build",
|
||||||
"build:web": "pnpm -r --filter '!@ns/web' build && pnpm -F @ns/web build",
|
"build:web": "pnpm -r --filter '!@ns/web' build && pnpm -F @ns/web build",
|
||||||
|
"build:cli": "pnpm run build && cp -r packages/web/dist cli/dist && go build -o cli/cli cli/main.go",
|
||||||
"preview": "pnpm -F @ns/web preview"
|
"preview": "pnpm -F @ns/web preview"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# @ns/tui
|
|
||||||
|
|
||||||
Provides a terminal-based interface for viewing and analyzing Nix evaluator
|
|
||||||
statistics.
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@ns/tui",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"type": "module",
|
|
||||||
"bin": {
|
|
||||||
"ns-tui": "./dist/cli.js"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"build": "tsc",
|
|
||||||
"check": "tsc --noEmit",
|
|
||||||
"dev": "node --loader ts-node/esm src/cli.ts"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@ns/core": "workspace:*"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "^25.5.2",
|
|
||||||
"typescript": "^6.0.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
import { readFile } from 'fs/promises';
|
|
||||||
import { parseStats } from '@ns/core';
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
const args = process.argv.slice(2);
|
|
||||||
|
|
||||||
// FIXME: nuke all of this actually
|
|
||||||
if (args.length === 0) {
|
|
||||||
console.log('NS');
|
|
||||||
console.log('\nUsage: ns-tui <stats.json>');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const filePath = args[0];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const content = await readFile(filePath, 'utf-8');
|
|
||||||
const raw = JSON.parse(content);
|
|
||||||
const stats = parseStats(raw);
|
|
||||||
|
|
||||||
console.log('\n=== Nix Evaluator Statistics ===\n');
|
|
||||||
console.log(`CPU Time: ${stats.cpuTime.toFixed(3)}s`);
|
|
||||||
console.log(`Expressions: ${stats.nrExprs.toLocaleString()}`);
|
|
||||||
console.log(`Thunks: ${stats.nrThunks.toLocaleString()}`);
|
|
||||||
console.log(` - Avoided: ${stats.nrAvoided.toLocaleString()}`);
|
|
||||||
console.log(` - Ratio: ${((stats.nrAvoided / stats.nrThunks) * 100).toFixed(2)}%`);
|
|
||||||
|
|
||||||
const totalMemory =
|
|
||||||
stats.envs.bytes +
|
|
||||||
stats.list.bytes +
|
|
||||||
stats.values.bytes +
|
|
||||||
stats.symbols.bytes +
|
|
||||||
stats.sets.bytes;
|
|
||||||
console.log(`Total Memory: ${(totalMemory / 1024 / 1024).toFixed(2)} MB`);
|
|
||||||
|
|
||||||
console.log('\n=== Memory Breakdown ===\n');
|
|
||||||
console.log(`Environments: ${(stats.envs.bytes / 1024 / 1024).toFixed(2)} MB`);
|
|
||||||
console.log(`Lists: ${(stats.list.bytes / 1024 / 1024).toFixed(2)} MB`);
|
|
||||||
console.log(`Values: ${(stats.values.bytes / 1024 / 1024).toFixed(2)} MB`);
|
|
||||||
console.log(`Symbols: ${(stats.symbols.bytes / 1024 / 1024).toFixed(2)} MB`);
|
|
||||||
console.log(`Sets: ${(stats.sets.bytes / 1024 / 1024).toFixed(2)} MB`);
|
|
||||||
|
|
||||||
if (stats.gc) {
|
|
||||||
console.log('\n=== Garbage Collection ===\n');
|
|
||||||
console.log(`Heap Size: ${(stats.gc.heapSize / 1024 / 1024).toFixed(2)} MB`);
|
|
||||||
console.log(`Total Alloc: ${(stats.gc.totalBytes / 1024 / 1024).toFixed(2)} MB`);
|
|
||||||
console.log(`GC Cycles: ${stats.gc.cycles.toLocaleString()}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('\n' + '='.repeat(40));
|
|
||||||
console.log('='.repeat(40) + '\n');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error:', error instanceof Error ? error.message : String(error));
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2022",
|
|
||||||
"module": "ES2022",
|
|
||||||
"lib": ["ES2022"],
|
|
||||||
"types": ["node"],
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"outDir": "./dist",
|
|
||||||
"rootDir": "./src",
|
|
||||||
"declaration": true,
|
|
||||||
"declarationMap": true,
|
|
||||||
"sourceMap": true,
|
|
||||||
"strict": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"forceConsistentCasingInFileNames": true
|
|
||||||
},
|
|
||||||
"include": ["src/**/*"]
|
|
||||||
}
|
|
||||||
|
|
@ -38,6 +38,13 @@ function App() {
|
||||||
|
|
||||||
// Load from localStorage on mount
|
// Load from localStorage on mount
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
const query = window.location.search;
|
||||||
|
const urlParams = new URLSearchParams(query);
|
||||||
|
|
||||||
|
const file = urlParams.get('file');
|
||||||
|
if (file) {
|
||||||
|
loadFromText(atob(file));
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const saved = localStorage.getItem(STORAGE_KEY);
|
const saved = localStorage.getItem(STORAGE_KEY);
|
||||||
if (saved) {
|
if (saved) {
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,6 @@ pkgs.mkShell {
|
||||||
packages = [
|
packages = [
|
||||||
pkgs.nodejs-slim
|
pkgs.nodejs-slim
|
||||||
pkgs.pnpm
|
pkgs.pnpm
|
||||||
|
pkgs.go
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue