From d6003e176eddc9465a57eed4560e34482ff1cfe2 Mon Sep 17 00:00:00 2001 From: Sebastian Tiedtke Date: Mon, 13 Nov 2023 12:13:05 -0500 Subject: [PATCH] Lifecycle identity refactor (#428) * Baseline refactor, tests still failing * Don't overwrite with v0.0 if set * More refactoring, tests still failing * Wrong mapping * Move to serialization phase * Preserve existing cell ID semantics * Make linter happy * Fmt * None until v2 * Deserialize options only --- examples/grpc-client/main.go | 6 +- internal/api/runme/parser/v1/parser.proto | 5 - internal/document/block.go | 14 ++ internal/document/document.go | 18 +- internal/document/document_test.go | 15 +- internal/document/editor/cell.go | 20 +- internal/document/editor/cell_test.go | 24 +- internal/document/editor/editor.go | 7 +- internal/document/editor/editor_test.go | 31 +-- .../document/editor/editorservice/service.go | 35 +-- .../editor/editorservice/service_test.go | 35 ++- internal/document/frontmatter.go | 15 +- internal/document/identity/resolver.go | 96 ++++++++ internal/document/node_test.go | 7 +- .../gen/proto/go/runme/parser/v1/parser.pb.go | 210 ++++++------------ .../proto/ts/runme/parser/v1/parser_pb.d.ts | 20 -- .../gen/proto/ts/runme/parser/v1/parser_pb.js | 15 +- .../gen/proto/ts/runme/parser/v1/parser_pb.ts | 43 ---- internal/runner/command.go | 4 +- internal/runner/service.go | 4 +- internal/runner/session.go | 4 +- internal/runner/shell_session.go | 4 +- internal/{identity => ulid}/generator.go | 0 internal/{identity => ulid}/generator_test.go | 0 pkg/project/document.go | 4 +- pkg/project/formatter.go | 10 +- pkg/project/project_test.go | 8 +- 27 files changed, 312 insertions(+), 342 deletions(-) create mode 100644 internal/document/identity/resolver.go rename internal/{identity => ulid}/generator.go (100%) rename internal/{identity => ulid}/generator_test.go (100%) diff --git a/examples/grpc-client/main.go b/examples/grpc-client/main.go index e966bc4c5..35733da7d 100644 --- a/examples/grpc-client/main.go +++ b/examples/grpc-client/main.go @@ -73,6 +73,9 @@ func run() error { resp, err := client.Deserialize(context.Background(), &parserv1.DeserializeRequest{ Source: data, + Options: &parserv1.DeserializeRequestOptions{ + Identity: parserv1.RunmeIdentity_RUNME_IDENTITY_UNSPECIFIED, + }, }) if err != nil { return err @@ -85,9 +88,6 @@ func run() error { resp2, err := client.Serialize(context.Background(), &parserv1.SerializeRequest{ Notebook: resp.Notebook, - Options: &parserv1.SerializeRequestOptions{ - Identity: parserv1.RunmeIdentity_RUNME_IDENTITY_UNSPECIFIED, - }, }) if err != nil { return err diff --git a/internal/api/runme/parser/v1/parser.proto b/internal/api/runme/parser/v1/parser.proto index 93c5ac0e9..9db5e503a 100644 --- a/internal/api/runme/parser/v1/parser.proto +++ b/internal/api/runme/parser/v1/parser.proto @@ -55,13 +55,8 @@ message DeserializeResponse { Notebook notebook = 1; } -message SerializeRequestOptions { - RunmeIdentity identity = 1; -} - message SerializeRequest { Notebook notebook = 1; - SerializeRequestOptions options = 2; } message SerializeResponse { diff --git a/internal/document/block.go b/internal/document/block.go index 28b77fd64..a23ca40d6 100644 --- a/internal/document/block.go +++ b/internal/document/block.go @@ -8,6 +8,7 @@ import ( "strings" "unicode" + "github.com/stateful/runme/internal/document/identity" "github.com/stateful/runme/internal/executable" "github.com/stateful/runme/internal/shell" "github.com/yuin/goldmark/ast" @@ -50,6 +51,8 @@ func (b CodeBlocks) Names() (result []string) { type Renderer func(ast.Node, []byte) ([]byte, error) type CodeBlock struct { + id string + idGenerated bool attributes map[string]string inner *ast.FencedCodeBlock intro string @@ -62,6 +65,7 @@ type CodeBlock struct { func newCodeBlock( node *ast.FencedCodeBlock, + identityResolver *identity.IdentityResolver, nameResolver *nameResolver, source []byte, render Renderer, @@ -71,6 +75,8 @@ func newCodeBlock( return nil, err } + id, hasID := identityResolver.GetCellID(node, attributes) + name, hasName := getName(node, source, nameResolver, attributes) value, err := render(node, source) @@ -79,6 +85,8 @@ func newCodeBlock( } return &CodeBlock{ + id: id, + idGenerated: !hasID, attributes: attributes, inner: node, intro: getIntro(node, source), @@ -100,6 +108,8 @@ func (b *CodeBlock) Clone() *CodeBlock { attributes[key] = value } return &CodeBlock{ + id: b.id, + idGenerated: b.idGenerated, attributes: attributes, intro: b.intro, language: b.language, @@ -149,6 +159,10 @@ func (b *CodeBlock) Lines() []string { return b.lines } +func (b *CodeBlock) ID() string { + return b.id +} + func (b *CodeBlock) Name() string { return b.name } diff --git a/internal/document/document.go b/internal/document/document.go index 76a2f6c79..3185fed04 100644 --- a/internal/document/document.go +++ b/internal/document/document.go @@ -11,19 +11,22 @@ import ( "github.com/yuin/goldmark/text" "github.com/stateful/runme/internal/document/constants" + "github.com/stateful/runme/internal/document/identity" ) type Document struct { - astNode ast.Node - nameResolver *nameResolver - node *Node - parser parser.Parser - renderer Renderer - source []byte + astNode ast.Node + identityResolver *identity.IdentityResolver + nameResolver *nameResolver + node *Node + parser parser.Parser + renderer Renderer + source []byte } -func New(source []byte, renderer Renderer) *Document { +func New(source []byte, renderer Renderer, identityResolver *identity.IdentityResolver) *Document { return &Document{ + identityResolver: identityResolver, nameResolver: &nameResolver{ namesCounter: map[string]int{}, cache: map[interface{}]string{}, @@ -63,6 +66,7 @@ func (d *Document) buildBlocksTree(parent ast.Node, node *Node) error { case ast.KindFencedCodeBlock: block, err := newCodeBlock( astNode.(*ast.FencedCodeBlock), + d.identityResolver, d.nameResolver, d.source, d.renderer, diff --git a/internal/document/document_test.go b/internal/document/document_test.go index c25084e6d..a7e203c90 100644 --- a/internal/document/document_test.go +++ b/internal/document/document_test.go @@ -4,11 +4,14 @@ import ( "bytes" "testing" + "github.com/stateful/runme/internal/document/identity" "github.com/stateful/runme/internal/renderer/cmark" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +var identityResolver = identity.NewResolver(identity.AllLifecycleIdentity) + func TestDocument_Parse(t *testing.T) { data := []byte(`# Examples @@ -32,7 +35,7 @@ First paragraph. 2. Item 2 3. Item 3 `) - doc := New(data, cmark.Render) + doc := New(data, cmark.Render, identityResolver) node, _, err := doc.Parse() require.NoError(t, err) assert.Len(t, node.children, 4) @@ -84,7 +87,7 @@ console.log("hello world!") `, )) - doc := New(data, cmark.Render) + doc := New(data, cmark.Render, identityResolver) node, _, err := doc.Parse() require.NoError(t, err) @@ -98,7 +101,7 @@ func TestDocument_FinalLineBreaks(t *testing.T) { data := []byte(`This will test final line breaks`) t.Run("No breaks", func(t *testing.T) { - doc := New(data, cmark.Render) + doc := New(data, cmark.Render, identityResolver) _, astNode, err := doc.Parse() require.NoError(t, err) @@ -114,7 +117,7 @@ func TestDocument_FinalLineBreaks(t *testing.T) { t.Run("1 LF", func(t *testing.T) { withLineBreaks := append(data, bytes.Repeat([]byte{'\n'}, 1)...) - doc := New(withLineBreaks, cmark.Render) + doc := New(withLineBreaks, cmark.Render, identityResolver) _, astNode, err := doc.Parse() require.NoError(t, err) @@ -130,7 +133,7 @@ func TestDocument_FinalLineBreaks(t *testing.T) { t.Run("1 CRLF", func(t *testing.T) { withLineBreaks := append(data, bytes.Repeat([]byte{'\r', '\n'}, 1)...) - doc := New(withLineBreaks, cmark.Render) + doc := New(withLineBreaks, cmark.Render, identityResolver) _, astNode, err := doc.Parse() require.NoError(t, err) @@ -146,7 +149,7 @@ func TestDocument_FinalLineBreaks(t *testing.T) { t.Run("7 LFs", func(t *testing.T) { withLineBreaks := append(data, bytes.Repeat([]byte{'\n'}, 7)...) - doc := New(withLineBreaks, cmark.Render) + doc := New(withLineBreaks, cmark.Render, identityResolver) _, astNode, err := doc.Parse() require.NoError(t, err) diff --git a/internal/document/editor/cell.go b/internal/document/editor/cell.go index f7e5ed64e..d0f2cd9a8 100644 --- a/internal/document/editor/cell.go +++ b/internal/document/editor/cell.go @@ -11,7 +11,7 @@ import ( "strings" "github.com/stateful/runme/internal/document" - "github.com/stateful/runme/internal/identity" + ulid "github.com/stateful/runme/internal/ulid" "github.com/yuin/goldmark/ast" ) @@ -54,13 +54,15 @@ type Notebook struct { frontmatterParseInfo *document.FrontmatterParseInfo } -func (c *Cell) EnsureID() { - id, ok := c.Metadata["id"] - if ok && identity.ValidID(id) { - return +// This mimics what otherwise would happen in the extension +func (n *Notebook) ForceLifecyleIdentities() { + for _, c := range n.Cells { + id, ok := c.Metadata[PrefixAttributeName(InternalAttributePrefix, "id")] + if !ok && id == "" || !ulid.ValidID(id) { + continue + } + c.Metadata["id"] = id } - - c.Metadata["id"] = identity.GenerateID() } func (n *Notebook) GetContentOffset() int { @@ -147,6 +149,10 @@ func toCellsRec( // In the future, we will include language detection (#77). metadata := block.Attributes() + cellID := block.ID() + if cellID != "" { + metadata[PrefixAttributeName(InternalAttributePrefix, "id")] = cellID + } metadata[PrefixAttributeName(InternalAttributePrefix, "name")] = block.Name() *cells = append(*cells, &Cell{ Kind: CodeKind, diff --git a/internal/document/editor/cell_test.go b/internal/document/editor/cell_test.go index a1d896af7..f65ae7a4f 100644 --- a/internal/document/editor/cell_test.go +++ b/internal/document/editor/cell_test.go @@ -99,7 +99,7 @@ Test paragraph ) func Test_toCells_DataNested(t *testing.T) { - doc := document.New(testDataNested, cmark.Render) + doc := document.New(testDataNested, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) cells := toCells(node, testDataNested) @@ -122,7 +122,7 @@ func Test_toCells_Lists(t *testing.T) { 2. Item 2 3. Item 3 `) - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) cells := toCells(node, data) @@ -138,7 +138,7 @@ func Test_toCells_Lists(t *testing.T) { ` + "```" + ` 3. Item 3 `) - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) cells := toCells(node, data) @@ -155,7 +155,7 @@ func Test_toCells_EmptyLang(t *testing.T) { echo 1 ` + "```" + ` `) - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) cells := toCells(node, data) @@ -173,7 +173,7 @@ def hello(): print("Hello World") ` + "```" + ` `) - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) cells := toCells(node, data) @@ -196,7 +196,7 @@ Last paragraph. `) parse := func() []*Cell { - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) cells := toCells(node, data) @@ -299,7 +299,7 @@ func Test_serializeCells_nestedCode(t *testing.T) { pre-commit install ` + "```" + ` `) - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) cells := toCells(node, data) @@ -331,7 +331,7 @@ func Test_serializeCells(t *testing.T) { t.Run("attributes_babikml", func(t *testing.T) { data := []byte("```sh { name=echo first= second=2 }\necho 1\n```\n") expected := []byte("```sh {\"first\":\"\",\"name\":\"echo\",\"second\":\"2\"}\necho 1\n```\n") - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) cells := toCells(node, data) @@ -340,7 +340,7 @@ func Test_serializeCells(t *testing.T) { t.Run("attributes", func(t *testing.T) { data := []byte("```sh {\"first\":\"\",\"name\":\"echo\",\"second\":\"2\"}\necho 1\n```\n") - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) cells := toCells(node, data) @@ -349,7 +349,7 @@ func Test_serializeCells(t *testing.T) { t.Run("privateFields", func(t *testing.T) { data := []byte("```sh {\"first\":\"\",\"name\":\"echo\",\"second\":\"2\"}\necho 1\n```\n") - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) @@ -369,7 +369,7 @@ def hello(): print("Hello World") ` + "```" + ` `) - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolverAll) node, _, err := doc.Parse() require.NoError(t, err) cells := toCells(node, data) @@ -444,7 +444,7 @@ func Test_notebook_frontmatter(t *testing.T) { t.Run(ex.kind, func(t *testing.T) { t.Parallel() - notebook, err := Deserialize(file, false) + notebook, err := Deserialize(file, identityResolverAll) require.NoError(t, err) fmtr, info := notebook.ParsedFrontmatter() diff --git a/internal/document/editor/editor.go b/internal/document/editor/editor.go index 08025b088..a724e26f3 100644 --- a/internal/document/editor/editor.go +++ b/internal/document/editor/editor.go @@ -10,18 +10,19 @@ import ( "github.com/stateful/runme/internal/renderer/cmark" "github.com/stateful/runme/internal/document/constants" + "github.com/stateful/runme/internal/document/identity" ) const FrontmatterKey = "frontmatter" -func Deserialize(data []byte, requireIdentity bool) (*Notebook, error) { +func Deserialize(data []byte, identityResolver *identity.IdentityResolver) (*Notebook, error) { sections, err := document.ParseSections(data) if err != nil { return nil, err } // Deserialize content to cells. - doc := document.New(sections.Content, cmark.Render) + doc := document.New(sections.Content, cmark.Render, identityResolver) node, _, err := doc.Parse() if err != nil { return nil, err @@ -37,7 +38,7 @@ func Deserialize(data []byte, requireIdentity bool) (*Notebook, error) { PrefixAttributeName(InternalAttributePrefix, constants.FinalLineBreaksKey): fmt.Sprint(finalLinesBreaks), } - f, info := document.ParseFrontmatterWithIdentity(string(sections.FrontMatter), requireIdentity) + f, info := document.ParseFrontmatterWithIdentity(string(sections.FrontMatter), identityResolver.DocumentEnabled()) notebook.parsedFrontmatter = &f notebook.frontmatterParseInfo = &info diff --git a/internal/document/editor/editor_test.go b/internal/document/editor/editor_test.go index a0d9d4fc4..7ab188e2e 100644 --- a/internal/document/editor/editor_test.go +++ b/internal/document/editor/editor_test.go @@ -11,22 +11,27 @@ import ( "github.com/stretchr/testify/require" "github.com/stateful/runme/internal/document/constants" - "github.com/stateful/runme/internal/identity" + "github.com/stateful/runme/internal/document/identity" + ulid "github.com/stateful/runme/internal/ulid" "github.com/stateful/runme/internal/version" ) -var testMockID = identity.GenerateID() +var ( + identityResolverNone = identity.NewResolver(identity.UnspecifiedLifecycleIdentity) + identityResolverAll = identity.NewResolver(identity.AllLifecycleIdentity) + testMockID = ulid.GenerateID() +) func TestMain(m *testing.M) { - identity.MockGenerator(testMockID) + ulid.MockGenerator(testMockID) code := m.Run() - identity.ResetGenerator() + ulid.ResetGenerator() os.Exit(code) } func TestEditor(t *testing.T) { - notebook, err := Deserialize(testDataNested, false) + notebook, err := Deserialize(testDataNested, identityResolverNone) require.NoError(t, err) result, err := Serialize(notebook) require.NoError(t, err) @@ -42,7 +47,7 @@ func TestEditor_List(t *testing.T) { 2. Item 2 3. Item 3 `) - notebook, err := Deserialize(data, false) + notebook, err := Deserialize(data, identityResolverNone) require.NoError(t, err) notebook.Cells[0].Value = "1. Item 1\n2. Item 2\n" @@ -71,7 +76,7 @@ func TestEditor_List(t *testing.T) { func TestEditor_CodeBlock(t *testing.T) { t.Run("ProvideGeneratedName", func(t *testing.T) { data := []byte("```sh\necho 1\n```\n") - notebook, err := Deserialize(data, false) + notebook, err := Deserialize(data, identityResolverNone) require.NoError(t, err) cell := notebook.Cells[0] assert.Equal( @@ -91,7 +96,7 @@ func TestEditor_CodeBlock(t *testing.T) { t.Run("PreserveName", func(t *testing.T) { data := []byte("```sh {\"name\":\"name1\"}\necho 1\n```\n") - notebook, err := Deserialize(data, false) + notebook, err := Deserialize(data, identityResolverNone) require.NoError(t, err) cell := notebook.Cells[0] assert.Equal( @@ -122,7 +127,7 @@ Paragraph 1 with a link [Link1](https://example.com 'Link Title 1') and a second err := os.Setenv("RUNME_AST_METADATA", "true") require.NoError(t, err) - notebook, err := Deserialize(data, false) + notebook, err := Deserialize(data, identityResolverNone) require.NoError(t, err) require.NotEmpty(t, notebook.Metadata) @@ -171,7 +176,7 @@ version = '%s' A paragraph `, testMockID, version.BaseVersion())) - notebook, err := Deserialize(data, false) + notebook, err := Deserialize(data, identityResolverNone) require.NoError(t, err) result, err := Serialize(notebook) require.NoError(t, err) @@ -188,7 +193,7 @@ func TestEditor_Newlines(t *testing.T) { This will test final line breaks`) t.Run("No line breaks", func(t *testing.T) { - notebook, err := Deserialize(data, false) + notebook, err := Deserialize(data, identityResolverNone) require.NoError(t, err) assert.Equal( @@ -209,7 +214,7 @@ This will test final line breaks`) t.Run("Single line break", func(t *testing.T) { withLineBreaks := append(data, byte('\n')) - notebook, err := Deserialize(withLineBreaks, false) + notebook, err := Deserialize(withLineBreaks, identityResolverNone) require.NoError(t, err) assert.Equal( @@ -230,7 +235,7 @@ This will test final line breaks`) t.Run("7 line breaks", func(t *testing.T) { withLineBreaks := append(data, bytes.Repeat([]byte{'\n'}, 7)...) - notebook, err := Deserialize(withLineBreaks, false) + notebook, err := Deserialize(withLineBreaks, identityResolverNone) require.NoError(t, err) assert.Equal( diff --git a/internal/document/editor/editorservice/service.go b/internal/document/editor/editorservice/service.go index 72eb71cbf..4facf5b38 100644 --- a/internal/document/editor/editorservice/service.go +++ b/internal/document/editor/editorservice/service.go @@ -4,6 +4,7 @@ import ( "context" "github.com/stateful/runme/internal/document/editor" + "github.com/stateful/runme/internal/document/identity" parserv1 "github.com/stateful/runme/internal/gen/proto/go/runme/parser/v1" "go.uber.org/zap" "golang.org/x/exp/constraints" @@ -15,16 +16,6 @@ type parserServiceServer struct { logger *zap.Logger } -var notebookIdentities = []parserv1.RunmeIdentity{ - parserv1.RunmeIdentity_RUNME_IDENTITY_ALL, - parserv1.RunmeIdentity_RUNME_IDENTITY_DOCUMENT, -} - -var cellIdentities = []parserv1.RunmeIdentity{ - parserv1.RunmeIdentity_RUNME_IDENTITY_ALL, - parserv1.RunmeIdentity_RUNME_IDENTITY_CELL, -} - func NewParserServiceServer(logger *zap.Logger) parserv1.ParserServiceServer { return &parserServiceServer{logger: logger} } @@ -32,11 +23,8 @@ func NewParserServiceServer(logger *zap.Logger) parserv1.ParserServiceServer { func (s *parserServiceServer) Deserialize(_ context.Context, req *parserv1.DeserializeRequest) (*parserv1.DeserializeResponse, error) { s.logger.Info("Deserialize", zap.ByteString("source", req.Source[:min(len(req.Source), 64)])) - currentIdentity := req.Options.Identity - notebookIdentity := containsIdentity(notebookIdentities, currentIdentity) - cellIdentity := containsIdentity(cellIdentities, currentIdentity) - - notebook, err := editor.Deserialize(req.Source, notebookIdentity) + identityResolver := identity.NewResolver(identity.ToLifecycleIdentity(req.Options.Identity)) + notebook, err := editor.Deserialize(req.Source, identityResolver) if err != nil { s.logger.Info("failed to call Deserialize", zap.Error(err)) return nil, err @@ -56,14 +44,6 @@ func (s *parserServiceServer) Deserialize(_ context.Context, req *parserv1.Deser } } - if cell.Kind == editor.CodeKind && cellIdentity { - if cell.Metadata == nil { - cell.Metadata = make(map[string]string) - } - - cell.EnsureID() - } - cells = append(cells, &parserv1.Cell{ Kind: parserv1.CellKind(cell.Kind), Value: cell.Value, @@ -113,12 +93,3 @@ func min[T constraints.Ordered](a, b T) T { } return b } - -func containsIdentity(ids []parserv1.RunmeIdentity, i parserv1.RunmeIdentity) bool { - for _, v := range ids { - if v == i { - return true - } - } - return false -} diff --git a/internal/document/editor/editorservice/service_test.go b/internal/document/editor/editorservice/service_test.go index e65a27a6e..4a916e8e1 100644 --- a/internal/document/editor/editorservice/service_test.go +++ b/internal/document/editor/editorservice/service_test.go @@ -8,7 +8,7 @@ import ( "testing" parserv1 "github.com/stateful/runme/internal/gen/proto/go/runme/parser/v1" - "github.com/stateful/runme/internal/identity" + ulid "github.com/stateful/runme/internal/ulid" "github.com/stateful/runme/internal/version" "github.com/stretchr/testify/assert" "go.uber.org/zap" @@ -19,7 +19,7 @@ import ( ) var ( - testMockID = identity.GenerateID() + testMockID = ulid.GenerateID() client parserv1.ParserServiceClient documentWithoutFrontmatter = strings.Join([]string{ @@ -50,7 +50,7 @@ var ( ) func TestMain(m *testing.M) { - identity.MockGenerator(testMockID) + ulid.MockGenerator(testMockID) lis := bufconn.Listen(2048) server := grpc.NewServer() @@ -71,7 +71,7 @@ func TestMain(m *testing.M) { client = parserv1.NewParserServiceClient(conn) code := m.Run() - identity.ResetGenerator() + ulid.ResetGenerator() os.Exit(code) } @@ -102,7 +102,7 @@ func Test_IdentityUnspecified(t *testing.T) { assert.Len(t, dResp.Notebook.Metadata, 1) } - sResp, err := serialize(client, dResp.Notebook, identity) + sResp, err := serializeWithIdentityPersistence(client, dResp.Notebook, identity) assert.NoError(t, err) content := string(sResp.Result) @@ -144,7 +144,7 @@ func Test_IdentityAll(t *testing.T) { assert.Contains(t, rawFrontmatter, "id: "+testMockID) assert.Contains(t, rawFrontmatter, "version: "+version.BaseVersion()) - sResp, err := serialize(client, dResp.Notebook, identity) + sResp, err := serializeWithIdentityPersistence(client, dResp.Notebook, identity) assert.NoError(t, err) content := string(sResp.Result) @@ -185,7 +185,7 @@ func Test_IdentityDocument(t *testing.T) { assert.Contains(t, rawFrontmatter, "id: "+testMockID) assert.Contains(t, rawFrontmatter, "version: "+version.BaseVersion()) - sResp, err := serialize(client, dResp.Notebook, identity) + sResp, err := serializeWithIdentityPersistence(client, dResp.Notebook, identity) assert.NoError(t, err) content := string(sResp.Result) @@ -227,7 +227,7 @@ func Test_IdentityCell(t *testing.T) { assert.Len(t, dResp.Notebook.Metadata, 1) } - sResp, err := serialize(client, dResp.Notebook, identity) + sResp, err := serializeWithIdentityPersistence(client, dResp.Notebook, identity) assert.NoError(t, err) content := string(sResp.Result) @@ -302,14 +302,25 @@ func deserialize(client parserv1.ParserServiceClient, content string, idt parser ) } -func serialize(client parserv1.ParserServiceClient, notebook *parserv1.Notebook, idt parserv1.RunmeIdentity) (*parserv1.SerializeResponse, error) { +func serializeWithIdentityPersistence(client parserv1.ParserServiceClient, notebook *parserv1.Notebook, idt parserv1.RunmeIdentity) (*parserv1.SerializeResponse, error) { + persistIdentityLikeExtension(notebook) return client.Serialize( context.Background(), &parserv1.SerializeRequest{ Notebook: notebook, - Options: &parserv1.SerializeRequestOptions{ - Identity: idt, - }, }, ) } + +// mimics what would happen on the extension side +func persistIdentityLikeExtension(notebook *parserv1.Notebook) { + for _, cell := range notebook.Cells { + // todo(sebastian): preserve original id when they are set? + // if _, ok := cell.Metadata["id"]; ok { + // break + // } + if v, ok := cell.Metadata["runme.dev/id"]; ok { + cell.Metadata["id"] = v + } + } +} diff --git a/internal/document/frontmatter.go b/internal/document/frontmatter.go index b81064aa8..5df8da889 100644 --- a/internal/document/frontmatter.go +++ b/internal/document/frontmatter.go @@ -9,7 +9,7 @@ import ( "github.com/pelletier/go-toml/v2" parserv1 "github.com/stateful/runme/internal/gen/proto/go/runme/parser/v1" - "github.com/stateful/runme/internal/identity" + ulid "github.com/stateful/runme/internal/ulid" "github.com/stateful/runme/internal/version" "gopkg.in/yaml.v3" ) @@ -39,7 +39,7 @@ type FrontmatterParseInfo struct { func NewFrontmatter() Frontmatter { return Frontmatter{ Runme: RunmeMetaData{ - ID: identity.GenerateID(), + ID: ulid.GenerateID(), Version: version.BaseVersion(), }, } @@ -189,11 +189,16 @@ func ParseFrontmatterWithIdentity(raw string, enabled bool) (f Frontmatter, info } func (fmtr *Frontmatter) ensureID() { - if !identity.ValidID(fmtr.Runme.ID) { - fmtr.Runme.ID = identity.GenerateID() + if !ulid.ValidID(fmtr.Runme.ID) { + fmtr.Runme.ID = ulid.GenerateID() } - fmtr.Runme.Version = version.BaseVersion() + baseVersion := version.BaseVersion() + // todo(sebastian): fix tests when reenabled + // if fmtr.Runme.Version != "" && baseVersion == "v0.0" { + // return + // } + fmtr.Runme.Version = baseVersion } func (fmtr Frontmatter) ToParser() *parserv1.Frontmatter { diff --git a/internal/document/identity/resolver.go b/internal/document/identity/resolver.go new file mode 100644 index 000000000..b5942093b --- /dev/null +++ b/internal/document/identity/resolver.go @@ -0,0 +1,96 @@ +package identity + +import ( + parserv1 "github.com/stateful/runme/internal/gen/proto/go/runme/parser/v1" + ulid "github.com/stateful/runme/internal/ulid" +) + +type LifecycleIdentity int + +const ( + UnspecifiedLifecycleIdentity LifecycleIdentity = iota + AllLifecycleIdentity + DocumentLifecycleIdentity + CellLifecycleIdentity +) + +type LifecycleIdentities []LifecycleIdentity + +const ( + DefaultLifecycleIdentity = UnspecifiedLifecycleIdentity +) + +var documentIdentities = &LifecycleIdentities{ + AllLifecycleIdentity, + DocumentLifecycleIdentity, +} + +var cellIdentities = &LifecycleIdentities{ + AllLifecycleIdentity, + CellLifecycleIdentity, +} + +func (required *LifecycleIdentities) Contains(id LifecycleIdentity) bool { + for _, v := range *required { + if v == id { + return true + } + } + return false +} + +type IdentityResolver struct { + documentIdentity bool + cellIdentity bool + cache map[interface{}]string +} + +func NewResolver(required LifecycleIdentity) *IdentityResolver { + return &IdentityResolver{ + documentIdentity: documentIdentities.Contains(required), + cellIdentity: cellIdentities.Contains(required), + cache: map[interface{}]string{}, + } +} + +func (ir *IdentityResolver) CellEnabled() bool { + return ir.cellIdentity +} + +func (ir *IdentityResolver) DocumentEnabled() bool { + return ir.documentIdentity +} + +func (ir *IdentityResolver) GetCellID(obj interface{}, attributes map[string]string) (string, bool) { + if !ir.cellIdentity { + return "", false + } + + // todo(sebastian): are invalid ulid's valid IDs? + if n, ok := attributes["id"]; ok && ulid.ValidID(n) { + ir.cache[obj] = n + return n, true + } + + if v, ok := ir.cache[obj]; ok { + return v, false + } + + id := ulid.GenerateID() + ir.cache[obj] = id + + return id, false +} + +func ToLifecycleIdentity(idt parserv1.RunmeIdentity) LifecycleIdentity { + switch idt { + case parserv1.RunmeIdentity_RUNME_IDENTITY_ALL: + return AllLifecycleIdentity + case parserv1.RunmeIdentity_RUNME_IDENTITY_DOCUMENT: + return DocumentLifecycleIdentity + case parserv1.RunmeIdentity_RUNME_IDENTITY_CELL: + return CellLifecycleIdentity + default: + return UnspecifiedLifecycleIdentity + } +} diff --git a/internal/document/node_test.go b/internal/document/node_test.go index a6aee2196..272fe6ea8 100644 --- a/internal/document/node_test.go +++ b/internal/document/node_test.go @@ -3,11 +3,14 @@ package document import ( "testing" + "github.com/stateful/runme/internal/document/identity" "github.com/stateful/runme/internal/renderer/cmark" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +var identityResolverNone = identity.NewResolver(identity.UnspecifiedLifecycleIdentity) + var testDataNested = []byte(`> bq1 > > echo "inside bq but not fenced" @@ -32,14 +35,14 @@ echo 1 `) func TestNode_String(t *testing.T) { - doc := New(testDataNested, cmark.Render) + doc := New(testDataNested, cmark.Render, identityResolverNone) node, _, err := doc.Parse() require.NoError(t, err) assert.Equal(t, string(testDataNested), node.String()) } func TestCollectCodeBlocks(t *testing.T) { - doc := New(testDataNested, cmark.Render) + doc := New(testDataNested, cmark.Render, identityResolverNone) node, _, err := doc.Parse() require.NoError(t, err) codeBlocks := CollectCodeBlocks(node) diff --git a/internal/gen/proto/go/runme/parser/v1/parser.pb.go b/internal/gen/proto/go/runme/parser/v1/parser.pb.go index d1bdd4ef1..2c0c7d554 100644 --- a/internal/gen/proto/go/runme/parser/v1/parser.pb.go +++ b/internal/gen/proto/go/runme/parser/v1/parser.pb.go @@ -530,66 +530,18 @@ func (x *DeserializeResponse) GetNotebook() *Notebook { return nil } -type SerializeRequestOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Identity RunmeIdentity `protobuf:"varint,1,opt,name=identity,proto3,enum=runme.parser.v1.RunmeIdentity" json:"identity,omitempty"` -} - -func (x *SerializeRequestOptions) Reset() { - *x = SerializeRequestOptions{} - if protoimpl.UnsafeEnabled { - mi := &file_runme_parser_v1_parser_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SerializeRequestOptions) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SerializeRequestOptions) ProtoMessage() {} - -func (x *SerializeRequestOptions) ProtoReflect() protoreflect.Message { - mi := &file_runme_parser_v1_parser_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SerializeRequestOptions.ProtoReflect.Descriptor instead. -func (*SerializeRequestOptions) Descriptor() ([]byte, []int) { - return file_runme_parser_v1_parser_proto_rawDescGZIP(), []int{7} -} - -func (x *SerializeRequestOptions) GetIdentity() RunmeIdentity { - if x != nil { - return x.Identity - } - return RunmeIdentity_RUNME_IDENTITY_UNSPECIFIED -} - type SerializeRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Notebook *Notebook `protobuf:"bytes,1,opt,name=notebook,proto3" json:"notebook,omitempty"` - Options *SerializeRequestOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"` + Notebook *Notebook `protobuf:"bytes,1,opt,name=notebook,proto3" json:"notebook,omitempty"` } func (x *SerializeRequest) Reset() { *x = SerializeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_runme_parser_v1_parser_proto_msgTypes[8] + mi := &file_runme_parser_v1_parser_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -602,7 +554,7 @@ func (x *SerializeRequest) String() string { func (*SerializeRequest) ProtoMessage() {} func (x *SerializeRequest) ProtoReflect() protoreflect.Message { - mi := &file_runme_parser_v1_parser_proto_msgTypes[8] + mi := &file_runme_parser_v1_parser_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -615,7 +567,7 @@ func (x *SerializeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SerializeRequest.ProtoReflect.Descriptor instead. func (*SerializeRequest) Descriptor() ([]byte, []int) { - return file_runme_parser_v1_parser_proto_rawDescGZIP(), []int{8} + return file_runme_parser_v1_parser_proto_rawDescGZIP(), []int{7} } func (x *SerializeRequest) GetNotebook() *Notebook { @@ -625,13 +577,6 @@ func (x *SerializeRequest) GetNotebook() *Notebook { return nil } -func (x *SerializeRequest) GetOptions() *SerializeRequestOptions { - if x != nil { - return x.Options - } - return nil -} - type SerializeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -643,7 +588,7 @@ type SerializeResponse struct { func (x *SerializeResponse) Reset() { *x = SerializeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_runme_parser_v1_parser_proto_msgTypes[9] + mi := &file_runme_parser_v1_parser_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -656,7 +601,7 @@ func (x *SerializeResponse) String() string { func (*SerializeResponse) ProtoMessage() {} func (x *SerializeResponse) ProtoReflect() protoreflect.Message { - mi := &file_runme_parser_v1_parser_proto_msgTypes[9] + mi := &file_runme_parser_v1_parser_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -669,7 +614,7 @@ func (x *SerializeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SerializeResponse.ProtoReflect.Descriptor instead. func (*SerializeResponse) Descriptor() ([]byte, []int) { - return file_runme_parser_v1_parser_proto_rawDescGZIP(), []int{9} + return file_runme_parser_v1_parser_proto_rawDescGZIP(), []int{8} } func (x *SerializeResponse) GetResult() []byte { @@ -745,55 +690,45 @@ var file_runme_parser_v1_parser_proto_rawDesc = []byte{ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x65, 0x62, - 0x6f, 0x6f, 0x6b, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x22, 0x55, 0x0a, - 0x17, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, - 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, - 0x6d, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x22, 0x8d, 0x01, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, - 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x6e, 0x6f, 0x74, - 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, - 0x6e, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, - 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, - 0x12, 0x42, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x2b, 0x0a, 0x11, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x2a, 0x4f, 0x0a, 0x08, 0x43, 0x65, 0x6c, 0x6c, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x19, 0x0a, - 0x15, 0x43, 0x45, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x45, 0x4c, 0x4c, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x52, 0x4b, 0x55, 0x50, 0x10, 0x01, 0x12, 0x12, - 0x0a, 0x0e, 0x43, 0x45, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, 0x4f, 0x44, 0x45, - 0x10, 0x02, 0x2a, 0x7d, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x6d, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x55, 0x4e, 0x4d, 0x45, 0x5f, 0x49, 0x44, 0x45, - 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x55, 0x4e, 0x4d, 0x45, 0x5f, 0x49, 0x44, 0x45, - 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x52, - 0x55, 0x4e, 0x4d, 0x45, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x44, 0x4f, - 0x43, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x55, 0x4e, 0x4d, - 0x45, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x43, 0x45, 0x4c, 0x4c, 0x10, - 0x03, 0x32, 0xc1, 0x01, 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x5a, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, - 0x7a, 0x65, 0x12, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, - 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x65, 0x72, 0x69, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x54, 0x0a, 0x09, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x2e, 0x72, - 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4a, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x66, 0x75, 0x6c, 0x2f, 0x72, 0x75, 0x6e, - 0x6d, 0x65, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2f, 0x70, - 0x61, 0x72, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x76, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6f, 0x6b, 0x52, 0x08, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x22, 0x49, 0x0a, + 0x10, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x35, 0x0a, 0x08, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x52, 0x08, + 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x22, 0x2b, 0x0a, 0x11, 0x53, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2a, 0x4f, 0x0a, 0x08, 0x43, 0x65, 0x6c, 0x6c, 0x4b, 0x69, 0x6e, + 0x64, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x45, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, + 0x43, 0x45, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x41, 0x52, 0x4b, 0x55, 0x50, + 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x45, 0x4c, 0x4c, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, + 0x43, 0x4f, 0x44, 0x45, 0x10, 0x02, 0x2a, 0x7d, 0x0a, 0x0d, 0x52, 0x75, 0x6e, 0x6d, 0x65, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x55, 0x4e, 0x4d, 0x45, + 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x55, 0x4e, 0x4d, 0x45, + 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, + 0x1b, 0x0a, 0x17, 0x52, 0x55, 0x4e, 0x4d, 0x45, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, + 0x59, 0x5f, 0x44, 0x4f, 0x43, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, + 0x52, 0x55, 0x4e, 0x4d, 0x45, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, 0x43, + 0x45, 0x4c, 0x4c, 0x10, 0x03, 0x32, 0xc1, 0x01, 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5a, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x65, 0x72, + 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x65, 0x72, 0x69, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x75, + 0x6e, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x09, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x12, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x4a, 0x5a, 0x48, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x66, 0x75, 0x6c, + 0x2f, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, + 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x72, 0x75, 0x6e, + 0x6d, 0x65, 0x2f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -809,7 +744,7 @@ func file_runme_parser_v1_parser_proto_rawDescGZIP() []byte { } var file_runme_parser_v1_parser_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_runme_parser_v1_parser_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_runme_parser_v1_parser_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_runme_parser_v1_parser_proto_goTypes = []interface{}{ (CellKind)(0), // 0: runme.parser.v1.CellKind (RunmeIdentity)(0), // 1: runme.parser.v1.RunmeIdentity @@ -820,34 +755,31 @@ var file_runme_parser_v1_parser_proto_goTypes = []interface{}{ (*DeserializeRequestOptions)(nil), // 6: runme.parser.v1.DeserializeRequestOptions (*DeserializeRequest)(nil), // 7: runme.parser.v1.DeserializeRequest (*DeserializeResponse)(nil), // 8: runme.parser.v1.DeserializeResponse - (*SerializeRequestOptions)(nil), // 9: runme.parser.v1.SerializeRequestOptions - (*SerializeRequest)(nil), // 10: runme.parser.v1.SerializeRequest - (*SerializeResponse)(nil), // 11: runme.parser.v1.SerializeResponse - nil, // 12: runme.parser.v1.Notebook.MetadataEntry - nil, // 13: runme.parser.v1.Cell.MetadataEntry + (*SerializeRequest)(nil), // 9: runme.parser.v1.SerializeRequest + (*SerializeResponse)(nil), // 10: runme.parser.v1.SerializeResponse + nil, // 11: runme.parser.v1.Notebook.MetadataEntry + nil, // 12: runme.parser.v1.Cell.MetadataEntry } var file_runme_parser_v1_parser_proto_depIdxs = []int32{ 4, // 0: runme.parser.v1.Notebook.cells:type_name -> runme.parser.v1.Cell - 12, // 1: runme.parser.v1.Notebook.metadata:type_name -> runme.parser.v1.Notebook.MetadataEntry + 11, // 1: runme.parser.v1.Notebook.metadata:type_name -> runme.parser.v1.Notebook.MetadataEntry 5, // 2: runme.parser.v1.Notebook.frontmatter:type_name -> runme.parser.v1.Frontmatter 0, // 3: runme.parser.v1.Cell.kind:type_name -> runme.parser.v1.CellKind - 13, // 4: runme.parser.v1.Cell.metadata:type_name -> runme.parser.v1.Cell.MetadataEntry + 12, // 4: runme.parser.v1.Cell.metadata:type_name -> runme.parser.v1.Cell.MetadataEntry 3, // 5: runme.parser.v1.Cell.text_range:type_name -> runme.parser.v1.TextRange 1, // 6: runme.parser.v1.DeserializeRequestOptions.identity:type_name -> runme.parser.v1.RunmeIdentity 6, // 7: runme.parser.v1.DeserializeRequest.options:type_name -> runme.parser.v1.DeserializeRequestOptions 2, // 8: runme.parser.v1.DeserializeResponse.notebook:type_name -> runme.parser.v1.Notebook - 1, // 9: runme.parser.v1.SerializeRequestOptions.identity:type_name -> runme.parser.v1.RunmeIdentity - 2, // 10: runme.parser.v1.SerializeRequest.notebook:type_name -> runme.parser.v1.Notebook - 9, // 11: runme.parser.v1.SerializeRequest.options:type_name -> runme.parser.v1.SerializeRequestOptions - 7, // 12: runme.parser.v1.ParserService.Deserialize:input_type -> runme.parser.v1.DeserializeRequest - 10, // 13: runme.parser.v1.ParserService.Serialize:input_type -> runme.parser.v1.SerializeRequest - 8, // 14: runme.parser.v1.ParserService.Deserialize:output_type -> runme.parser.v1.DeserializeResponse - 11, // 15: runme.parser.v1.ParserService.Serialize:output_type -> runme.parser.v1.SerializeResponse - 14, // [14:16] is the sub-list for method output_type - 12, // [12:14] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 2, // 9: runme.parser.v1.SerializeRequest.notebook:type_name -> runme.parser.v1.Notebook + 7, // 10: runme.parser.v1.ParserService.Deserialize:input_type -> runme.parser.v1.DeserializeRequest + 9, // 11: runme.parser.v1.ParserService.Serialize:input_type -> runme.parser.v1.SerializeRequest + 8, // 12: runme.parser.v1.ParserService.Deserialize:output_type -> runme.parser.v1.DeserializeResponse + 10, // 13: runme.parser.v1.ParserService.Serialize:output_type -> runme.parser.v1.SerializeResponse + 12, // [12:14] is the sub-list for method output_type + 10, // [10:12] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_runme_parser_v1_parser_proto_init() } @@ -941,18 +873,6 @@ func file_runme_parser_v1_parser_proto_init() { } } file_runme_parser_v1_parser_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SerializeRequestOptions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_runme_parser_v1_parser_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SerializeRequest); i { case 0: return &v.state @@ -964,7 +884,7 @@ func file_runme_parser_v1_parser_proto_init() { return nil } } - file_runme_parser_v1_parser_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_runme_parser_v1_parser_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SerializeResponse); i { case 0: return &v.state @@ -983,7 +903,7 @@ func file_runme_parser_v1_parser_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_runme_parser_v1_parser_proto_rawDesc, NumEnums: 2, - NumMessages: 12, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/gen/proto/ts/runme/parser/v1/parser_pb.d.ts b/internal/gen/proto/ts/runme/parser/v1/parser_pb.d.ts index f8f6482e5..5973109e3 100644 --- a/internal/gen/proto/ts/runme/parser/v1/parser_pb.d.ts +++ b/internal/gen/proto/ts/runme/parser/v1/parser_pb.d.ts @@ -111,15 +111,6 @@ export interface DeserializeResponse { */ notebook?: Notebook; } -/** - * @generated from protobuf message runme.parser.v1.SerializeRequestOptions - */ -export interface SerializeRequestOptions { - /** - * @generated from protobuf field: runme.parser.v1.RunmeIdentity identity = 1; - */ - identity: RunmeIdentity; -} /** * @generated from protobuf message runme.parser.v1.SerializeRequest */ @@ -128,10 +119,6 @@ export interface SerializeRequest { * @generated from protobuf field: runme.parser.v1.Notebook notebook = 1; */ notebook?: Notebook; - /** - * @generated from protobuf field: runme.parser.v1.SerializeRequestOptions options = 2; - */ - options?: SerializeRequestOptions; } /** * @generated from protobuf message runme.parser.v1.SerializeResponse @@ -231,13 +218,6 @@ declare class DeserializeResponse$Type extends MessageType * @generated MessageType for protobuf message runme.parser.v1.DeserializeResponse */ export declare const DeserializeResponse: DeserializeResponse$Type; -declare class SerializeRequestOptions$Type extends MessageType { - constructor(); -} -/** - * @generated MessageType for protobuf message runme.parser.v1.SerializeRequestOptions - */ -export declare const SerializeRequestOptions: SerializeRequestOptions$Type; declare class SerializeRequest$Type extends MessageType { constructor(); } diff --git a/internal/gen/proto/ts/runme/parser/v1/parser_pb.js b/internal/gen/proto/ts/runme/parser/v1/parser_pb.js index 8fb4253cd..0a5fb0106 100644 --- a/internal/gen/proto/ts/runme/parser/v1/parser_pb.js +++ b/internal/gen/proto/ts/runme/parser/v1/parser_pb.js @@ -147,23 +147,10 @@ class DeserializeResponse$Type extends MessageType { */ export const DeserializeResponse = new DeserializeResponse$Type(); // @generated message type with reflection information, may provide speed optimized methods -class SerializeRequestOptions$Type extends MessageType { - constructor() { - super("runme.parser.v1.SerializeRequestOptions", [ - { no: 1, name: "identity", kind: "enum", T: () => ["runme.parser.v1.RunmeIdentity", RunmeIdentity, "RUNME_IDENTITY_"] } - ]); - } -} -/** - * @generated MessageType for protobuf message runme.parser.v1.SerializeRequestOptions - */ -export const SerializeRequestOptions = new SerializeRequestOptions$Type(); -// @generated message type with reflection information, may provide speed optimized methods class SerializeRequest$Type extends MessageType { constructor() { super("runme.parser.v1.SerializeRequest", [ - { no: 1, name: "notebook", kind: "message", T: () => Notebook }, - { no: 2, name: "options", kind: "message", T: () => SerializeRequestOptions } + { no: 1, name: "notebook", kind: "message", T: () => Notebook } ]); } } diff --git a/internal/gen/proto/ts/runme/parser/v1/parser_pb.ts b/internal/gen/proto/ts/runme/parser/v1/parser_pb.ts index efc3c796b..5b41b1e16 100644 --- a/internal/gen/proto/ts/runme/parser/v1/parser_pb.ts +++ b/internal/gen/proto/ts/runme/parser/v1/parser_pb.ts @@ -385,43 +385,6 @@ export class DeserializeResponse extends Message { } } -/** - * @generated from message runme.parser.v1.SerializeRequestOptions - */ -export class SerializeRequestOptions extends Message { - /** - * @generated from field: runme.parser.v1.RunmeIdentity identity = 1; - */ - identity = RunmeIdentity.UNSPECIFIED; - - constructor(data?: PartialMessage) { - super(); - proto3.util.initPartial(data, this); - } - - static readonly runtime: typeof proto3 = proto3; - static readonly typeName = "runme.parser.v1.SerializeRequestOptions"; - static readonly fields: FieldList = proto3.util.newFieldList(() => [ - { no: 1, name: "identity", kind: "enum", T: proto3.getEnumType(RunmeIdentity) }, - ]); - - static fromBinary(bytes: Uint8Array, options?: Partial): SerializeRequestOptions { - return new SerializeRequestOptions().fromBinary(bytes, options); - } - - static fromJson(jsonValue: JsonValue, options?: Partial): SerializeRequestOptions { - return new SerializeRequestOptions().fromJson(jsonValue, options); - } - - static fromJsonString(jsonString: string, options?: Partial): SerializeRequestOptions { - return new SerializeRequestOptions().fromJsonString(jsonString, options); - } - - static equals(a: SerializeRequestOptions | PlainMessage | undefined, b: SerializeRequestOptions | PlainMessage | undefined): boolean { - return proto3.util.equals(SerializeRequestOptions, a, b); - } -} - /** * @generated from message runme.parser.v1.SerializeRequest */ @@ -431,11 +394,6 @@ export class SerializeRequest extends Message { */ notebook?: Notebook; - /** - * @generated from field: runme.parser.v1.SerializeRequestOptions options = 2; - */ - options?: SerializeRequestOptions; - constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -445,7 +403,6 @@ export class SerializeRequest extends Message { static readonly typeName = "runme.parser.v1.SerializeRequest"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ { no: 1, name: "notebook", kind: "message", T: Notebook }, - { no: 2, name: "options", kind: "message", T: SerializeRequestOptions }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): SerializeRequest { diff --git a/internal/runner/command.go b/internal/runner/command.go index 2f36b0495..83d4177cb 100644 --- a/internal/runner/command.go +++ b/internal/runner/command.go @@ -15,7 +15,7 @@ import ( "github.com/creack/pty" "github.com/pkg/errors" - "github.com/stateful/runme/internal/identity" + ulid "github.com/stateful/runme/internal/ulid" "go.uber.org/multierr" "go.uber.org/zap" ) @@ -198,7 +198,7 @@ func newCommand(cfg *commandConfig) (*command, error) { extraArgs = append(extraArgs, "-c", script) case CommandModeTempFile: for { - id := identity.GenerateID() + id := ulid.GenerateID() tempScriptFile = filepath.Join(cfg.Directory, fmt.Sprintf(".runme-script-%s", id)) if fileExtension != "" { diff --git a/internal/runner/service.go b/internal/runner/service.go index 715067e7e..67b30bbce 100644 --- a/internal/runner/service.go +++ b/internal/runner/service.go @@ -11,8 +11,8 @@ import ( "github.com/pkg/errors" "github.com/stateful/runme/internal/env" runnerv1 "github.com/stateful/runme/internal/gen/proto/go/runme/runner/v1" - "github.com/stateful/runme/internal/identity" "github.com/stateful/runme/internal/rbuffer" + ulid "github.com/stateful/runme/internal/ulid" "github.com/stateful/runme/pkg/project" "go.uber.org/zap" "golang.org/x/sync/errgroup" @@ -155,7 +155,7 @@ func ConvertRunnerProject(runnerProj *runnerv1.Project) (project.Project, error) } func (r *runnerService) Execute(srv runnerv1.RunnerService_ExecuteServer) error { - logger := r.logger.With(zap.String("_id", identity.GenerateID())) + logger := r.logger.With(zap.String("_id", ulid.GenerateID())) logger.Info("running Execute in runnerService") diff --git a/internal/runner/session.go b/internal/runner/session.go index b63c6710b..c4716509c 100644 --- a/internal/runner/session.go +++ b/internal/runner/session.go @@ -5,7 +5,7 @@ import ( "sync" lru "github.com/hashicorp/golang-lru/v2" - "github.com/stateful/runme/internal/identity" + ulid "github.com/stateful/runme/internal/ulid" "github.com/stateful/runme/pkg/project" "go.uber.org/zap" ) @@ -36,7 +36,7 @@ func NewSession(envs []string, proj project.Project, logger *zap.Logger) (*Sessi } s := &Session{ - ID: identity.GenerateID(), + ID: ulid.GenerateID(), envStore: newEnvStore(sessionEnvs...), logger: logger, diff --git a/internal/runner/shell_session.go b/internal/runner/shell_session.go index 7d1aa344d..ebab2e5a8 100644 --- a/internal/runner/shell_session.go +++ b/internal/runner/shell_session.go @@ -8,8 +8,8 @@ import ( "github.com/creack/pty" "github.com/pkg/errors" - "github.com/stateful/runme/internal/identity" xpty "github.com/stateful/runme/internal/pty" + ulid "github.com/stateful/runme/internal/ulid" "golang.org/x/term" ) @@ -25,7 +25,7 @@ type ShellSession struct { } func NewShellSession(command string) (*ShellSession, error) { - id := identity.GenerateID() + id := ulid.GenerateID() cmd := exec.Command(command) cmd.Env = append(os.Environ(), "RUNMESHELL="+id) diff --git a/internal/identity/generator.go b/internal/ulid/generator.go similarity index 100% rename from internal/identity/generator.go rename to internal/ulid/generator.go diff --git a/internal/identity/generator_test.go b/internal/ulid/generator_test.go similarity index 100% rename from internal/identity/generator_test.go rename to internal/ulid/generator_test.go diff --git a/pkg/project/document.go b/pkg/project/document.go index c05f80dfb..c12673157 100644 --- a/pkg/project/document.go +++ b/pkg/project/document.go @@ -9,6 +9,7 @@ import ( "github.com/go-git/go-billy/v5/util" "github.com/pkg/errors" "github.com/stateful/runme/internal/document" + "github.com/stateful/runme/internal/document/identity" "github.com/stateful/runme/internal/renderer/cmark" ) @@ -60,7 +61,8 @@ func parseDocumentForCodeBlocks(filepath string, fs billy.Basic, doFrontmatter b fmtr = &f } - doc := document.New(data, cmark.Render) + identityResolver := identity.NewResolver(identity.DefaultLifecycleIdentity) + doc := document.New(data, cmark.Render, identityResolver) node, _, err := doc.Parse() if err != nil { return nil, nil, err diff --git a/pkg/project/formatter.go b/pkg/project/formatter.go index 3dd7b1244..981cc41a2 100644 --- a/pkg/project/formatter.go +++ b/pkg/project/formatter.go @@ -13,6 +13,7 @@ import ( "github.com/pkg/errors" "github.com/stateful/runme/internal/document" "github.com/stateful/runme/internal/document/editor" + "github.com/stateful/runme/internal/document/identity" "github.com/stateful/runme/internal/renderer/cmark" ) @@ -26,9 +27,10 @@ func Format(files []string, basePath string, flatten bool, formatJSON bool, writ } var formatted []byte + identityResolver := identity.NewResolver(identity.DefaultLifecycleIdentity) if flatten { - notebook, err := editor.Deserialize(data, false) + notebook, err := editor.Deserialize(data, identityResolver) if err != nil { return errors.Wrap(err, "failed to deserialize") } @@ -42,13 +44,17 @@ func Format(files []string, basePath string, flatten bool, formatJSON bool, writ } formatted = buf.Bytes() } else { + if identityResolver.CellEnabled() { + notebook.ForceLifecyleIdentities() + } + formatted, err = editor.Serialize(notebook) if err != nil { return errors.Wrap(err, "failed to serialize") } } } else { - doc := document.New(data, cmark.Render) + doc := document.New(data, cmark.Render, identityResolver) _, astNode, err := doc.Parse() if err != nil { return errors.Wrap(err, "failed to parse source") diff --git a/pkg/project/project_test.go b/pkg/project/project_test.go index 8d0118af3..b4dfd367f 100644 --- a/pkg/project/project_test.go +++ b/pkg/project/project_test.go @@ -14,12 +14,16 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/storage/filesystem" "github.com/stateful/runme/internal/document" + "github.com/stateful/runme/internal/document/identity" "github.com/stateful/runme/internal/renderer/cmark" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -var pfs = projectDir() +var ( + identityResolverNone = identity.NewResolver(identity.UnspecifiedLifecycleIdentity) + pfs = projectDir() +) func Test_CodeBlocks(t *testing.T) { t.Run("LookupWithFile", func(t *testing.T) { @@ -32,7 +36,7 @@ func Test_CodeBlocks(t *testing.T) { bytes, err := util.ReadFile(lfs, file) require.NoError(t, err) - doc := document.New(bytes, cmark.Render) + doc := document.New(bytes, cmark.Render, identityResolverNone) node, _, err := doc.Parse() require.NoError(t, err)