# How to Glob the Top-Level Directory in the JFrame Repository

> Learn how to glob the top-level directory of a repository using Go's filepath.Glob and os.Stat functions. Easily identify directories and files in your project.

- Repository: [卷鸡科技/jframe](https://github.com/juanjitech/jframe)
- Tags: how-to-guide
- Published: 2026-03-05

---

**Use Go's `filepath.Glob("*")` function to retrieve all entries directly under the repository root, then iterate over the results with `os.Stat` to distinguish between directories like `cmd/` and configuration files like `go.mod`.**

The `juanjitech/jframe` repository is a Go-based micro-framework organized into modular directories such as `core/`, `cmd/`, and `mod/`. When you need to programmatically inspect these structural components, **globbing the top-level directory** provides a portable, pattern-matching approach that works across development environments without recursing into subdirectories.

## Understanding the JFrame Repository Structure

Before implementing glob logic, examine what resides at the repository root. The top-level directory contains both architectural folders and build configuration files:

- **Directories**: `cmd/`, `core/`, `docs/`, `mod/`, `pkg/`, `conf/`
- **Files**: [`README.md`](https://github.com/juanjitech/jframe/blob/main/README.md), `Dockerfile`, `go.mod`, `go.sum`, [`main.go`](https://github.com/juanjitech/jframe/blob/main/main.go)

While [`main.go`](https://github.com/juanjitech/jframe/blob/main/main.go) appears in root listings, the actual entry point source resides at [`main/main.go`](https://github.com/juanjitech/jframe/blob/main/main/main.go), with HTTP server logic implemented in [`cmd/server/server.go`](https://github.com/juanjitech/jframe/blob/main/cmd/server/server.go). The [`core/kernel/kernel.go`](https://github.com/juanjitech/jframe/blob/main/core/kernel/kernel.go) file orchestrates module registration, and [`mod/example/service/example.go`](https://github.com/juanjitech/jframe/blob/main/mod/example/service/example.go) demonstrates how services wire into the kernel. Understanding this layout helps you interpret glob results meaningfully.

## Using filepath.Glob to List Top-Level Entries

The standard library's `filepath.Glob` function provides the most direct way to match patterns against the filesystem. When executed from the repository root, the `"*"` pattern returns every file and directory exactly one level deep, excluding nested paths like [`core/kernel/kernel.go`](https://github.com/juanjitech/jframe/blob/main/core/kernel/kernel.go).

```go
package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
)

func main() {
	// Ensure operation from the repository root
	root, err := os.Getwd()
	if err != nil {
		log.Fatalf("cannot determine working directory: %v", err)
	}
	fmt.Printf("Scanning top-level entries in: %s\n\n", root)

	// Glob pattern matches everything directly under root (no recursion)
	matches, err := filepath.Glob("*")
	if err != nil {
		log.Fatalf("glob operation failed: %v", err)
	}

	for _, name := range matches {
		info, err := os.Stat(name)
		if err != nil {
			log.Printf("cannot stat %s: %v", name, err)
			continue
		}
		if info.IsDir() {
			fmt.Printf("[DIR]  %s\n", name)
		} else {
			fmt.Printf("[FILE] %s\n", name)
		}
	}
}

```

### The Glob Pattern Syntax

The `"*"` wildcard matches any sequence of characters **excluding the path separator**. This constraint ensures the operation returns only top-level entries, preventing descent into subdirectories like `cmd/server/` or `mod/example/`. The function returns results in lexical order, consistent with standard `ls` output.

### Distinguishing Files from Directories

Since `filepath.Glob` returns bare filenames without type information, call `os.Stat` on each match to inspect the `FileInfo` structure. Check `info.IsDir()` to categorize entries—critical when you need to process module directories (`mod/`, `core/`) differently from configuration files (`go.mod`, `Dockerfile`).

## Alternative Methods for Top-Level Directory Listing

While globbing provides pattern-matching flexibility, Go offers several alternatives optimized for different scenarios when working with the JFrame repository structure.

### os.ReadDir for Efficient Iteration

Go 1.16 introduced `os.ReadDir`, which returns `DirEntry` values without requiring subsequent `stat` calls for type information. This approach avoids the overhead of pattern parsing when you simply need all top-level items.

```go
entries, err := os.ReadDir(".")
if err != nil {
    log.Fatal(err)
}
for _, e := range entries {
    fmt.Printf("%s isDir=%v\n", e.Name(), e.IsDir())
}

```

### filepath.WalkDir with Depth Control

When you need recursion but want to stop at the top level, use `filepath.WalkDir` with a depth counter. Return `filepath.SkipDir` when the depth exceeds one to prevent descending into subdirectories like `core/kernel/` or `cmd/server/`.

```go
depth := 0
filepath.WalkDir(".", func(path string, d os.DirEntry, err error) error {
    if depth > 1 {
        return filepath.SkipDir
    }
    depth++
    fmt.Println(path)
    return nil
})

```

### External Tools in CI Pipelines

For shell scripts and CI configurations targeting the JFrame repository, external utilities often suffice. Use `git ls-files` to list tracked top-level items, or `find . -maxdepth 1` for filesystem-level globbing equivalent. These integrate cleanly with Makefiles and GitHub Actions workflows without requiring Go compilation.

## Key Files in the JFrame Top-Level Directory

Understanding the repository layout helps contextualize glob results. The following critical files and directories reside at the root level:

| Path | Purpose |
|------|---------|
| [`main/main.go`](https://github.com/juanjitech/jframe/blob/main/main/main.go) | Application entry point that bootstraps the kernel |
| [`cmd/server/server.go`](https://github.com/juanjitech/jframe/blob/main/cmd/server/server.go) | HTTP server command implementation for the CLI |
| [`core/kernel/kernel.go`](https://github.com/juanjitech/jframe/blob/main/core/kernel/kernel.go) | Orchestration layer registering modules and services |
| [`core/logx/logger.go`](https://github.com/juanjitech/jframe/blob/main/core/logx/logger.go) | Centralized Zap-based logging configuration |
| [`mod/example/service/example.go`](https://github.com/juanjitech/jframe/blob/main/mod/example/service/example.go) | Sample service demonstrating module wiring |
| `go.mod` | Module dependency definitions |
| `Dockerfile` | Container build instructions |

When you glob the top-level directory, you capture the parent folders (`cmd/`, `core/`, `mod/`) that contain these implementation files, enabling programmatic discovery of the framework's architecture.

## Summary

- Use **`filepath.Glob("*")`** to retrieve all top-level entries in the JFrame repository without recursing into subdirectories.
- Combine globbing with **`os.Stat`** to differentiate between directories like `cmd/` and files like `go.mod`.
- Consider **`os.ReadDir`** as a higher-performance alternative when you don't need pattern matching.
- Reference specific source paths like [`core/kernel/kernel.go`](https://github.com/juanjitech/jframe/blob/main/core/kernel/kernel.go) and [`cmd/server/server.go`](https://github.com/juanjitech/jframe/blob/main/cmd/server/server.go) to understand the architectural organization revealed by top-level globbing.

## Frequently Asked Questions

### What is the difference between filepath.Glob and os.ReadDir?

`filepath.Glob` evaluates wildcard patterns like `"*"` or `"*.go"` against the filesystem, returning matching paths as strings. `os.ReadDir` returns all directory contents as `DirEntry` values without pattern matching, providing faster iteration and built-in type information via `IsDir()` without requiring additional `stat` calls.

### How do I prevent filepath.Glob from recursing into subdirectories?

The glob pattern `"*"` inherently matches only entries directly under the specified directory, excluding path separators. To ensure no recursion occurs, avoid patterns like `"**"` or `"*/*"`, and always verify you remain at the top level before processing nested paths.

### Can I use globbing to find specific file types in the JFrame repository?

Yes. Modify the glob pattern to include file extensions or naming conventions. For example, `filepath.Glob("*.go")` returns only Go source files at the root level, while `filepath.Glob("core/*")` matches entries within the `core/` directory. Combine multiple glob calls or use `filepath.Match` for more complex filtering logic.

### Why does my glob return different results on Windows versus Linux?

`filepath.Glob` uses the operating system's path separator and case-sensitivity rules. Windows uses backslashes and case-insensitive matching by default, while Linux uses forward slashes and case-sensitive matching. Always use `filepath.Join` to construct paths and avoid hardcoded separators in patterns to ensure cross-platform consistency when globbing the top-level directory.