rubyatscale / singed

Get a flamegraph anywhere in your code base. Powered by stackprof, rbspy, and speedscope
MIT License
409 stars 10 forks source link

Bundle speedscope #35

Open technicalpickles opened 6 months ago

technicalpickles commented 6 months ago

Currently, singed assumes you have a working node install, and can run npx to be able to install and run speedscope.

Is there any way to bundle speedscope to reduce friction even more?

When you run npx speedscope <path>, it is essentially creating a static HTML file, and then singed is using open on it to get a browser for it.

technicalpickles commented 6 months ago

Looked at this a bit with @nateberkopec yesterday. The speedscope command itself is written in javascript, so needs a node runtime. But, looking at it more closely, it is mostly creating some temporary html and javascript files that eventually load the bundled dist/release/index.html.

Knowing that, we could port it to another language... for example, bash:

#!/bin/bash

set -x

helpString="Usage: speedscope [filepath]

If invoked with no arguments, will open a local copy of speedscope in your default browser.
Once open, you can browse for a profile to import.

If - is used as the filepath, will read from stdin instead.

cat /path/to/profile | speedscope - 
"

function getProfileBuffer() {
    if [ "$1" == "-" ]; then
        cat -
    else
        cat $1
    fi
}

urlToOpen="file://$(realpath "$(dirname $0)/../dist/release/index.html")"

filePrefix="speedscope-$(date +%s)-$$"
tempdir=$(mktemp -d)

jsPath="$tempdir/$filePrefix.js"
echo "Creating temp file $jsPath"
jsSource="speedscope.loadFileFromBase64(\"$1\", \"$(getProfileBuffer $1 | base64 -w 0)\")"
echo "$jsSource" > "$jsPath"
urlToOpen="$urlToOpen#localProfilePath=$jsPath"

htmlPath="$tempdir/$filePrefix.html"
echo "Creating temp file $htmlPath"
cat <<EOF > "$htmlPath"
<script>window.location="${urlToOpen}"</script>
EOF

function openBrowser() {
  if command -v xdg-open > /dev/null; then
    xdg-open $1
  elif command -v open > /dev/null; then
    open $1
  else
    echo "Could not open $1 in a browser. Please open it manually."
  fi
}

urlToOpen="file://${htmlPath}"
echo "Opening $urlToOpen in your default browser"
openBrowser $urlToOpen

This still requires the static files for speedscope to be installed somehwere

One way to do this would be to make part of releasing singed: