@@ -186,10 +186,12 @@ func (cs CommentStyle) Render(s string) string {
186186 case CommentStyleBlock :
187187 return "/*\n " + s + "\n */\n "
188188 default :
189- panic (fmt .Errorf ("golicenser: missing comment style render for %q" , cs ))
189+ // Cannot render as a comment.
190+ return s
190191 }
191192}
192193
194+ // Parse parses the comment and returns the uncommented string.
193195func (cs CommentStyle ) Parse (s string ) string {
194196 switch cs {
195197 case CommentStyleLine :
@@ -208,10 +210,12 @@ func (cs CommentStyle) Parse(s string) string {
208210 case CommentStyleBlock :
209211 return strings .TrimSuffix (strings .TrimPrefix (s , "/*\n " ), "\n */\n " )
210212 default :
211- panic (fmt .Errorf ("golicenser: missing comment style parse for %q" , cs ))
213+ // Cannot parse as a comment.
214+ return s
212215 }
213216}
214217
218+ // Header is a helper for generating and updating license headers.
215219type Header struct {
216220 tmpl * template.Template
217221 matcher * regexp.Regexp
@@ -226,6 +230,7 @@ var tmplFuncMap = template.FuncMap{
226230 "basename" : filepath .Base ,
227231}
228232
233+ // HeaderOpts are the options for creating a license header.
229234type HeaderOpts struct {
230235 Template string
231236 MatchTemplate string
@@ -237,6 +242,7 @@ type HeaderOpts struct {
237242 CommentStyle CommentStyle
238243}
239244
245+ // NewHeader creates a new header with the given options.
240246func NewHeader (opts HeaderOpts ) (* Header , error ) {
241247 if opts .Author == "" {
242248 return nil , fmt .Errorf ("invalid author: %q" , opts .Author )
@@ -304,18 +310,22 @@ func NewHeader(opts HeaderOpts) (*Header, error) {
304310}
305311
306312// Create creates a new license header for the file.
307- func (h * Header ) Create (filename string ) string {
308- return h .commentStyle .Render (h .render (filename , timeNow ().Format ("2006" )))
313+ func (h * Header ) Create (filename string ) (string , error ) {
314+ header , err := h .render (filename , timeNow ().Format ("2006" ))
315+ if err != nil {
316+ return "" , fmt .Errorf ("render header: %w" , err )
317+ }
318+ return h .commentStyle .Render (header ), nil
309319}
310320
311321// Update updates an existing license header if it matches the
312- func (h * Header ) Update (filename , header string ) (string , bool ) {
322+ func (h * Header ) Update (filename , header string ) (string , bool , error ) {
313323 if cs , err := detectCommentStyle (header ); err == nil {
314324 header = cs .Parse (header )
315325 }
316326 match := h .matcher .FindStringSubmatch (header )
317327 if match == nil {
318- return header , false
328+ return header , false , nil
319329 }
320330
321331 var year string
@@ -374,12 +384,15 @@ func (h *Header) Update(filename, header string) (string, bool) {
374384 if year == "" {
375385 year = timeNow ().Format ("2006" )
376386 }
377- newHeader := h .render (filename , year )
378387
379- return h .commentStyle .Render (newHeader ), newHeader != header
388+ newHeader , err := h .render (filename , year )
389+ if err != nil {
390+ return "" , false , fmt .Errorf ("render header: %w" , err )
391+ }
392+ return h .commentStyle .Render (newHeader ), newHeader != header , nil
380393}
381394
382- func (h * Header ) render (filename , year string ) string {
395+ func (h * Header ) render (filename , year string ) ( string , error ) {
383396 // Built-in variables.
384397 m := map [string ]any {
385398 "author" : h .author ,
@@ -390,9 +403,9 @@ func (h *Header) render(filename, year string) string {
390403
391404 var b bytes.Buffer
392405 if err := h .tmpl .Execute (& b , m ); err != nil {
393- panic ( fmt .Errorf ("golicenser: execute header template: %w" , err ) )
406+ return "" , fmt .Errorf ("execute template: %w" , err )
394407 }
395- return b .String ()
408+ return b .String (), nil
396409}
397410
398411func headerMatcher (tmpl * template.Template , escapeTmpl bool , authorRegexp * regexp.Regexp , variables map [string ]any ) (* regexp.Regexp , error ) {
0 commit comments