Skip to content
Open
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
41 changes: 41 additions & 0 deletions stovepipe/core/filter/filter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2025 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package filter implements a filter for commit events.
package filter

import (
"strings"

"github.com/uber/submitqueue/stovepipe/entity"
)

// Config controls which VCS URIs are watched.
// WatchedURIPrefixes is a list of URI prefixes to match against ChangeInfo.URI.
// Example: "git://github.com/uber/go-code/refs/heads/main"
// watches all commits on the main branch of uber/go-code.
type Config struct {
WatchedURIPrefixes []string
}

// ShouldProcess returns true if the commit event's URI matches
// any of the configured watched prefixes.
func ShouldProcess(cfg Config, event entity.ChangeInfo) bool {
for _, prefix := range cfg.WatchedURIPrefixes {
if strings.HasPrefix(event.URI, prefix) {
return true
}
}
return false
}
37 changes: 35 additions & 2 deletions stovepipe/entity/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,46 @@
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package entity holds Stovepipe-specific domain types (distinct from shared repo entity/).
// Package entity holds Stovepipe-specific domain entities.
package entity

// ChangeInfo represents a new change detected on a VCS remote.
// It is intentionally VCS-agnostic: the URI scheme carries the
// provider identity, mirroring the github:// scheme used in
// SubmitQueue's ChangeInfo.
//
// URI format: "git://<host>/<repo>/<ref>/<new-revision>"
// Example: "git://github.com/uber/go-code/refs/heads/main/c3a4d5e6f789..."
//
// Fields are immutable after construction.
type ChangeInfo struct {
// URI is the canonical VCS identifier for this change.
// Scheme is "git://"; path encodes host, repo, ref, and new revision.
// This mirrors the ChangeInfo.URI pattern used in SubmitQueue.
URI string `json:"uri"`

// PreviousURI is the URI of the prior revision on the same ref, if known.
// Empty string if unavailable.
// Example: "git://github.com/uber/go-code/refs/heads/main/aabbccdd..."
PreviousURI string `json:"previous_uri,omitempty"`

// Author is the identity of the person who authored the change.
Author Author `json:"author"`
}

// Author identifies the person who authored a change.
// Mirrors SubmitQueue's Author to keep the two domains consistent.
type Author struct {
// Name is the display name of the author.
Name string `json:"name"`
// Email is the email address of the author.
Email string `json:"email,omitempty"`
}
46 changes: 46 additions & 0 deletions stovepipe/extension/changeingester/logging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2025 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package changeingester provides ChangeIngester implementations.
package changeingester

import (
"context"

"github.com/uber/submitqueue/stovepipe/entity"
"github.com/uber/submitqueue/stovepipe/extension"
"go.uber.org/zap"
)

// LoggingHandler is a stub ChangeHandler that logs received changes.
// Replace with real persistence logic once DB schema is ready.
type LoggingHandler struct {
logger *zap.Logger
}

// New constructs a new LoggingHandler.
// The return type enforces interface compliance at compile time.
func New(logger *zap.Logger) extension.ChangeHandler {
return LoggingHandler{logger: logger}
}

func (h LoggingHandler) IngestChange(ctx context.Context, info entity.ChangeInfo) error {
h.logger.Info("ingested change",
zap.String("uri", info.URI),
zap.String("previous_uri", info.PreviousURI),
zap.String("author", info.Author.Name),
zap.String("author_email", info.Author.Email),
)
return nil
}
18 changes: 18 additions & 0 deletions stovepipe/extension/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,21 @@

// Package extension holds Stovepipe-specific extension implementations.
package extension

import (
"context"

"github.com/uber/submitqueue/stovepipe/entity"
)

// ChangeIngester subscribes to change events from a VCS source
// and dispatches them for processing. The source and VCS are
// implementation details left to the injected backend.
type ChangeIngester interface {
Start(ctx context.Context) error
}

// ChangeHandler processes a single change received from the ingester.
type ChangeHandler interface {
IngestChange(ctx context.Context, info entity.ChangeInfo) error
}
Loading