@@ -242,29 +242,37 @@ var (
242242}
243243
244244// readCurrentVersion reads the version file at the given path
245- // and extracts the version string from a line that looks like:
246- // Version = "dev" or Version = "1.2.3".
247- // If the file does not exist, it creates the file with a default version "dev".
245+ // and extracts the version string. If the file does not exist,
246+ // it first tries to get the latest tag from git in that directory,
247+ // writes it into the version file, and returns it.
248+ // If there are no tags or git fails, it falls back to “dev”.
248249func readCurrentVersion (path string ) (string , error ) {
249250 data , err := os .ReadFile (path )
250251 if err != nil {
251252 if os .IsNotExist (err ) {
252- // File does not exist: create it with default version "dev".
253+ dir := filepath .Dir (path )
254+ if fromGit , gitErr := getVersionFromGitDir (dir ); gitErr == nil {
255+ if err := writeVersionFile (path , fromGit ); err != nil {
256+ return "" , fmt .Errorf ("failed to write version file from git tag: %w" , err )
257+ }
258+ return fromGit , nil
259+ }
260+ // Fallback to dev
253261 defaultVersion := "dev"
254262 if err := writeVersionFile (path , defaultVersion ); err != nil {
255- return "" , fmt .Errorf ("failed to create default version file: %v " , err )
263+ return "" , fmt .Errorf ("failed to create default version file: %w " , err )
256264 }
257265 return defaultVersion , nil
258266 }
259- return "" , fmt .Errorf ("failed to read version file: %v " , err )
267+ return "" , fmt .Errorf ("failed to read version file: %w " , err )
260268 }
261- // Look for a line like: Version = "..."
269+
270+ // File exists: parse out the version string
262271 re := regexp .MustCompile (`Version\s*=\s*"([^"]+)"` )
263- matches := re .FindSubmatch (data )
264- if matches == nil || len (matches ) < 2 {
265- return "" , errors .New ("failed to find version string in file" )
272+ if matches := re .FindSubmatch (data ); matches != nil && len (matches ) >= 2 {
273+ return string (matches [1 ]), nil
266274 }
267- return string ( matches [ 1 ]), nil
275+ return "" , errors . New ( "failed to find version string in file" )
268276}
269277
270278// gitCommit stages the version file (plus any extra files provided),
@@ -304,12 +312,14 @@ func gitCommit(newVersion string, extraFiles []string) error {
304312 return nil
305313}
306314
307- // getVersionFromGit retrieves the most recent tag from git and removes the "v" prefix.
308- func getVersionFromGit () (string , error ) {
315+ // getVersionFromGitDir retrieves the most recent tag from git in the given directory
316+ // and strips off any leading "v".
317+ func getVersionFromGitDir (dir string ) (string , error ) {
309318 cmd := exec .Command ("git" , "describe" , "--tags" , "--abbrev=0" )
319+ cmd .Dir = dir
310320 out , err := cmd .Output ()
311321 if err != nil {
312- return "" , fmt .Errorf ("failed to get version from git: %v" , err )
322+ return "" , fmt .Errorf ("failed to get version from git in %q : %v" , dir , err )
313323 }
314324 tag := strings .TrimSpace (string (out ))
315325 return strings .TrimPrefix (tag , "v" ), nil
@@ -352,7 +362,8 @@ func Run(versionFilePath string, versionArg string, extraFiles []string) (Versio
352362 newVersion = strings .TrimPrefix (bumped , "v" )
353363 meta .BumpType = versionArg
354364 case "from-git" :
355- fromGit , err := getVersionFromGit ()
365+ dir := filepath .Dir (versionFilePath )
366+ fromGit , err := getVersionFromGitDir (dir )
356367 if err != nil {
357368 return meta , err
358369 }
@@ -423,7 +434,8 @@ func DryRun(versionFilePath string, versionArg string) (VersionMeta, error) {
423434 newVersion = strings .TrimPrefix (bumped , "v" )
424435 meta .BumpType = versionArg
425436 case "from-git" :
426- fromGit , err := getVersionFromGit ()
437+ dir := filepath .Dir (versionFilePath )
438+ fromGit , err := getVersionFromGitDir (dir )
427439 if err != nil {
428440 return meta , err
429441 }
0 commit comments