aboutsummaryrefslogtreecommitdiff
path: root/guix/deprecation.scm
blob: 47e653dfb2dd2a648b707a578a77c746f2ab2ba1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2021 Mathieu Othacehe <othacehe@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (guix deprecation)
  #:use-module (guix i18n)
  #:use-module (guix diagnostics)
  #:autoload   (guix utils) (source-properties->location)
  #:export (define-deprecated

            define-deprecated/public
            define-deprecated/alias
            define-deprecated/public-alias

            warn-about-old-daemon
            warn-about-deprecation))

;;; Commentary:
;;;
;;; Provide a mechanism to mark bindings as deprecated.
;;;
;;; Code:

(define (warn-about-old-daemon)
  (warning (G_ "Your Guix daemon is severely outdated, and will soon cease to
be able to download binary substitutes.  To upgrade it, refer to the
'Upgrading Guix' section in the manual.~%")))

(define* (warn-about-deprecation variable properties
                                 #:key replacement)
  (let ((location (and properties (source-properties->location properties))))
    (if replacement
        (warning location (G_ "'~a' is deprecated, use '~a' instead~%")
                 variable replacement)
        (warning location (G_ "'~a' is deprecated~%")
                 variable))))

(define-syntax public (syntax-rules ()))          ;private syntactic keyword

(define-syntax define-deprecated
  (lambda (s)
    "Define a deprecated variable or procedure, along these lines:

  (define-deprecated foo bar 42)
  (define-deprecated old new)
  (define-deprecated (baz x y) qux (qux y x))

This will write a deprecation warning to GUIX-WARNING-PORT."
    (syntax-case s ()
      ((_ (proc formals ...) replacement body ...)
       #'(define-deprecated proc replacement
           (lambda* (formals ...) body ...)))
      ((_ variable replacement exp)
       #'(define-deprecated private variable replacement exp))
      ((_ visibility variable replacement exp)
       (identifier? #'variable)
       (with-syntax ((real (datum->syntax
                            #'variable
                            (symbol-append '%
                                           (syntax->datum #'variable)
                                           '/deprecated))))
         #`(begin
             (define real
               (begin
                 (lambda () replacement)          ;just to ensure it's bound
                 exp))

             (define-syntax variable
               (lambda (s)
                 (warn-about-deprecation 'variable (syntax-source s)
                                         #:replacement 'replacement)
                 (syntax-case s ()
                   ((_ args (... ...))
                    #'(real args (... ...)))
                   (id
                    (identifier? #'id)
                    #'real))))

             ;; When asking for public visibility, export both REAL and
             ;; VARIABLE.  Exporting REAL is useful when defining deprecated
             ;; packages: there must be a public variable bound to a package
             ;; so that the (guix discover) machinery finds it.
             #,(if (free-identifier=? #'visibility #'public)
                   #'(export real variable)
                   #'(begin)))))
      ((_ variable alias)
       (identifier? #'alias)
       #'(define-deprecated variable alias alias)))))

(define-syntax-rule (define-deprecated/public body ...)
  "Like 'define-deprecated', but export all the newly introduced bindings."
  (define-deprecated public body ...))

(define-syntax-rule (define-deprecated/alias deprecated replacement)
  "Define as an alias a deprecated variable, procedure, or macro, along
these lines:

  (define-deprecated/alias nix-server? store-connection?)

where 'nix-server?' is the deprecated name for 'store-connection?'.

This will write a deprecation warning to GUIX-WARNING-PORT."
  (define-syntax deprecated
    (lambda (s)
      (warn-about-deprecation 'deprecated (syntax-source s)
                              #:replacement 'replacement)
      (syntax-case s ()
        ((_ args (... ...))
         #'(replacement args (... ...)))
        (id
         (identifier? #'id)
         #'replacement)))))

(define-syntax-rule (define-deprecated/public-alias deprecated replacement)
  "Like define-deprecated/alias, but exporting DEPRECATED.
It is assumed, that REPLACEMENT is already public."
  (begin
    (define-deprecated/alias deprecated replacement)
    (export deprecated)))