5 Commits

Author SHA1 Message Date
  Alois Mahdal 37d5465b78 Replace '+pya' with a bit smarter app class 1 year ago
  Alois Mahdal 16b0c57214 Add tiny amount of boilerplate to '+py3' 1 year ago
  Alois Mahdal c56b2366bc Add spaces between formats to help distinguish and skip 1 year ago
  Alois Mahdal 7311f2e42e Add support for +sed format (sed -f) 1 year ago
  Alois Mahdal 3565ee60f7 Enforce use of python3 when doing computations 1 year ago
2 changed files with 139 additions and 19 deletions
  1. 2
    2
      bin/czkrates
  2. 137
    17
      bin/mkx

+ 2
- 2
bin/czkrates View File

@@ -62,7 +62,7 @@ parse_rate1() {
62 62
         test "$wntcur" = "$Code" || continue
63 63
         case $Amount in
64 64
             1) echo "${!wntfld}" ;;
65
-            *) python -c "print(float($Rate)/$Amount)" ;;
65
+            *) python3 -c "print(float($Rate)/$Amount)" ;;
66 66
         esac
67 67
     done
68 68
 }
@@ -89,7 +89,7 @@ maybe_multiply() {
89 89
         echo "$price"
90 90
     else
91 91
         think "multiplying by: $Mult"
92
-        python -c "print(float($price) * $Mult)"
92
+        python3 -c "print(float($price) * $Mult)"
93 93
     fi
94 94
 }
95 95
 

+ 137
- 17
bin/mkx View File

@@ -28,6 +28,7 @@ lstemplates() {
28 28
     #
29 29
     # Print list of valid templates
30 30
     #
31
+    echo sed
31 32
     echo pya
32 33
     echo shellfu
33 34
     echo Bash
@@ -44,20 +45,30 @@ mktemplate() {
44 45
     # Print template $Template for $FilePath
45 46
     #
46 47
     case "$Template" in
48
+
47 49
         sh)
48 50
             echo "#!/bin/sh"
49 51
             echo ''
50 52
             echo ''
51 53
             ;;
54
+
52 55
         bash|Bash)
53 56
             echo "#!/bin/bash"
54 57
             echo ''
55 58
             echo ''
56 59
             ;;
60
+
61
+        sed)
62
+            echo "#!/bin/sed -f"
63
+            echo ''
64
+            echo ''
65
+            ;;
66
+
57 67
         lua|Lua)
58 68
             echo "#!$(which lua)"
59 69
             echo ''
60 70
             ;;
71
+
61 72
         pl|Perl)
62 73
             echo "#!$(which perl)"
63 74
             echo ''
@@ -66,56 +77,164 @@ mktemplate() {
66 77
             echo ''
67 78
             echo ''
68 79
             ;;
80
+
69 81
         py|Python)
70 82
             echo "#!$(which python)"
71 83
             echo ''
72 84
             echo "if __name__ == '__main__':"
73 85
             echo '    '
74 86
             ;;
87
+
75 88
         py3|Python3)
76 89
             echo "#!/usr/bin/python3"
77 90
             echo ''
78
-            echo "if __name__ == '__main__':"
79
-            echo '    '
91
+            echo 'import sys'
92
+            echo ''
93
+            echo ''
94
+            echo 'class UsageError(ValueError):'
95
+            echo '    pass'
96
+            echo ''
97
+            echo ''
98
+            echo 'def usage():'
99
+            echo '    self = sys.argv[0]'
100
+            echo '    raise UsageError("usage: %s [-j|-t|-p] YAML_FILE.." % self)'
101
+            echo ''
102
+            echo ''
103
+            echo 'def main(argv):'
104
+            echo '    if len(argv) < 2:'
105
+            echo '        usage()'
106
+            echo ''
107
+            echo ''
108
+            echo 'if __name__ == "__main__":'
109
+            echo '    main(sys.argv[1:])'
80 110
             ;;
111
+
81 112
         pya)
82
-            echo '#!/usr/bin/python'
113
+            echo '#!/usr/bin/python3'
83 114
             echo '"""'
84 115
             echo 'A simple application'
85 116
             echo '"""'
86 117
             echo ''
87 118
             echo 'import sys'
119
+            echo 'import traceback'
120
+            echo ''
121
+            echo ''
122
+            echo 'class UsageError(ValueError):'
123
+            echo '    pass'
88 124
             echo ''
89 125
             echo ''
90
-            echo 'class App(object):'
126
+            echo 'class AppError(RuntimeError):'
127
+            echo '    pass'
128
+            echo ''
129
+            echo ''
130
+            echo 'class BaseApp:'
91 131
             echo '    """'
92 132
             echo '    Main application class'
93 133
             echo '    """'
94 134
             echo ''
95
-            echo '    def __init__(self, argv):'
96
-            echo '        self.argv = argv'
97
-            echo '        # agument decoding and further initializations'
135
+            echo '    @classmethod'
136
+            echo '    def main(cls, factory=None):'
137
+            echo '        factory = factory if factory else cls.from_argv'
138
+            echo '        try:'
139
+            echo '            app = factory()'
140
+            echo '            es = app.run()'
141
+            echo '        except UsageError as e:'
142
+            echo '            print(e, file=sys.stderr)'
143
+            echo '            sys.exit(2)'
144
+            echo '        except AppError as e:'
145
+            echo '            print(e, file=sys.stderr)'
146
+            echo '            sys.exit(3)'
147
+            echo '        except Exception:'
148
+            echo '            sys.stderr.write(traceback.format_exc())'
149
+            echo '            sys.exit(4)'
150
+            echo '        if type(es) is not int:'
151
+            echo '            msg = ('
152
+            echo '                "%s.run() did not return proper exit status: %r is not int"'
153
+            echo '                % (app.__class__.__name__, es)'
154
+            echo '            )'
155
+            echo '            BaseApp.WARN(msg)'
156
+            echo '            es = 4'
157
+            echo '        sys.exit(es)'
98 158
             echo ''
99 159
             echo '    @classmethod'
100
-            echo '    def main(cls, argv):'
160
+            echo '    def from_argv(cls):'
161
+            echo '        return cls('
162
+            echo '            name=sys.argv[0],'
163
+            echo '            args=sys.argv[1:]'
164
+            echo '        )'
165
+            echo ''
166
+            echo '    def __init__(self, name, args):'
167
+            echo '        self.name = name'
168
+            echo '        self.args = args'
169
+            echo ''
170
+            echo '    def _throw_usage(self, pattern=None):'
171
+            echo '        """'
172
+            echo '        Throw UsageError with pattern *pattern*.'
101 173
             echo '        """'
102
-            echo '        Initialize and launch'
174
+            echo '        parts = ["usage:", self.name]'
175
+            echo '        if pattern:'
176
+            echo '            parts.append(pattern)'
177
+            echo '        raise UsageError(" ".join(parts))'
178
+            echo ''
179
+            echo '    @staticmethod'
180
+            echo '    def WARN(msg):'
181
+            echo '        """'
182
+            echo '        Warn user with message *msg*.  *msg* can be string or a list of lines.'
183
+            echo '        """'
184
+            echo '        if type(msg) is list:'
185
+            echo '            lines = msg'
186
+            echo '        else:'
187
+            echo '            lines = [str(msg)]'
188
+            echo '        for line in lines:'
189
+            echo '            print(line, file=sys.stderr)'
190
+            echo ''
191
+            echo '    def _validate(self):'
192
+            echo '        """'
193
+            echo '        Validate *self.args*; throw UsageError if needed.'
103 194
             echo '        """'
104
-            echo '        app = cls(argv)'
105
-            echo '        app.run()'
195
+            echo '        if not self.args:'
196
+            echo '            self._throw_usage("ARG..")'
106 197
             echo ''
107 198
             echo '    def run(self):'
108 199
             echo '        """'
109
-            echo '        Run the application'
200
+            echo '        Run the application; return integer exit status'
110 201
             echo '        """'
111
-            echo '        # actual action (calling other methods)'
112
-            echo '        print self.argv'
113
-            echo '        print __doc__'
202
+            echo '        self._validate()'
203
+            echo '        if self.args[0] == "--fail":'
204
+            echo '            raise AppError("you asked for it")'
205
+            echo '        if self.args[0] == "--fail-unexpectedly":'
206
+            echo '            raise RuntimeError("you asked for it ANyway")'
207
+            echo '        if self.args[0] == "--warn":'
208
+            echo '            BaseApp.WARN("you asked for a warning")'
209
+            echo '            return 0'
210
+            echo '        if self.args[0] == "--badret":'
211
+            echo '            return object()'
212
+            echo '        return 0'
213
+            echo ''
114 214
             echo ''
215
+            echo 'class App(BaseApp):'
115 216
             echo ''
116
-            echo 'if __name__ == '__main__':'
117
-            echo '    App.main(sys.argv)'
217
+            echo '    def _validate(self):'
218
+            echo '        """'
219
+            echo '        Validate *self.args*; throw UsageError as needed.'
220
+            echo ''
221
+            echo '        Prefer using self._throw_usage().'
222
+            echo '        """'
223
+            echo '        App.WARN("You need to rewrite App._validate()!!!")'
224
+            echo '        super()._validate()'
225
+            echo ''
226
+            echo '    def run(self):'
227
+            echo '        """'
228
+            echo '        Run the application; return integer exit status'
229
+            echo '        """'
230
+            echo '        App.WARN("You need to rewrite App.run()")'
231
+            echo '        super().run()'
232
+            echo ''
233
+            echo ''
234
+            echo 'if __name__ == "__main__":'
235
+            echo '    App.main()'
118 236
             ;;
237
+
119 238
         shellfu)
120 239
             echo "#!/bin/bash"
121 240
             echo ""
@@ -139,6 +258,7 @@ mktemplate() {
139 258
             echo ''
140 259
             echo 'main "$@"'
141 260
             ;;
261
+
142 262
         *)
143 263
             die "unknown template or language: $Template"
144 264
             ;;