Some checks failed
		
		
	
	Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
				
			
		
			
				
	
	
		
			337 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Tcl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			337 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Tcl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/sh
 | ||
| # Tcl ignores the next line -*- tcl -*- \
 | ||
| exec tclsh8.6 "$0" -- "$@"
 | ||
| 
 | ||
| ######################################################################
 | ||
| #                ProjMan 2
 | ||
| #        Distributed under GNU Public License
 | ||
| # Author: Sergey Kalinin svk@nuk-svk.ru
 | ||
| # Copyright (c) "SVK", 2024, https://nuk-svk.ru
 | ||
| #######################################################################
 | ||
| # Changelog generator from the Git commit history.
 | ||
| # For DEB and RPM packages
 | ||
| # usage a git command:
 | ||
| # 
 | ||
| #    git log --abbrev-commit --all --pretty='%h, %ad, %an, %ae, %s, %b'
 | ||
| #######################################################################
 | ||
| 
 | ||
| # puts $tcl_platform(platform)
 | ||
| 
 | ||
| # Устанавливаем рабочий каталог, если его нет то создаём.
 | ||
| # Согласно спецификации XDG проверяем наличие переменных и каталогов
 | ||
| if [info exists env(XDG_CONFIG_HOME)] {
 | ||
|     set dir(cfg) [file join $env(XDG_CONFIG_HOME) changelog-gen]
 | ||
| } elseif [file exists [file join $env(HOME) .config]] {
 | ||
|     set dir(cfg) [file join $env(HOME) .config changelog-gen]
 | ||
| } else {
 | ||
|     #set dir(cfg) [file join $env(HOME) .changelog-gen]
 | ||
| }
 | ||
| 
 | ||
| if {[file exists $dir(cfg)] == 0} {
 | ||
|     file mkdir $dir(cfg)
 | ||
| }
 | ||
| 
 | ||
| # Use whereis command for finding the git executable file.
 | ||
| # for unix-like operating systems
 | ||
