runpath

package module
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 19, 2026 License: MIT Imports: 5 Imported by: 6

README

GitHub Workflow Status (branch) GoDoc Coverage Status Supported Go Versions GitHub Release Go Report Card

runpath

runpath package provides func to get the execution location of Go code, including the absolute path of the source file.


CHINESE README

中文说明

Installation

Install the package with:

go get github.com/yylego/runpath

Core Features

runpath is a runtime path utils package that obtains the absolute path of Go code execution locations.

Core Capabilities:

  1. Runtime Path Access - Get code execution location's absolute path via runtime.Caller()
  2. Parent DIR Operations - Parent DIR related operations through PARENT/DIR namespace
  3. Testing Support - runtestpath sub-package designed to support getting source file paths from test files
  4. Path Extension Handling - Support for changing and removing file extensions

runpath Advantages:

Unlike the built-in filepath.Abs(".") which doesn't always provide the expected result in certain situations, runpath uses Go's runtime package to provide precise location tracking, making it valuable when the exact execution path is needed.

Core API Overview

Path Operations:

  • Path(), Current(), CurrentPath() - Get current source file absolute path
  • Name(), CurrentName() - Get current source file name
  • Skip(skip int) - Skip specified levels to get caller path
  • GetPathChangeExtension(), GetRex() - Change file extension
  • GetPathRemoveExtension(), GetNox() - Remove .go extension

DIR Operations:

  • PARENT.Path(), DIR.Path() - Get parent DIR path
  • PARENT.Join(), DIR.Join() - Join paths
  • PARENT.Up(), DIR.UpTo() - Navigate up DIR structure

Test Utilities (runtestpath):

  • SrcPath(t) - Get tested source file path (from _test.go to corresponding .go file)
  • SrcName(t) - Get tested source file name
  • SrcPathChangeExtension(t, ext) - Change tested file extension

Common Use Cases

  • Dynamic Config File Paths - Read config.json from config.go dynamically
  • Test Code Generation - Locate source files when generating code in tests
  • Accurate Execution Paths - More reliable than filepath.Abs(".") for execution location

Example Usage

Basic Path Operations

This example shows how to get the current source file path and parent DIR information.

package main

import (
	"fmt"

	"github.com/yylego/runpath"
)

func main() {
	// Get current source file path
	currentPath := runpath.Path()
	fmt.Println("Current source path:")
	fmt.Println(currentPath)

	// Get current source file name
	currentName := runpath.Name()
	fmt.Println("Current source name:")
	fmt.Println(currentName)

	// Get parent DIR path
	parentPath := runpath.PARENT.Path()
	fmt.Println("Parent DIR path:")
	fmt.Println(parentPath)

	// Get parent DIR name
	parentName := runpath.PARENT.Name()
	fmt.Println("Parent DIR name:")
	fmt.Println(parentName)
}

⬆️ Source: Source

DIR Navigation and Path Construction

This example shows how to navigate DIR structures and build paths.

package main

import (
	"fmt"

	"github.com/yylego/runpath"
)

func main() {
	// Join paths with parent DIR
	configPath := runpath.PARENT.Join("config.json")
	fmt.Println("Config path:")
	fmt.Println(configPath)

	dataPath := runpath.DIR.Join("data", "example.txt")
	fmt.Println("Data path:")
	fmt.Println(dataPath)

	// Navigate up DIR structure
	upOne := runpath.PARENT.Up(1)
	fmt.Println("Up 1 DIR:")
	fmt.Println(upOne)

	upTwo := runpath.PARENT.Up(2)
	fmt.Println("Up 2 DIRs:")
	fmt.Println(upTwo)

	// Navigate up and join with path
	moduleConfig := runpath.PARENT.UpTo(1, "config.json")
	fmt.Println("Module config:")
	fmt.Println(moduleConfig)

	projectConfig := runpath.PARENT.UpTo(2, "config", "settings.json")
	fmt.Println("Project config:")
	fmt.Println(projectConfig)
}

⬆️ Source: Source

File Extension Handling

This example demonstrates changing file extensions and working with config files.

package main

import (
	"fmt"

	"github.com/yylego/runpath"
)

func main() {
	// Get current file path with different extension
	jsonPath := runpath.GetPathChangeExtension(".json")
	fmt.Println("JSON config path:")
	fmt.Println(jsonPath)

	// Using compact alias GetRex
	yamlPath := runpath.GetRex(".yaml")
	fmt.Println("YAML config path:")
	fmt.Println(yamlPath)

	// Get path without extension
	basePath := runpath.GetNox()
	fmt.Println("Base path (no extension):")
	fmt.Println(basePath)

	// Demonstrate use case: reading config file with same name
	configPath := runpath.GetRex(".config.json")
	fmt.Println("Config file path:")
	fmt.Println(configPath)
}

⬆️ Source: Source


Working with Configuration Files

You can use runpath to build paths to configuration files based on the execution location of the code. This is valuable in tests where different configurations are loaded depending on where the test is being executed.

path := runpath.DIR.Join("config.json")

This constructs the path to config.json relative to the execution DIR abs-path.

