Function bodies 64 total
main.run function · go · L92-L133 (42 LOC)cmd/ladle/main.go
func run(cmd *cobra.Command, args []string, f *flags) error {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
// Handle completion installation
if f.installComp != "" {
return completion.Generate(os.Stdout, completion.Shell(f.installComp))
}
if len(args) == 0 {
return cmd.Help()
}
u, err := uri.Parse(args[0])
if err != nil {
return err
}
client, err := newClient(ctx, u, f)
if err != nil {
return err
}
// Handle internal completion helpers
if f.completeBucket {
return handleCompleteBucket(ctx, client, u, f.profile)
}
if f.completePath {
return handleCompletePath(ctx, client, u)
}
// Directory => browser mode
if u.IsDirectory() {
return runBrowser(ctx, client, u, f)
}
// File editing
if f.meta {
return runMetaEdit(ctx, client, u, f)
}
return runFileEdit(ctx, client, u, f)
}main.newClient function · go · L135-L147 (13 LOC)cmd/ladle/main.go
func newClient(ctx context.Context, u *uri.URI, f *flags) (storage.Client, error) {
switch u.Scheme {
case uri.SchemeS3:
return s3client.New(ctx, s3client.Options{
Profile: f.profile,
Region: f.region,
EndpointURL: f.endpointURL,
NoSignRequest: f.noSignRequest,
})
default:
return nil, fmt.Errorf("scheme %q is not yet supported (coming soon)", u.Scheme)
}
}main.runFileEdit function · go · L149-L239 (91 LOC)cmd/ladle/main.go
func runFileEdit(ctx context.Context, client storage.Client, u *uri.URI, f *flags) error {
// Download file
var buf strings.Builder
sp := spinner.New(os.Stderr, fmt.Sprintf("Downloading %s ...", u))
sp.Start()
if err := client.Download(ctx, u.Bucket, u.Key, &buf); err != nil {
sp.Stop()
return err
}
sp.StopWithMessage(fmt.Sprintf("✓ Downloaded %s", u))
original := buf.String()
// Binary check
if editor.IsBinary([]byte(original)) && !f.force {
fmt.Fprintf(os.Stderr, "Warning: %s appears to be a binary file.\n", u)
fmt.Fprintf(os.Stderr, "Use --force to edit anyway.\n")
return fmt.Errorf("binary file detected")
}
// Create temp file
filename := filepath.Base(u.Key)
tmpPath, err := editor.TempFile(filename, []byte(original))
if err != nil {
return err
}
// Crash recovery: print temp path on interrupt
fmt.Fprintf(os.Stderr, "Temp file: %s\n", tmpPath)
// Open editor
editorCmd := editor.ResolveEditor(f.editorCmd)
if err := editor.Open(editorCmd, tmpPath)main.runMetaEdit function · go · L241-L321 (81 LOC)cmd/ladle/main.go
func runMetaEdit(ctx context.Context, client storage.Client, u *uri.URI, f *flags) error {
// Fetch metadata
sp := spinner.New(os.Stderr, fmt.Sprintf("Fetching metadata for %s ...", u))
sp.Start()
objMeta, err := client.HeadObject(ctx, u.Bucket, u.Key)
if err != nil {
sp.Stop()
return err
}
sp.StopWithMessage(fmt.Sprintf("✓ Fetched metadata for %s", u))
// Marshal to YAML
originalYAML, err := meta.Marshal(u.String(), objMeta)
if err != nil {
return err
}
originalStr := string(originalYAML)
// Create temp file
tmpPath, err := editor.TempFile("metadata.yaml", originalYAML)
if err != nil {
return err
}
fmt.Fprintf(os.Stderr, "Temp file: %s\n", tmpPath)
// Open editor
editorCmd := editor.ResolveEditor(f.editorCmd)
if err := editor.Open(editorCmd, tmpPath); err != nil {
fmt.Fprintf(os.Stderr, "Recovery: your edits are saved at %s\n", tmpPath)
return err
}
// Read modified content
modifiedBytes, err := os.ReadFile(tmpPath)
if err != nil {
return fmt.main.runBrowser function · go · L323-L347 (25 LOC)cmd/ladle/main.go
func runBrowser(ctx context.Context, client storage.Client, u *uri.URI, f *flags) error {
b := browser.New(client, u, os.Stdin, os.Stderr)
for {
sel, err := b.Run(ctx)
if err != nil {
return err
}
if sel.Action == browser.ActionQuit {
return nil
}
if sel.Action == browser.ActionEdit {
if f.meta {
if err := runMetaEdit(ctx, client, sel.URI, f); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
}
} else {
if err := runFileEdit(ctx, client, sel.URI, f); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
}
}
// Return to browser after editing
continue
}
}
}main.handleCompleteBucket function · go · L351-L366 (16 LOC)cmd/ladle/main.go
func handleCompleteBucket(ctx context.Context, client storage.Client, u *uri.URI, profile string) error {
buckets, err := loadBucketCache(profile)
if err != nil {
buckets, err = client.ListBuckets(ctx)
if err != nil {
return nil // Silently fail for completions
}
_ = saveBucketCache(profile, buckets)
}
for _, b := range buckets {
if strings.HasPrefix(b, u.Bucket) {
fmt.Println(b)
}
}
return nil
}main.bucketCachePath function · go · L368-L377 (10 LOC)cmd/ladle/main.go
func bucketCachePath(profile string) string {
if profile == "" {
profile = "default"
}
home, err := os.UserHomeDir()
if err != nil {
return ""
}
return filepath.Join(home, ".cache", "ladle", "buckets_"+profile+".cache")
}Same scanner, your repo: https://repobility.com — Repobility
main.loadBucketCache function · go · L379-L397 (19 LOC)cmd/ladle/main.go
func loadBucketCache(profile string) ([]string, error) {
p := bucketCachePath(profile)
info, err := os.Stat(p)
if err != nil {
return nil, err
}
if time.Since(info.ModTime()) > bucketCacheTTL {
return nil, fmt.Errorf("cache expired")
}
data, err := os.ReadFile(p)
if err != nil {
return nil, err
}
content := strings.TrimSpace(string(data))
if content == "" {
return nil, nil
}
return strings.Split(content, "\n"), nil
}main.saveBucketCache function · go · L399-L405 (7 LOC)cmd/ladle/main.go
func saveBucketCache(profile string, buckets []string) error {
p := bucketCachePath(profile)
if err := os.MkdirAll(filepath.Dir(p), 0700); err != nil {
return err
}
return os.WriteFile(p, []byte(strings.Join(buckets, "\n")+"\n"), 0600)
}main.confirm function · go · L419-L427 (9 LOC)cmd/ladle/main.go
func confirm(in io.Reader, out io.Writer, prompt string) bool {
fmt.Fprintf(out, "%s [y/N]: ", prompt)
scanner := bufio.NewScanner(in)
if !scanner.Scan() {
return false
}
answer := strings.TrimSpace(strings.ToLower(scanner.Text()))
return answer == "y" || answer == "yes"
}browser.New function · go · L79-L92 (14 LOC)internal/browser/browser.go
func New(client storage.Client, u *uri.URI, in *os.File, out io.Writer) *Browser {
return &Browser{
client: client,
scheme: u.Scheme,
bucket: u.Bucket,
prefix: u.Key,
bucketListEnabled: u.IsBucketList(),
fd: int(in.Fd()),
in: in,
out: out,
expanded: make(map[string]bool),
childCache: make(map[string][]storage.ListEntry),
}
}browser.Browser.termHeight method · go · L95-L104 (10 LOC)internal/browser/browser.go
func (b *Browser) termHeight() int {
if b.heightOverride > 0 {
return b.heightOverride
}
_, h, err := term.GetSize(b.fd)
if err != nil || h <= 0 {
return 1000 // fallback: no scrolling
}
return h
}browser.Browser.Run method · go · L107-L118 (12 LOC)internal/browser/browser.go
func (b *Browser) Run(ctx context.Context) (*Selection, error) {
oldState, err := term.MakeRaw(b.fd)
if err != nil {
return nil, fmt.Errorf("setting terminal raw mode: %w", err)
}
defer func() { _ = term.Restore(b.fd, oldState) }()
_, _ = fmt.Fprint(b.out, ansiAltScreenOn+ansiHideCursor)
defer func() { _, _ = fmt.Fprint(b.out, ansiShowCursor+ansiAltScreenOff) }()
return b.runLoop(ctx)
}browser.Browser.buildItems method · go · L186-L194 (9 LOC)internal/browser/browser.go
func (b *Browser) buildItems(entries []storage.ListEntry) []item {
var items []item
b.appendTreeItems(&items, entries, b.prefix, 0)
if b.prefix != "" || b.bucketListEnabled {
items = append(items, item{label: "..", isNav: true, navID: "up"})
}
items = append(items, item{label: "quit", isNav: true, navID: "quit"})
return items
}browser.Browser.appendTreeItems method · go · L197-L215 (19 LOC)internal/browser/browser.go
func (b *Browser) appendTreeItems(items *[]item, entries []storage.ListEntry, prefix string, depth int) {
for _, e := range entries {
name := strings.TrimPrefix(e.Key, prefix)
if name == "" {
continue
}
*items = append(*items, item{
label: name,
entry: e,
isDir: e.IsDir,
depth: depth,
})
if e.IsDir && b.expanded[e.Key] {
if children, ok := b.childCache[e.Key]; ok {
b.appendTreeItems(items, children, e.Key, depth+1)
}
}
}
}Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
browser.Browser.handleInput method · go · L221-L343 (123 LOC)internal/browser/browser.go
func (b *Browser) handleInput(ctx context.Context, items []item, cursor int) (int, bool, []item) {
filter := ""
filtering := false
visible := allIndices(len(items))
scrollOffset := 0
if cursor >= len(visible) {
cursor = len(visible) - 1
}
if cursor < 0 {
cursor = 0
}
b.renderFiltered(items, visible, cursor, filter, filtering, &scrollOffset)
buf := make([]byte, 3)
for {
n, err := b.in.Read(buf)
if err != nil {
return 0, true, items
}
if filtering {
changed := false
if n == 1 {
switch buf[0] {
case 27: // Escape — clear filter and exit filter mode
filter = ""
filtering = false
changed = true
case 13: // Enter — exit filter mode, keep filter
filtering = false
case 127, 8: // Backspace / Ctrl+H
if len(filter) > 0 {
filter = filter[:len(filter)-1]
changed = true
}
default:
if buf[0] >= 32 && buf[0] < 127 {
filter += string(buf[0])
changed = true
}
}
} else if n == 3browser.Browser.expandDir method · go · L346-L364 (19 LOC)internal/browser/browser.go
func (b *Browser) expandDir(ctx context.Context, items []item, visible []int, cursor int, filter string) ([]item, []int, int) {
if len(visible) == 0 {
return items, visible, cursor
}
it := items[visible[cursor]]
if it.isDir && !it.isNav && it.entry.Key != "" && !b.expanded[it.entry.Key] {
children, err := b.client.List(ctx, b.bucket, it.entry.Key, "/")
if err == nil {
b.childCache[it.entry.Key] = children
b.expanded[it.entry.Key] = true
items = b.rebuildItems(ctx, items)
visible = filterIndices(items, filter)
if cursor >= len(visible) {
cursor = len(visible) - 1
}
}
}
return items, visible, cursor
}browser.Browser.collapseDir method · go · L367-L383 (17 LOC)internal/browser/browser.go
func (b *Browser) collapseDir(ctx context.Context, items []item, visible []int, cursor int, filter string) ([]item, []int, int) {
if len(visible) == 0 {
return items, visible, cursor
}
it := items[visible[cursor]]
if it.isDir && !it.isNav && b.expanded[it.entry.Key] {
delete(b.expanded, it.entry.Key)
items = b.rebuildItems(ctx, items)
visible = filterIndices(items, filter)
if cursor >= len(visible) {
cursor = len(visible) - 1
}
} else if it.depth > 0 {
cursor = b.findParentIndex(items, visible, cursor)
}
return items, visible, cursor
}browser.Browser.rebuildItems method · go · L387-L393 (7 LOC)internal/browser/browser.go
func (b *Browser) rebuildItems(ctx context.Context, fallback []item) []item {
entries, err := b.client.List(ctx, b.bucket, b.prefix, "/")
if err != nil {
return fallback
}
return b.buildItems(entries)
}browser.Browser.findParentIndex method · go · L396-L405 (10 LOC)internal/browser/browser.go
func (b *Browser) findParentIndex(items []item, visible []int, cursor int) int {
currentDepth := items[visible[cursor]].depth
for i := cursor - 1; i >= 0; i-- {
it := items[visible[i]]
if it.isDir && !it.isNav && it.depth < currentDepth {
return i
}
}
return cursor
}browser.allIndices function · go · L407-L413 (7 LOC)internal/browser/browser.go
func allIndices(n int) []int {
idx := make([]int, n)
for i := range idx {
idx[i] = i
}
return idx
}browser.filterIndices function · go · L415-L427 (13 LOC)internal/browser/browser.go
func filterIndices(items []item, filter string) []int {
if filter == "" {
return allIndices(len(items))
}
lower := strings.ToLower(filter)
var idx []int
for i, it := range items {
if it.isNav || strings.Contains(strings.ToLower(it.label), lower) {
idx = append(idx, i)
}
}
return idx
}browser.headerLines function · go · L435-L443 (9 LOC)internal/browser/browser.go
func headerLines(filtering bool, filter string) int {
// header: 2 lines (blank + URI)
n := 2
if filtering || filter != "" {
n++ // filter bar
}
n++ // blank line after header
return n
}Repobility (the analyzer behind this table) · https://repobility.com
browser.Browser.renderFiltered method · go · L445-L563 (119 LOC)internal/browser/browser.go
func (b *Browser) renderFiltered(items []item, visible []int, cursor int, filter string, filtering bool, scrollOffset *int) {
b.w("%s%s", ansiHome, ansiClearScreen)
// Header
if b.bucket == "" {
b.w("\r\n %s%s%s://%s\r\n", ansiBold, ansiCyan, b.scheme, ansiReset)
} else {
b.w("\r\n %s%s%s://%s/%s%s\r\n", ansiBold, ansiCyan, b.scheme, b.bucket, b.prefix, ansiReset)
}
// Filter bar
if filtering {
b.w(" %s/%s %s%s\u2588%s\r\n", ansiYellow, ansiReset, filter, ansiDim, ansiReset)
} else if filter != "" {
b.w(" %s/ %s%s\r\n", ansiDim, filter, ansiReset)
}
b.w("\r\n")
// Check if there are any non-nav visible items
hasContent := false
for _, vi := range visible {
if !items[vi].isNav {
hasContent = true
break
}
}
if !hasContent {
if filter != "" {
b.w(" %s(no matches)%s\r\n", ansiDim, ansiReset)
} else {
b.w(" %s(empty)%s\r\n", ansiDim, ansiReset)
}
}
// Calculate viewport
// Fixed overhead: header area + help (2 lines: blank + texbrowser.Browser.renderNav method · go · L565-L571 (7 LOC)internal/browser/browser.go
func (b *Browser) renderNav(it item, selected bool) {
if selected {
b.w(" %s \u25b8 %s %s\r\n", ansiReverse, it.label, ansiReset)
} else {
b.w(" %s%s%s\r\n", ansiGray, it.label, ansiReset)
}
}browser.Browser.renderDir method · go · L573-L579 (7 LOC)internal/browser/browser.go
func (b *Browser) renderDir(it item, selected bool, prefix string) {
if selected {
b.w(" %s%s%s%s\r\n", prefix, ansiReverse, it.label, ansiReset)
} else {
b.w(" %s%s%s%s%s\r\n", prefix, ansiBold, ansiBlue, it.label, ansiReset)
}
}browser.Browser.renderFile method · go · L581-L588 (8 LOC)internal/browser/browser.go
func (b *Browser) renderFile(it item, selected bool, prefix string) {
size := formatSize(it.entry.Size)
if selected {
b.w(" %s%s%-30s %s%s\r\n", prefix, ansiReverse, it.label, size, ansiReset)
} else {
b.w(" %s%-30s %s%s%s\r\n", prefix, it.label, ansiDim, size, ansiReset)
}
}browser.Browser.goUp method · go · L590-L606 (17 LOC)internal/browser/browser.go
func (b *Browser) goUp() {
if b.prefix == "" {
if b.bucketListEnabled {
b.bucket = ""
}
return
}
// Remove trailing slash
p := strings.TrimSuffix(b.prefix, "/")
// Go to parent
parent := path.Dir(p)
if parent == "." {
b.prefix = ""
} else {
b.prefix = parent + "/"
}
}browser.Browser.runBucketList method · go · L610-L643 (34 LOC)internal/browser/browser.go
func (b *Browser) runBucketList(ctx context.Context, cursor *int) (*Selection, bool, error) {
buckets, err := b.client.ListBuckets(ctx)
if err != nil {
return nil, true, fmt.Errorf("listing buckets: %w", err)
}
var items []item
for _, name := range buckets {
items = append(items, item{
label: name,
isDir: true,
})
}
items = append(items, item{label: "quit", isNav: true, navID: "quit"})
if *cursor >= len(items) {
*cursor = len(items) - 1
}
idx, quit, currentItems := b.handleInput(ctx, items, *cursor)
if quit {
return &Selection{Action: ActionQuit}, true, nil
}
sel := currentItems[idx]
if sel.isNav && sel.navID == "quit" {
return &Selection{Action: ActionQuit}, true, nil
}
b.bucket = sel.label
b.prefix = ""
*cursor = 0
return nil, false, nil
}browser.computeTreePrefixes function · go · L648-L703 (56 LOC)internal/browser/browser.go
func computeTreePrefixes(items []item, visible []int) []string {
prefixes := make([]string, len(visible))
continueLine := make(map[int]bool) // whether depth d has more siblings below
for i, vi := range visible {
it := items[vi]
if it.isNav {
prefixes[i] = ""
continue
}
// Determine if this is the last sibling at its depth among remaining visible items.
isLast := true
for j := i + 1; j < len(visible); j++ {
peer := items[visible[j]]
if peer.isNav {
continue
}
if peer.depth < it.depth {
break // went up a level — no more siblings
}
if peer.depth == it.depth {
isLast = false
break
}
}
var b strings.Builder
// Ancestor levels: draw "│ " or " "
for d := 0; d < it.depth; d++ {
if continueLine[d] {
b.WriteString("│ ")
} else {
b.WriteString(" ")
}
}
// Current level connector
if isLast {
b.WriteString("└── ")
} else {
b.WriteString("├── ")
}
// Update continueLine for this depthbrowser.formatSize function · go · L705-L721 (17 LOC)internal/browser/browser.go
func formatSize(size int64) string {
const (
kb = 1024
mb = 1024 * kb
gb = 1024 * mb
)
switch {
case size >= gb:
return fmt.Sprintf("%.1f GB", float64(size)/float64(gb))
case size >= mb:
return fmt.Sprintf("%.1f MB", float64(size)/float64(mb))
case size >= kb:
return fmt.Sprintf("%.1f KB", float64(size)/float64(kb))
default:
return fmt.Sprintf("%d B", size)
}
}Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
completion.Generate function · go · L19-L30 (12 LOC)internal/completion/completion.go
func Generate(w io.Writer, shell Shell) error {
switch shell {
case ShellBash:
return generateBash(w)
case ShellZsh:
return generateZsh(w)
case ShellFish:
return generateFish(w)
default:
return fmt.Errorf("unsupported shell: %s (supported: bash, zsh, fish)", shell)
}
}completion.generateBash function · go · L32-L96 (65 LOC)internal/completion/completion.go
func generateBash(w io.Writer) error {
script := `# ladle bash completion
_ladle_completions() {
local cur prev opts cmd
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd="${COMP_WORDS[0]}"
opts="--meta --editor --profile --region --endpoint-url --no-sign-request --yes --force --dry-run --help --version"
# Extract --profile value from command line
local profile_arg=""
for ((i=0; i<${#COMP_WORDS[@]}; i++)); do
if [[ "${COMP_WORDS[$i]}" == "--profile" ]]; then
profile_arg="--profile ${COMP_WORDS[$((i+1))]}"
elif [[ "${COMP_WORDS[$i]}" == --profile=* ]]; then
profile_arg="--profile ${COMP_WORDS[$i]#--profile=}"
fi
done
# Complete S3 URIs
if [[ "$cur" == s3://* ]]; then
local bucket_and_path="${cur#s3://}"
local bucket="${bucket_and_path%%/*}"
if [[ "$bucket_and_path" == */* ]]; then
# Complete keys within bucket
completion.generateZsh function · go · L98-L159 (62 LOC)internal/completion/completion.go
func generateZsh(w io.Writer) error {
script := `#compdef ladle
_ladle() {
local -a opts
opts=(
'--meta[Edit metadata instead of file content]'
'--editor[Specify editor command]:editor:'
'--profile[AWS named profile]:profile:'
'--region[AWS region]:region:'
'--endpoint-url[Custom endpoint URL]:url:'
'--no-sign-request[Do not sign requests]'
'--yes[Skip confirmation prompt]'
'--force[Force operation on binary files]'
'--dry-run[Show diff without uploading]'
'--help[Show help]'
'--version[Show version]'
)
_arguments -s $opts '*:uri:_ladle_uri'
}
_ladle_uri() {
local cur="${words[CURRENT]}"
local cmd="${words[1]}"
# Extract --profile value from command line
local -a profile_arg
local -i i
for ((i=1; i<$#words; i++)); do
if [[ "${words[$i]}" == "--profile" ]]; then
profile_arg=(--profile "${words[$((i+1))]}")
elif [[ "${words[$i]}"contenttype.Detect function · go · L52-L70 (19 LOC)internal/contenttype/contenttype.go
func Detect(filename string) string {
ext := strings.ToLower(filepath.Ext(filename))
if ext == "" {
return "application/octet-stream"
}
// Check extra types first
if ct, ok := extraTypes[ext]; ok {
return ct
}
// Fall back to Go's mime package
ct := mime.TypeByExtension(ext)
if ct != "" {
return ct
}
return "application/octet-stream"
}diff.Generate function · go · L11-L42 (32 LOC)internal/diff/diff.go
func Generate(original, modified, labelOrig, labelMod string) string {
origLines := splitLines(original)
modLines := splitLines(modified)
edits := lcsEdits(origLines, modLines)
// Check if there are any actual changes
hasChanges := false
for _, e := range edits {
if e.op != ' ' {
hasChanges = true
break
}
}
if !hasChanges {
return ""
}
hunks := buildHunks(edits, 3)
if len(hunks) == 0 {
return ""
}
var sb strings.Builder
sb.WriteString(fmt.Sprintf("--- %s\n", labelOrig))
sb.WriteString(fmt.Sprintf("+++ %s\n", labelMod))
for _, h := range hunks {
sb.WriteString(h.String())
}
return sb.String()
}diff.Print function · go · L45-L60 (16 LOC)internal/diff/diff.go
func Print(w io.Writer, diffText string) {
for _, line := range strings.Split(diffText, "\n") {
switch {
case strings.HasPrefix(line, "---"), strings.HasPrefix(line, "+++"):
fmt.Fprintf(w, "\033[1m%s\033[0m\n", line)
case strings.HasPrefix(line, "@@"):
fmt.Fprintf(w, "\033[36m%s\033[0m\n", line)
case strings.HasPrefix(line, "+"):
fmt.Fprintf(w, "\033[32m%s\033[0m\n", line)
case strings.HasPrefix(line, "-"):
fmt.Fprintf(w, "\033[31m%s\033[0m\n", line)
default:
fmt.Fprintln(w, line)
}
}
}diff.splitLines function · go · L62-L71 (10 LOC)internal/diff/diff.go
func splitLines(s string) []string {
if s == "" {
return nil
}
lines := strings.Split(s, "\n")
if len(lines) > 0 && lines[len(lines)-1] == "" {
lines = lines[:len(lines)-1]
}
return lines
}diff.hunk.String method · go · L91-L100 (10 LOC)internal/diff/diff.go
func (h *hunk) String() string {
var sb strings.Builder
sb.WriteString(fmt.Sprintf("@@ -%d,%d +%d,%d @@\n", h.origStart, h.origCount, h.modStart, h.modCount))
for _, l := range h.lines {
sb.WriteByte(l.op)
sb.WriteString(l.text)
sb.WriteByte('\n')
}
return sb.String()
}Same scanner, your repo: https://repobility.com — Repobility
diff.lcsEdits function · go · L103-L146 (44 LOC)internal/diff/diff.go
func lcsEdits(a, b []string) []edit {
n := len(a)
m := len(b)
// Build LCS table
dp := make([][]int, n+1)
for i := range dp {
dp[i] = make([]int, m+1)
}
for i := 1; i <= n; i++ {
for j := 1; j <= m; j++ {
if a[i-1] == b[j-1] {
dp[i][j] = dp[i-1][j-1] + 1
} else if dp[i-1][j] >= dp[i][j-1] {
dp[i][j] = dp[i-1][j]
} else {
dp[i][j] = dp[i][j-1]
}
}
}
// Backtrack to build edit script
var edits []edit
i, j := n, m
for i > 0 || j > 0 {
if i > 0 && j > 0 && a[i-1] == b[j-1] {
edits = append(edits, edit{' ', a[i-1]})
i--
j--
} else if j > 0 && (i == 0 || dp[i][j-1] >= dp[i-1][j]) {
edits = append(edits, edit{'+', b[j-1]})
j--
} else {
edits = append(edits, edit{'-', a[i-1]})
i--
}
}
// Reverse to get forward order
for l, r := 0, len(edits)-1; l < r; l, r = l+1, r-1 {
edits[l], edits[r] = edits[r], edits[l]
}
return edits
}diff.buildHunks function · go · L148-L229 (82 LOC)internal/diff/diff.go
func buildHunks(edits []edit, contextLines int) []hunk {
// Find all change ranges (contiguous runs of non-context edits)
type changeRange struct {
start, end int
}
var changes []changeRange
i := 0
for i < len(edits) {
if edits[i].op != ' ' {
start := i
for i < len(edits) && edits[i].op != ' ' {
i++
}
changes = append(changes, changeRange{start, i - 1})
} else {
i++
}
}
if len(changes) == 0 {
return nil
}
// Group changes into hunks, merging those whose context overlaps
type hunkRange struct {
start, end int
}
var hunkRanges []hunkRange
for _, cr := range changes {
ctxStart := cr.start - contextLines
if ctxStart < 0 {
ctxStart = 0
}
ctxEnd := cr.end + contextLines
if ctxEnd >= len(edits) {
ctxEnd = len(edits) - 1
}
if len(hunkRanges) > 0 && ctxStart <= hunkRanges[len(hunkRanges)-1].end+1 {
hunkRanges[len(hunkRanges)-1].end = ctxEnd
} else {
hunkRanges = append(hunkRanges, hunkRange{ctxStart, ctxEnd})
}
}
/editor.ResolveEditor function · go · L14-L24 (11 LOC)internal/editor/editor.go
func ResolveEditor(flagValue string) string {
if flagValue != "" {
return flagValue
}
for _, env := range []string{"LADLE_EDITOR", "EDITOR", "VISUAL"} {
if v := os.Getenv(env); v != "" {
return v
}
}
return "vi"
}editor.TempFile function · go · L28-L40 (13 LOC)internal/editor/editor.go
func TempFile(filename string, content []byte) (string, error) {
dir, err := os.MkdirTemp("", "ladle-*")
if err != nil {
return "", fmt.Errorf("creating temp dir: %w", err)
}
path := filepath.Join(dir, filename)
if err := os.WriteFile(path, content, 0600); err != nil {
os.RemoveAll(dir)
return "", fmt.Errorf("writing temp file: %w", err)
}
return path, nil
}editor.Open function · go · L43-L59 (17 LOC)internal/editor/editor.go
func Open(editor, filePath string) error {
parts := strings.Fields(editor)
if len(parts) == 0 {
return fmt.Errorf("empty editor command")
}
args := append(parts[1:], filePath)
cmd := exec.Command(parts[0], args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("editor exited with error: %w", err)
}
return nil
}editor.IsBinary function · go · L69-L80 (12 LOC)internal/editor/editor.go
func IsBinary(data []byte) bool {
limit := 8192
if len(data) < limit {
limit = len(data)
}
for i := 0; i < limit; i++ {
if data[i] == 0 {
return true
}
}
return false
}meta.Marshal function · go · L21-L40 (20 LOC)internal/meta/meta.go
func Marshal(uri string, meta *storage.ObjectMetadata) ([]byte, error) {
y := MetadataYAML{
ContentType: meta.ContentType,
CacheControl: meta.CacheControl,
ContentEncoding: meta.ContentEncoding,
ContentDisposition: meta.ContentDisposition,
Metadata: meta.Metadata,
}
if y.Metadata == nil {
y.Metadata = make(map[string]string)
}
data, err := yaml.Marshal(&y)
if err != nil {
return nil, fmt.Errorf("marshaling metadata: %w", err)
}
header := fmt.Sprintf("# %s\n", uri)
return append([]byte(header), data...), nil
}meta.Unmarshal function · go · L43-L60 (18 LOC)internal/meta/meta.go
func Unmarshal(data []byte) (*storage.ObjectMetadata, error) {
var y MetadataYAML
if err := yaml.Unmarshal(data, &y); err != nil {
return nil, fmt.Errorf("parsing metadata YAML: %w", err)
}
meta := &storage.ObjectMetadata{
ContentType: y.ContentType,
CacheControl: y.CacheControl,
ContentEncoding: y.ContentEncoding,
ContentDisposition: y.ContentDisposition,
Metadata: y.Metadata,
}
if meta.Metadata == nil {
meta.Metadata = make(map[string]string)
}
return meta, nil
}Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
spinner.New function · go · L25-L32 (8 LOC)internal/spinner/spinner.go
func New(w io.Writer, message string) *Spinner {
return &Spinner{
w: w,
message: message,
done: make(chan struct{}),
stopped: make(chan struct{}),
}
}spinner.Spinner.Start method · go · L35-L60 (26 LOC)internal/spinner/spinner.go
func (s *Spinner) Start() {
s.mu.Lock()
if s.running {
s.mu.Unlock()
return
}
s.running = true
s.mu.Unlock()
go func() {
ticker := time.NewTicker(80 * time.Millisecond)
defer ticker.Stop()
defer close(s.stopped)
i := 0
for {
select {
case <-s.done:
return
case <-ticker.C:
_, _ = fmt.Fprintf(s.w, "\r\033[K%s %s", frames[i%len(frames)], s.message)
i++
}
}
}()
}spinner.Spinner.Stop method · go · L63-L76 (14 LOC)internal/spinner/spinner.go
func (s *Spinner) Stop() {
s.mu.Lock()
if !s.running {
s.mu.Unlock()
return
}
s.running = false
close(s.done)
s.mu.Unlock()
// Wait for the goroutine to finish before writing to avoid data race.
<-s.stopped
_, _ = fmt.Fprintf(s.w, "\r\033[K")
}page 1 / 2next ›