| proc GetGitCommandUnix {} {
 | ||
|     global gitCommand
 | ||
|     set cmd "whereis -b git"
 | ||
|     catch "exec $cmd" result
 | ||
|     # puts $result
 | ||
|     if {$result ne ""} {
 | ||
|         set fields [split $result ":"]
 | ||
|         # puts $fields
 | ||
|         if {[lindex $fields 1] ne ""} {
 | ||
|             # puts [lindex $fields 1]
 | ||
| 	        set gitCommand "[string trim [lindex $fields 1]]"
 | ||
| 		} else {
 | ||
|             puts "GIT command not found"
 | ||
|             exit
 | ||
|         }
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| # Setting the git-command for windows family OS
 | ||
| proc GetGitCommandWindows {} {
 | ||
|     global gitCommand
 | ||
|     set gitCommand "c:/git/bin/git.exe"
 | ||
| }
 | ||
| 
 | ||
| switch $tcl_platform(platform) {
 | ||
|     unix     {GetGitCommandUnix}
 | ||
|     windows  {GetGitCommandWindows}
 | ||
| }
 | ||
| 
 | ||
| proc ReadGitLog {} {
 | ||
|     global args gitCommand lastCommitTimeStampSec
 | ||
|     set cmd exec
 | ||
|     set i 0
 | ||
|     lappend cmd "$gitCommand"
 | ||
|     lappend cmd "log"
 | ||
|     lappend cmd "--abbrev-commit"
 | ||
|     # Проверяем была ли запись для данного проекта если была то к времени последнего коммита прибавляем 1 сек.
 | ||
|     # и получаем журнал после этой даты
 | ||
|     if {[info exists lastCommitTimeStampSec] && [info exists args(--last)]} {
 | ||
|         lappend cmd "--after='[clock format [clock add $lastCommitTimeStampSec 1 second] -format {%a, %e %b %Y %H:%M:%S %z}]'"
 | ||
|     }
 | ||
|     lappend cmd "--all"
 | ||
|     lappend cmd "--pretty='%h, %ad, %an, %ae, %s, %b'"
 | ||
|     # puts $cmd
 | ||
|     catch $cmd pipe
 | ||
|     # puts $pipe
 | ||
|     set outBuffer ""
 | ||
|     foreach line [split $pipe "\n"] {
 | ||
|         # puts $line
 | ||
|         # set line [string trim $line]
 | ||
|         set line [string trim [string trim $line] {'}] 
 | ||
|         if {[regexp -nocase -all -- {^[0-9a-z]+} $line match]} {
 | ||
|             set outBuffer $line
 | ||
|             if {$outBuffer ne ""} {
 | ||
|                 lappend res [list $i $outBuffer]
 | ||
|                 incr i
 | ||
|             }
 | ||
|             # puts $outBuffer
 | ||
|         } else {
 | ||
|             if {$line ne ""} {
 | ||
|                 append outBuffer ". " $line
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
|     # puts $res
 | ||
|     if [info exists res] {
 | ||
|         return $res
 | ||
|     } else {
 | ||
|         puts "\nRepository '$args(--project-name)' do not have any changes\n"
 | ||
|         exit
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| proc StoreProjectInfo {timeStamp} {
 | ||
|     global dir args
 | ||
|     set cfgFile [open [file join $dir(cfg) $args(--project-name).conf]  "w+"]
 | ||
|     puts $cfgFile "# set args(--project-version) \"$args(--project-version)\""
 | ||
|     puts $cfgFile "# set args(--project-release) \"$args(--project-release)\""
 | ||
|     puts $cfgFile "set lastCommitTimeStamp \"$timeStamp\""
 | ||
|     puts $cfgFile "set lastCommitTimeStampSec [clock scan $timeStamp]"
 | ||
|     close $cfgFile   
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| proc GenerateChangelogDEB {} {
 | ||
|     global args
 | ||
|     # puts "GenerateChangelogDEB"
 | ||
|     set lastCommitTimeStamp ""
 | ||
|     set commiter ""
 | ||
|     set commitText ""
 | ||
|     # ReadGitLog
 | ||
|     set lst [lsort -integer -index 0 [ReadGitLog]]
 | ||
|     # puts $lst
 | ||
|     # exit
 | ||
|     set outText ""
 | ||
|     foreach l $lst {
 | ||
|         set index [lindex $l 0]
 | ||
|         set line [lindex $l 1]
 | ||
|         # puts "$index - $line"
 | ||
|         set record [split $line ","]
 | ||
|         set timeStamp [string trim [lindex $record 1]]
 | ||
|         set email [string trim [lindex $record 3]]
 | ||
|         if {$lastCommitTimeStamp eq ""} {
 | ||
|             set lastCommitTimeStamp [string trim [lindex $record 1]]
 | ||
|         }
 | ||
|         set timeStamp [clock format [clock scan $timeStamp] -format {%a, %e %b %Y %H:%M:%S %z}]
 | ||
|         # puts "> $commiter"
 | ||
|         if {$index == 0} {
 | ||
|             puts "$args(--project-name) ($args(--project-version)-$args(--project-release)) stable; urgency=medium\n"
 | ||
|             append outText "$args(--project-name) ($args(--project-version)-$args(--project-release)) stable; urgency=medium\n\n"
 | ||
|             set commiter [lindex $record 2]
 | ||
|             StoreProjectInfo $timeStamp
 | ||
|          	  # puts "\n \[ [string trim $commiter] \]"
 | ||
|         }
 | ||
|         # puts ">> $commiter"
 | ||
|         if {$commiter ne [lindex $record 2]} {
 | ||
|             puts "\n -- [string trim $commiter] <$email>  $timeStamp"
 | ||
|             append outText "\n -- [string trim $commiter] <$email>  $timeStamp\n"
 | ||
|             puts "\n$args(--project-name) ($args(--project-version)-$args(--project-release)) stable; urgency=medium\n"
 | ||
|             append outText "\n$args(--project-name) ($args(--project-version)-$args(--project-release)) stable; urgency=medium\n\n"
 | ||
|             set commiter [lindex $record 2]
 | ||
|             # puts "\n \[ [string trim $commiter] \]"
 | ||
|         }
 | ||
|         
 | ||
|         set commitTex [lindex $record 4]
 | ||
|         puts "  * $commitTex"
 | ||
|         append outText "  * $commitTex\n"
 | ||
| 
 | ||
|     }
 | ||
|     puts "\n -- [string trim $commiter] <$email>  $timeStamp"
 | ||
|     append outText "\n -- [string trim $commiter] <$email>  $timeStamp\n"
 | ||
|     return $outText
 | ||
| }
 | ||
| 
 | ||
| proc GenerateChangelogRPM {} {
 | ||
|     puts "GenerateChangelogRPM"
 | ||
|     
 | ||
| }
 | ||
| 
 | ||
| proc GenerateChangelogTXT {} {
 | ||
|     global args
 | ||
|     set lastCommitTimeStamp ""
 | ||
|     set commiter ""
 | ||
|     set commitText ""
 | ||
|     set lst [lsort -integer -index 0 [ReadGitLog]]
 | ||
|     puts "$args(--project-name) ($args(--project-version)-$args(--project-release)"
 | ||
|     foreach l $lst {
 | ||
|         set index [lindex $l 0]
 | ||
|         set line [lindex $l 1]
 | ||
|         # puts "$index - $line"
 | ||
|         set record [split $line ","]
 | ||
|         set timeStamp [string trim [lindex $record 1]]
 | ||
|         set email [string trim [lindex $record 3]]
 | ||
|         if {$lastCommitTimeStamp eq ""} {
 | ||
|             set lastCommitTimeStamp [string trim [lindex $record 1]]
 | ||
|         }
 | ||
|         set timeStamp [clock format [clock scan $timeStamp] -format {%a, %e %b %Y %H:%M:%S %z}]
 | ||
|         # puts "> $commiter"
 | ||
|         if {$index == 0} {
 | ||
|             append outText "$args(--project-name) ($args(--project-version)-$args(--project-release))\n"
 | ||
|             set commiter [lindex $record 2]
 | ||
|             puts "\n[string trim $commiter] <$email>  $timeStamp"
 | ||
|             append outText "\n[string trim $commiter] <$email>  $timeStamp\n"
 | ||
|             StoreProjectInfo $timeStamp
 | ||
|         }
 | ||
|         if {$commiter ne [lindex $record 2]} {
 | ||
|             puts "\n[string trim $commiter] <$email>  $timeStamp"
 | ||
|             append outText "\n[string trim $commiter] <$email>  $timeStamp\n"
 | ||
|             set commiter [lindex $record 2]
 | ||
|         }
 | ||
|         
 | ||
|         set commitTex [lindex $record 4]
 | ||
|         puts "  - $commitTex"
 | ||
|         append outText "  - $commitTex\n"
 | ||
| 
 | ||
|     }
 | ||
|     return $outText
 | ||
| }
 | ||
| # puts [ReadGitLog]
 | ||
| 
 | ||
| proc ShowHelp {} {
 | ||
|     puts "\nChangelog generator from the Git commit history. For DEB and RPM packages"
 | ||
|     puts "Usage:\n"
 | ||
|     puts "\tchangelog-gen \[options\]\n"
 | ||
|     puts "Where options:"
 | ||
|     puts "\t--project-name - name of project (package) "
 | ||
|     puts "\t--project-version - package version"
 | ||
|     puts "\t--project-release - package release name (number)"
 | ||
|     puts "\t--deb - debian package format of changelog"
 | ||
|     puts "\t--rpm - rpm package format of changelog"
 | ||
|     puts "\t--txt - plain text changelog out"
 | ||
|     puts "\t--out-file - changelog file name"
 | ||
|     puts "\t--last - The timestamp since the last launch of this program for a given project"
 | ||
| }
 | ||
| 
 | ||
| proc StoreChangeLog {outText} {
 | ||
|     global args
 | ||
|     if [file exists $args(--out-file)] {
 | ||
|         file copy -force $args(--out-file) "$args(--out-file).tmp"
 | ||
|         
 | ||
|         set origOutFile [open "$args(--out-file).tmp"  "r"]
 | ||
|         set origText [read $origOutFile]
 | ||
|         close $origOutFile
 | ||
|         
 | ||
|         set outFile [open $args(--out-file)  "w"]
 | ||
|         puts $outFile $outText
 | ||
|         puts $outFile $origText
 | ||
|         close $outFile
 | ||
|         
 | ||
|         if [info exists args(--last)] {
 | ||
|             set outFile [open $args(--out-file)  "r+"]
 | ||
|             puts $outFile $outText
 | ||
|             close $outFile
 | ||
|         } else {
 | ||
|             set outFile [open $args(--out-file)  "w+"]
 | ||
|             puts $outFile $outText
 | ||
|             close $outFile
 | ||
|         }
 | ||
|     } else {
 | ||
|         set outFile [open $args(--out-file)  "w+"]
 | ||
|         puts $outFile $outText
 | ||
|         close $outFile
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| set arglen [llength $argv]
 | ||
| set index 0
 | ||
| while {$index < $arglen} {
 | ||
|     set arg [lindex $argv $index]
 | ||
|     switch -exact $arg {
 | ||
|         --project-name {
 | ||
|             set args($arg) [lindex $argv [incr index]]
 | ||
|         }
 | ||
|         --project-version {
 | ||
|             set args($arg) [lindex $argv [incr index]]
 | ||
|         }
 | ||
|         --project-release {
 | ||
|             set args($arg) [lindex $argv [incr index]]
 | ||
|         }
 | ||
|         --deb {
 | ||
|             set args($arg) true
 | ||
|         }
 | ||
|         --rpm {
 | ||
|             set args($arg) true
 | ||
|         }
 | ||
|         --txt {
 | ||
|             set args($arg) true
 | ||
|         }
 | ||
|         --out-file {
 | ||
|             set args($arg) [lindex $argv [incr index]]
 | ||
|         }
 | ||
|         --last {
 | ||
|             set args($arg) true
 | ||
|         }
 | ||
|         --help {
 | ||
|             ShowHelp
 | ||
|             exit
 | ||
|         }
 | ||
|         default  {
 | ||
|             set filename [lindex $argv $index]
 | ||
|         }
 | ||
|     }
 | ||
|     incr index
 | ||
| }
 | ||
| 
 | ||
| if ![info exists args(--project-name)] {
 | ||
|     puts "You mast set --project-name option\n"
 | ||
|     exit
 | ||
| }
 | ||
| if ![info exists args(--project-version)] {
 | ||
|     puts "You mast set --project-version option\n"
 | ||
|     exit
 | ||
| }
 | ||
| if ![info exists args(--project-release)] {
 | ||
|     puts "You mast set --project-release option\n"
 | ||
|     exit
 | ||
| }
 | ||
| 
 | ||
| if [file exists [file join $dir(cfg) $args(--project-name).conf]] {
 | ||
|     source [file join $dir(cfg) $args(--project-name).conf]
 | ||
| }
 | ||
| 
 | ||
| foreach arg [array names args] {
 | ||
|     puts "$arg $args($arg)"
 | ||
| }
 | ||
| 
 | ||
| if [info exists args(--deb)] {
 | ||
|     set outText [GenerateChangelogDEB]
 | ||
|     if [info exists args(--out-file)] {
 | ||
|         StoreChangeLog $outText
 | ||
|     }
 | ||
| }
 | ||
| if [info exists args(--rpm)] {
 | ||
|     GenerateChangelogRPM
 | ||
| }
 | ||
| if [info exists args(--txt)] {
 | ||
|     set outText [GenerateChangelogTXT]
 | ||
|     if [info exists args(--out-file)] {
 | ||
|         StoreChangeLog $outText
 | ||
|     }
 | ||
| }
 |