You can also use PARENT with the same approach:

path := runpath.PARENT.Join("config.json")

If you need to navigate up multiple DIR levels from the execution location, use:

path := runpath.PARENT.UpTo(3, "config.json")

This will return the path to config.json located three levels up from the execution DIR abs-path.


Locating Source Code in Test Cases

When running tests, you might need to generate code and reference the source file path. Here's how you can locate the test file's source path:

func TestSrcPath(t *testing.T) {
    path := runpath.SrcPath(t)
    t.Log(path)
    require.True(t, strings.HasSuffix(path, "runpath/runtestpath/utils_runtestpath.go"))
}

This approach helps when generating code that needs to be placed alongside the source files based on the execution location.


Changing File Extensions Based on Context

You can also change the file extension depending on the test context (e.g., from .go to .json):

func TestSrcPathChangeExtension(t *testing.T) {
    path := runpath.SrcPathChangeExtension(t, ".json")
    t.Log(path)
    require.True(t, strings.HasSuffix(path, "runpath/runtestpath/utils_runtestpath.json"))
}

func TestSrcRex(t *testing.T) {
    path := SrcRex(t, ".json")
    t.Log(path)
    require.True(t, strings.HasSuffix(path, "runpath/runtestpath/runtestpath.json"))
}

This allows you to load different types of files (e.g., configuration files) based on the execution location and test requirements.


Function Overview

  • Path(): Returns the absolute path of the source file where the code is executed, representing the execution location.
  • Current(), CurrentPath(), CurrentName(), Name(): Variants of Path() that retrieve the file path or name based on the current execution context.
  • Skip(int): Retrieves the path from a specified stack frame, helpful when getting the execution location of the calling code.
  • GetPathChangeExtension(): Returns the current source file path with a new extension (e.g., changing .go to .json).
  • GetPathRemoveExtension(): Returns the current source file path without the .go extension.
  • Join(): Joins the current DIR abs-path with extra path components, constructing paths based on the execution location.
  • Up(), UpTo(): Navigates up the DIR structure a specified amount of levels from the execution location.

Test-Specific Operations

  • SrcPath(t *testing.T): Retrieves the source path of the file being tested.
  • SrcName(t *testing.T): Retrieves the name of the source file being tested.
  • SrcPathChangeExtension(t *testing.T, ext string): Changes the extension of the test file path (e.g., from .go to .json).
  • SrcSkipRemoveExtension(t *testing.T): Removes the .go extension from the test file path.

This package is valuable in test files, where you need to reference source code paths and configuration files based on the execution location of the test file.


📄 License

MIT License - see LICENSE.


💬 Contact & Feedback

Contributions are welcome! Report bugs, suggest features, and contribute code:

  • 🐛 Mistake reports? Open an issue on GitHub with reproduction steps
  • 💡 Fresh ideas? Create an issue to discuss
  • 📖 Documentation confusing? Report it so we can improve
  • 🚀 Need new features? Share the use cases to help us understand requirements
  • Performance issue? Help us optimize through reporting slow operations
  • 🔧 Configuration problem? Ask questions about complex setups
  • 📢 Follow project progress? Watch the repo to get new releases and features
  • 🌟 Success stories? Share how this package improved the workflow
  • 💬 Feedback? We welcome suggestions and comments

🔧 Development

