Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clear relationship between ephemeral and persistent lifecycle IDs #677

Merged
merged 6 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions cmd/gqltool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ import (
"github.com/stateful/runme/v3/internal/client/graphql"
)

var (
apiURL = flag.String("api-url", "http://localhost:4000", "The API base address")
// tokenDir = flag.String("token-dir", cmd.GetUserConfigHome(), "The directory with tokens")
)
// var tokenDir = flag.String("token-dir", cmd.GetUserConfigHome(), "The directory with tokens")
var apiURL = flag.String("api-url", "http://localhost:4000", "The API base address")

func init() {
flag.Parse()
Expand Down
3 changes: 3 additions & 0 deletions internal/cmd/code_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ func runCodeServerCommand(cmd *cobra.Command, execFile string, routeToBuffer boo
return buffer.Bytes(), nil
}

//lint:ignore U1000 Ignore because it's only used in tests running in docker
func getLatestExtensionVersion(experimental bool) (string, error) {
var tagName string

Expand Down Expand Up @@ -286,6 +287,7 @@ func getLatestExtensionVersion(experimental bool) (string, error) {
return tagName, nil
}

//lint:ignore U1000 Ignore because it's only used in tests running in docker
func getExtensionURL(tagName string) (string, error) {
var arch string

Expand Down Expand Up @@ -322,6 +324,7 @@ func getExtensionURL(tagName string) (string, error) {
return downloadURL, nil
}

//lint:ignore U1000 Ignore because it's only used in tests running in docker
func downloadVscodeExtension(dir string, experimental bool) (string, error) {
tagName, err := getLatestExtensionVersion(experimental)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/code_server_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:test !darwin
//go:build test_with_docker

package cmd

Expand Down
25 changes: 21 additions & 4 deletions internal/cmd/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ package cmd

import (
"fmt"
"strings"

"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/stateful/runme/v3/pkg/document/identity"
"github.com/stateful/runme/v3/pkg/project"
)

func fmtCmd() *cobra.Command {
var (
formatJSON bool
flatten bool
write bool
flatten bool
formatJSON bool
identityStr string
write bool
)

cmd := cobra.Command{
Expand All @@ -39,7 +42,19 @@ func fmtCmd() *cobra.Command {
}
}

return project.FormatFiles(files, flatten, formatJSON, write, func(file string, formatted []byte) error {
var identityResolver *identity.IdentityResolver
switch strings.ToLower(identityStr) {
case "all":
identityResolver = identity.NewResolver(identity.AllLifecycleIdentity)
case "doc", "document":
identityResolver = identity.NewResolver(identity.DocumentLifecycleIdentity)
case "cell":
identityResolver = identity.NewResolver(identity.CellLifecycleIdentity)
default:
identityResolver = identity.NewResolver(identity.DefaultLifecycleIdentity)
}

return project.FormatFiles(files, identityResolver, formatJSON, write, func(file string, formatted []byte) error {
out := cmd.OutOrStdout()
_, _ = fmt.Fprintf(out, "===== %s =====\n", file)
_, _ = out.Write(formatted)
Expand All @@ -54,6 +69,8 @@ func fmtCmd() *cobra.Command {
cmd.Flags().BoolVar(&flatten, "flatten", true, "Flatten nested blocks in the output. WARNING: This can currently break frontmatter if turned off.")
cmd.Flags().BoolVar(&formatJSON, "json", false, "Print out data as JSON. Only possible with --flatten and not allowed with --write.")
cmd.Flags().BoolVarP(&write, "write", "w", false, "Write result to the source file instead of stdout.")
cmd.Flags().StringVar(&identityStr, "identity", "", "Set the lifecycle identity. Overrides the default.")
_ = cmd.Flags().MarkDeprecated("flatten", "This flag is now default and no longer has any other effect.")

return &cmd
}
13 changes: 8 additions & 5 deletions internal/command/command_terminal.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import (
"go.uber.org/zap"
)

var introMsg = []byte(
" # Runme terminal: Upon exit, exported environment variables will roll up into your session." +
" Type 'save' to add this session to the notebook.\n\n",
const (
introFirstLine = "Runme terminal: Upon exit, exported environment variables will roll up into your session."
introSecondLine = "Type 'save' to add this session to the notebook."
envSourceCmd = "runme beta env source --silent --insecure --export"
)

type terminalCommand struct {
Expand Down Expand Up @@ -53,12 +54,14 @@ func (c *terminalCommand) Start(ctx context.Context) (err error) {
}
}

if _, err := c.stdinWriter.Write([]byte(" eval $(runme beta env source --silent --insecure --export)\n alias save=\"exit\"\n clear\n")); err != nil {
if _, err := c.stdinWriter.Write([]byte(" eval $(" + envSourceCmd + ")\n alias save=\"exit\"\n clear\n")); err != nil {
return err
}

// todo(sebastian): good enough for prototype; it makes more sense to write this message at the TTY-level
_, err = c.stdinWriter.Write(introMsg)
_, err = c.stdinWriter.Write([]byte(
" # " + introFirstLine +
" " + introSecondLine + "\n\n"))

return err
}
Expand Down
28 changes: 18 additions & 10 deletions internal/command/command_terminal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ func TestTerminalCommand_EnvPropagation(t *testing.T) {

// Terminal command sets up a trap on EXIT.
// Wait for it before starting to send commands.
expectContainLine(t, stdout, "trap -- \"__cleanup\" EXIT")
expectContainLines(t, stdout, []string{"trap -- \"__cleanup\" EXIT"})

_, err = stdinW.Write([]byte("export TEST_ENV=1\n"))
require.NoError(t, err)
// Wait for the prompt before sending the next command.
expectContainLine(t, stdout, "$")
expectContainLines(t, stdout, []string{"$"})
_, err = stdinW.Write([]byte("exit\n"))
require.NoError(t, err)

Expand Down Expand Up @@ -91,23 +91,31 @@ func TestTerminalCommand_Intro(t *testing.T) {

require.NoError(t, cmd.Start(ctx))

expectContainLine(t, stdout, "eval $(runme beta env source --silent --insecure --export)")
// todo(sebastian): why won't this work on docker? winsize?
// expectContainLine(t, stdout, strings.Trim(string(introMsg), " \r\n"))
expectContainLines(t, stdout, []string{envSourceCmd, introSecondLine})
}

func expectContainLine(t *testing.T, r io.Reader, expected string) {
func expectContainLines(t *testing.T, r io.Reader, expected []string) {
t.Helper()
var output strings.Builder
hits := make(map[string]bool, len(expected))

for {
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
if strings.Contains(line, expected) {
return
}
_, _ = output.WriteString(scanner.Text())
}
require.NoError(t, scanner.Err())

for _, e := range expected {
if strings.Contains(output.String(), e) {
hits[e] = true
}
}

if len(hits) == len(expected) {
return
}

time.Sleep(time.Millisecond * 400)
}
}
Expand Down
4 changes: 1 addition & 3 deletions internal/runner/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,7 @@ func (r *runnerService) ResolveProgram(ctx context.Context, req *runnerv1.Resolv
return nil, err
}

var (
modifiedScriptBuf bytes.Buffer
)
var modifiedScriptBuf bytes.Buffer

script := req.GetScript()
if commands := req.GetCommands(); script == "" && len(commands.Lines) > 0 {
Expand Down
4 changes: 1 addition & 3 deletions internal/runnerv2service/service_resolve_program.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ func (r *runnerService) ResolveProgram(ctx context.Context, req *runnerv2.Resolv
return nil, err
}

var (
modifiedScriptBuf bytes.Buffer
)
var modifiedScriptBuf bytes.Buffer

script := req.GetScript()
if commands := req.GetCommands(); script == "" && len(commands.Lines) > 0 {
Expand Down
6 changes: 4 additions & 2 deletions internal/telemetry/scarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ const (
client = "Kernel"
)

type reporterFunc func() error
type lookupEnvFunc func(key string) (string, bool)
type (
reporterFunc func() error
lookupEnvFunc func(key string) (string, bool)
)

var reporter reporterFunc

Expand Down
44 changes: 30 additions & 14 deletions pkg/document/document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/stateful/runme/v3/pkg/document/identity"
)

var testIdentityResolver = identity.NewResolver(identity.DefaultLifecycleIdentity)
var allIdentityResolver = identity.NewResolver(identity.AllLifecycleIdentity)

func TestDocument_Parse(t *testing.T) {
data := []byte(`# Examples
Expand All @@ -36,7 +36,7 @@ First paragraph.
2. Item 2
3. Item 3
`)
doc := New(data, testIdentityResolver)
doc := New(data, allIdentityResolver)
node, err := doc.Root()
require.NoError(t, err)
assert.Len(t, node.children, 4)
Expand Down Expand Up @@ -70,27 +70,43 @@ First paragraph.
}

func TestDocument_Frontmatter(t *testing.T) {
t.Run("Parse", func(t *testing.T) {
data := bytes.TrimSpace([]byte(`
lcidRegex := `---\nkey: value\nrunme:\n id: .*\n version: v(?:[3-9]\d*|2\.\d+\.\d+|2\.\d+|\d+)\n---`
data := bytes.TrimSpace([]byte(`
---
key: value
---

First paragraph
`,
))
))

t.Run("Parse_DefaultIdentity", func(t *testing.T) {
defaultIdentityResolver := identity.NewResolver(identity.DefaultLifecycleIdentity)
doc := New(data, defaultIdentityResolver)
err := doc.Parse()
require.NoError(t, err)
assert.Equal(t, []byte("First paragraph"), doc.Content())
assert.Equal(t, 20, doc.ContentOffset())

frontmatter, err := doc.FrontmatterWithError()
require.NoError(t, err)
marshaledFrontmatter, err := frontmatter.Marshal(defaultIdentityResolver.DocumentEnabled())
require.NoError(t, err)
assert.NotRegexp(t, lcidRegex, string(marshaledFrontmatter))
})

doc := New(data, testIdentityResolver)
t.Run("Parse_AllIdentity", func(t *testing.T) {
doc := New(data, allIdentityResolver)
err := doc.Parse()
require.NoError(t, err)
assert.Equal(t, []byte("First paragraph"), doc.Content())
assert.Equal(t, 20, doc.ContentOffset())

frontmatter, err := doc.FrontmatterWithError()
require.NoError(t, err)
marshaledFrontmatter, err := frontmatter.Marshal(testIdentityResolver.DocumentEnabled())
marshaledFrontmatter, err := frontmatter.Marshal(allIdentityResolver.DocumentEnabled())
require.NoError(t, err)
assert.Regexp(t, `---\nkey: value\nrunme:\n id: .*\n version: v(?:[3-9]\d*|2\.\d+\.\d+|2\.\d+|\d+)\n---`, string(marshaledFrontmatter))
assert.Regexp(t, lcidRegex, string(marshaledFrontmatter))
})

t.Run("Format", func(t *testing.T) {
Expand Down Expand Up @@ -137,7 +153,7 @@ shell = "fish"

for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
doc := New(tc.Data, testIdentityResolver)
doc := New(tc.Data, allIdentityResolver)
_, err := doc.Root()
require.NoError(t, err)

Expand All @@ -158,7 +174,7 @@ shell = "fish"
---
`,
))
doc := New(data, testIdentityResolver)
doc := New(data, allIdentityResolver)
err := doc.Parse()
require.NoError(t, err)

Expand All @@ -172,7 +188,7 @@ func TestDocument_TrailingLineBreaks(t *testing.T) {
data := []byte(`This will test final line breaks`)

t.Run("No breaks", func(t *testing.T) {
doc := New(data, testIdentityResolver)
doc := New(data, allIdentityResolver)
astNode, err := doc.RootAST()
require.NoError(t, err)

Expand All @@ -189,7 +205,7 @@ func TestDocument_TrailingLineBreaks(t *testing.T) {

t.Run("1 LF", func(t *testing.T) {
withLineBreaks := append(data, bytes.Repeat([]byte{'\n'}, 1)...)
doc := New(withLineBreaks, testIdentityResolver)
doc := New(withLineBreaks, allIdentityResolver)
astNode, err := doc.RootAST()
require.NoError(t, err)

Expand All @@ -206,7 +222,7 @@ func TestDocument_TrailingLineBreaks(t *testing.T) {

t.Run("1 CRLF", func(t *testing.T) {
withLineBreaks := append(data, bytes.Repeat([]byte{'\r', '\n'}, 1)...)
doc := New(withLineBreaks, testIdentityResolver)
doc := New(withLineBreaks, allIdentityResolver)
astNode, err := doc.RootAST()
require.NoError(t, err)

Expand All @@ -223,7 +239,7 @@ func TestDocument_TrailingLineBreaks(t *testing.T) {

t.Run("7 LFs", func(t *testing.T) {
withLineBreaks := append(data, bytes.Repeat([]byte{'\n'}, 7)...)
doc := New(withLineBreaks, testIdentityResolver)
doc := New(withLineBreaks, allIdentityResolver)
astNode, err := doc.RootAST()
require.NoError(t, err)

Expand Down
3 changes: 1 addition & 2 deletions pkg/document/editor/cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,7 @@ func toCellsRec(

// In the future, we will include language detection (#77).
metadata := block.Attributes()
cellID := block.ID()
if cellID != "" {
if cellID := block.ID(); cellID != "" {
metadata[PrefixAttributeName(InternalAttributePrefix, "id")] = cellID
}
metadata[PrefixAttributeName(InternalAttributePrefix, "name")] = block.Name()
Expand Down
Loading
Loading