New code contributions, follow this process:

  1. Fork: Fork the repo on GitHub (using the webpage UI).
  2. Clone: Clone the forked project (git clone https://github.com/yourname/repo-name.git).
  3. Navigate: Navigate to the cloned project (cd repo-name)
  4. Branch: Create a feature branch (git checkout -b feature/xxx).
  5. Code: Implement the changes with comprehensive tests
  6. Testing: (Golang project) Ensure tests pass (go test ./...) and follow Go code style conventions
  7. Documentation: Update documentation to support client-facing changes and use significant commit messages
  8. Stage: Stage changes (git add .)
  9. Commit: Commit changes (git commit -m "Add feature xxx") ensuring backward compatible code
  10. Push: Push to the branch (git push origin feature/xxx).
  11. PR: Open a merge request on GitHub (on the GitHub webpage) with detailed description.

Please ensure tests pass and include relevant documentation updates.


🌟 Support

Welcome to contribute to this project via submitting merge requests and reporting issues.

Project Support:

  • Give GitHub stars if this project helps you
  • 🤝 Share with teammates and (golang) programming friends
  • 📝 Write tech blogs about development tools and workflows - we provide content writing support
  • 🌟 Join the ecosystem - committed to supporting open source and the (golang) development scene

Have Fun Coding with this package! 🎉🎉🎉


GitHub Stars

starring

Give me stars! Thank you!!!


Documentation

Overview

Parent DIR namespace features used in runtime path operations Provides namespace-like organization as parent DIR functions Enables clean API design with PARENT.Path(), PARENT.Join() patterns

父 DIR 命名空间功能,用于运行时路径操作 为父 DIR 相关函数提供类似命名空间的组织方式 实现清晰的 API 设计,支持 PARENT.Path()、PARENT.Join() 模式

Package runpath: Runtime path and execution location tracking engine Provides precise source code location tracking via Go's runtime package Supports path manipulation, extension handling, and parent DIR navigation Enables dynamic config file path construction based on execution context

runpath: 运行时路径获取和执行位置跟踪引擎 通过 Go 的 runtime 包提供精确的源代码位置跟踪 支持路径操作、扩展名处理和父 DIR 导航 基于执行上下文实现动态配置文件路径构建

Index

Constants

This section is empty.

Variables

View Source
var (
	PARENT = &parentNamespace{} // Namespace instance as parent DIR operations // 父 DIR 操作的全局实例
	DIR    = &parentNamespace{} // Concise name as PARENT // PARENT 的同义词,更简单的名称
)

Namespace instances as parent DIR operations Since Go has no namespace concept, this provides organized API access

父 DIR 操作的全局命名空间实例 由于 Go 缺乏命名空间概念,这提供了有组织的 API 访问

Functions

func Current

func Current() string

Current returns the source file path at the invocation site Since the package name is runpath, it means "run path of this code" Kept concise and simple to use

Current 获得当前源码文件路径 因为包名是 runpath,Current 的含义就是 "current run path" 保持简洁便于使用

func CurrentName

func CurrentName() string

CurrentName returns the source file name at the invocation site Gets just the filename without the DIR path

CurrentName 获得当前源码文件名称 仅获取文件名,不包含 DIR 路径

func CurrentPath

func CurrentPath() string

CurrentPath returns the source file path at the invocation site Same as Current, with a more explicit name

CurrentPath 获得当前源码文件路径 Current 的替代版本,提供给喜欢明确命名的用户

func GetNox

func GetNox() string

GetNox returns the source file path without extension Removes the .go suffix from the file path

GetNox 返回不带扩展名的当前源文件路径 从当前文件路径中移除 .go 后缀

func GetPathChangeExtension

func GetPathChangeExtension(pointExtension string) string

GetPathChangeExtension changes the source file extension at invocation site Removes .go suffix and adds new extension like ".xxx.zzz" Common use: in config.go, get config.json path to load configuration Can add ".json", "_dev.json", "_uat.json" to match different environments This function is the backbone of dynamic config file loading

GetPathChangeExtension 把当前源码的文件路径去除结尾.go,再增加新的结尾 可以增加 ".xxx.yyy.zzz" 等任意扩展名 常见用途:在 config.go 里获取 config.json 的路径来读取配置 可以增加 ".json"、"_dev.json"、"_uat.json" 用于不同环境 这个函数对动态配置文件加载非常重要

func GetPathRemoveExtension

func GetPathRemoveExtension() string

GetPathRemoveExtension removes the .go extension from the source file path Less used but kept as a complete API

GetPathRemoveExtension 把当前源码的文件路径去除结尾.go 使用频率较低但保留以保持完整性

func GetRex

func GetRex(pointExtension string) string

GetRex is a concise name of GetPathChangeExtension Changes the source file extension with a new one

GetRex 是 GetPathChangeExtension 的简短别名 更改当前源文件的扩展名

func GetSkipRemoveExtension

func GetSkipRemoveExtension(skip int) string

GetSkipRemoveExtension removes the .go extension with specified frame skip count

GetSkipRemoveExtension 返回指定调用帧跳过的去除 .go 扩展名的源文件路径

func Name

func Name() string

Name returns the runtime source file name Gets just the filename at execution location

Name 获得运行时的源码文件名称 获取执行位置的文件名

func Path

func Path() string

Path returns the runtime source file path at execution location Gets the absolute path of the invoking source file

Path 获得运行时的源码文件路径 获取调用源文件的绝对路径

func Skip

func Skip(skip int) string

Skip returns the runtime source location with specified frame skip count When skip=0, returns the invoking point's path The skip argument represents skips from the invocation position Skip(1) equals runtime.Caller(1)'s path at the same position Skip(2) equals runtime.Caller(2)'s path at the same position

Skip 获得运行时的源码位置 当传0的时候就是调用点的路径 核心原则:实参 skip 是调用位置的 skip 次数 Skip(1) 相当于在相同位置调用 runtime.Caller(1) 的路径 Skip(2) 相当于在相同位置调用 runtime.Caller(2) 的路径

Types

This section is empty.

Directories

Path Synopsis
internal
demos/demo1x command
demos/demo2x command
demos/demo3x command
examples/example1/locate
Package locate replicates runpath's parentNamespace and Skip function without mustAbsPath protection.
Package locate replicates runpath's parentNamespace and Skip function without mustAbsPath protection.
Package runtestpath: Test-specific runtime path utilities used in source file finding Enables finding source files from test files during test execution To get test file path, use runpath.Path() instead This package specializes in finding source files being tested Each function takes *testing.T to indicate test-exclusive usage
Package runtestpath: Test-specific runtime path utilities used in source file finding Enables finding source files from test files during test execution To get test file path, use runpath.Path() instead This package specializes in finding source files being tested Each function takes *testing.T to indicate test-exclusive usage

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL