Browse Source

Replace mkexec with mkx (simpler, better...)

Alois Mahdal 7 years ago
parent
commit
409a21c935
3 changed files with 198 additions and 183 deletions
  1. 7
    7
      README.md
  2. 0
    176
      bin/mkexec
  3. 191
    0
      bin/mkx

+ 7
- 7
README.md View File

@@ -74,17 +74,17 @@ mode, where you can enter URLs one per line.  Quit this mode by entering *EOF*
74 74
     url2
75 75
 
76 76
 
77
-### mkexec ###
77
+### mkx ###
78 78
 
79
-    mkexec [-f] [-e] name [type] [purpose]
79
+    mkx [-f|--force] FILE [TEMPLATE]
80
+    mkx -l|--list
80 81
 
81 82
 Make executable script, i.e. create new file, add shebang line and template,
82
-and mark it executable (0755).  type (py, pl, bash...) and purpose (test
83
-or nothing) are used to choose the right template.  If not supplied, attempt
84
-is made to guess from the filename.
83
+and mark it executable (0755).  If TEMPLATE is not given, language is guessed
84
+from FILE suffix.  If the file already  exist, gives up, unless `-f` option
85
+is passed.
85 86
 
86
-If the file already  exist, gives up, unless *-f* option is passed.  *-e*
87
-option causes default editor to be spawned with the new file loaded.
87
+Use `-l` to list supported TEMPLATEs
88 88
 
89 89
 
90 90
 ### pfile ###

+ 0
- 176
bin/mkexec View File

@@ -1,176 +0,0 @@
1
-#!/usr/bin/perl
2
-# make an executable file
3
-
4
-use strict;
5
-use warnings;
6
-
7
-sub usage; sub mkexec; sub guesstype; sub guesspurpose;
8
-sub getcmd; sub launch_editor;
9
-
10
-my $DEFAULT_TYPE = 'sh';
11
-my $DEFAULT_MODE = 0755;
12
-my $DEFAULT_FORCE = 0;
13
-my $DEFAULT_EDIT = 0;
14
-
15
-
16
-## .... ##   . . .  .   .    .     .      .       .        .         .
17
-## INIT ## -------------------------------------------------------------------
18
-## '''' ##   ' ' '  '   '    '     '      '       '        '         '
19
-
20
-my $force = $DEFAULT_FORCE;
21
-my $edit = $DEFAULT_EDIT;
22
-my $name; my $type; my $purpose;
23
-
24
-foreach (@ARGV) {
25
-    if (m/\b-f\b|\b--force\b/) {
26
-        $force++;
27
-    } elsif (m/\b-e\b|\b--edit\b/) {
28
-        $edit++;
29
-    } elsif (defined $type) {
30
-        $purpose = $_;
31
-    } elsif (defined $name) {
32
-        $type = $_;
33
-    } else {
34
-        $name = $_;
35
-    }
36
-}
37
-
38
-usage unless defined $name;
39
-$type = guesstype $name unless defined $type;
40
-$purpose = guesspurpose $name unless defined $purpose;
41
-
42
-my $bangs = {
43
-    pl   => `which perl`,
44
-    sh   => '/bin/sh',
45
-    py   => `which python`,
46
-    bash => '/bin/bash',
47
-    sed  => `which sed`,
48
-    bc   => `which bc`,
49
-    exp  => `which expect` . " -f",
50
-};
51
-
52
-my $templates = {
53
-    py => {
54
-        ''      => "if __name__ == '__main__':\n",
55
-        test    => "import unittest\n\n\n"
56
-                   . "class TestCase(unittest.TestCase):\n"
57
-                   . "    pass\n\n\n"
58
-                   . "if __name__ == '__main__':\n"
59
-                   ."    unittest.main()\n",
60
-    },
61
-    pl => {
62
-        ''      => "use strict;\nuse warnings;\n",
63
-        test    => "use strict;\nuse warnings;\nuse Test::More;\n\n",
64
-    },
65
-    bash => {
66
-        'ffoo'  => "\n. \"\$(ffoom path)\" || exit 3\n\n"
67
-                   . "ffoo import pretty\n\n"
68
-                   . "FFOO_DEBUG=true",
69
-        'shellfu'  => "\n. \"\$(shellfu-get path)\" || exit 3\n\n"
70
-                   . "shellfu import pretty\n\n"
71
-                   . "PRETTY_DEBUG=\${PRETTY_DEBUG:-true}\n\n"
72
-                   . "usage() {\n"
73
-                   . "    mkusage \"arg...\"\n"
74
-                   . "}\n\n"
75
-                   . "main() {\n"
76
-                   . "    while true; do case \$1 in\n"
77
-                   . "        -*) usage ;;\n"
78
-                   . "        *)  break ;;\n"
79
-                   . "    esac done\n"
80
-                   . "}\n\n"
81
-                   . "main \"\$@\"",
82
-    },
83
-};
84
-
85
-my $editors = [ qw/ vim editor / ];
86
-my $cmds;
87
-$cmds->{vim}->{test}    = "vim --version 2>/dev/null";
88
-$cmds->{vim}->{run}     = "vim +\"normal G\$\" '%s'";
89
-$cmds->{editor}->{test} = "editor --version 2>/dev/null";
90
-$cmds->{editor}->{run}  = "editor '%s'";
91
-
92
-unless ($purpose eq ""
93
-        or exists $templates->{$type}->{$purpose}) {
94
-    warn "undefined purpose '$purpose' for type '$type'\n";
95
-    $purpose = "";
96
-}
97
-
98
-
99
-## ... ##   # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
100
-## RUN ## ----------------------------------------------------------------- #
101
-## ''' ##   # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
102
-
103
-if (exists $bangs->{$type}) {
104
-    $force and -e $name
105
-        and (defined `cp "$name" "$name~"` or die $!);
106
-    (not -e $name or $force)
107
-        and mkexec $name, mkbody($type, $purpose);
108
-    chmod $DEFAULT_MODE, $name;
109
-    launch_editor $name if $edit;
110
-} else {
111
-    die "unknown type: $type\n";
112
-}
113
-
114
-
115
-## .... ##   ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''-.
116
-## SUBZ ## ----------------------------------------------------------------- :
117
-## '''' ##   ..............................................................-'
118
-
119
-sub usage {
120
-    print STDERR "usage: $0 [-f|-e] filename [type] [purpose]\n";
121
-    exit 0;
122
-}
123
-
124
-sub guesstype {
125
-    my $name = shift;
126
-    my ($ext) = $name =~ m|\.(\w+)$|;
127
-    return ( $ext ? $ext : $DEFAULT_TYPE);
128
-}
129
-
130
-sub guesspurpose {
131
-    my $name = shift;
132
-    my $testword = '[tT][eE][sS][tT]';
133
-    return 'test' if $name =~ m|^test_|i;
134
-    return 'test' if $name =~ m|_test.py$|i;
135
-    return 'test' if $name =~ m|_test.pl$|i;
136
-    return 'test' if $name =~ m|\btest\w*/|i;
137
-    return 'test' if $name =~ m|.*Test/|i;
138
-    return 'test' if $name =~ m|\bt/|;
139
-    return ''
140
-}
141
-
142
-sub mkbody {
143
-    my $type = shift;
144
-    my $purpose = shift;
145
-    my $tmpl = "";
146
-    $tmpl .= $templates->{$type}->{$purpose}
147
-        if exists $templates->{$type}
148
-            and exists $templates->{$type}->{$purpose};
149
-    return sprintf "#!%s\n%s\n", $bangs->{$type}, $tmpl;
150
-}
151
-
152
-sub mkexec {
153
-    my ($name, $body) = @_;
154
-    open EXE, ">", $name    or die "cannot open $name for writing: $!\n";
155
-    -W EXE                  or die "file $name is not writable\n";
156
-    print EXE $body;
157
-    close EXE               or die "cannot close $name: $!\n";
158
-}
159
-
160
-sub get_cmd {
161
-    foreach (@$editors) {
162
-        return $cmds->{$_}->{run} if `$cmds->{$_}->{test}`
163
-    }
164
-    warn "no supported editor available\n";
165
-    return;
166
-}
167
-
168
-sub launch_editor {
169
-    my $name = shift;
170
-    my $form = get_cmd;
171
-    if ($form) {
172
-        my $command = sprintf get_cmd, $name;
173
-        exec "$command";
174
-    } else { return }
175
-    warn "failed to launch editor: $form\n";
176
-}

+ 191
- 0
bin/mkx View File

@@ -0,0 +1,191 @@
1
+#!/bin/bash
2
+
3
+
4
+usage() {
5
+    local self
6
+    self="$(basename "$0")"
7
+    warn "usage: $self [-f|--force] FILE [[+]TEMPLATE]"
8
+    warn "usage: $self -l|--list"
9
+    exit 2
10
+}
11
+
12
+warn() {
13
+    #
14
+    # Print warning
15
+    #
16
+    echo "$@" >&2
17
+}
18
+
19
+die() {
20
+    #
21
+    # Warn and exit prematurely
22
+    #
23
+    warn "$@"
24
+    exit 3
25
+}
26
+
27
+lstemplates() {
28
+    #
29
+    # Print list of valid templates
30
+    #
31
+    echo +pya
32
+    echo +shellfu
33
+    echo Bash
34
+    echo Lua
35
+    echo Perl
36
+    echo py3
37
+    echo Python3
38
+    echo Python
39
+}
40
+
41
+#shellcheck disable=SC2016
42
+mktemplate() {
43
+    #
44
+    # Print template $1 for $FilePath
45
+    #
46
+    # Template may be a name of built-in template (starting with
47
+    # plus sign) or language name (actually *interpreter* name).
48
+    #
49
+    local tmplname="${1:-$Template}"
50
+    case "$tmplname" in
51
+        sh)
52
+            echo "#!/bin/sh"
53
+            echo ''
54
+            echo ''
55
+            ;;
56
+        bash|Bash)
57
+            echo "#!/bin/bash"
58
+            echo ''
59
+            echo ''
60
+            ;;
61
+        lua|Lua)
62
+            echo "#!$(which lua)"
63
+            echo ''
64
+            ;;
65
+        pl|Perl)
66
+            echo "#!$(which perl)"
67
+            echo ''
68
+            echo 'use strict;'
69
+            echo 'use warnings;'
70
+            echo ''
71
+            echo ''
72
+            ;;
73
+        py|Python)
74
+            echo "#!$(which python)"
75
+            echo ''
76
+            echo "if __name__ == '__main__':"
77
+            echo '    '
78
+            ;;
79
+        py3|Python3)
80
+            echo "#!/usr/bin/python3"
81
+            echo ''
82
+            echo "if __name__ == '__main__':"
83
+            echo '    '
84
+            ;;
85
+        +pya)
86
+            echo '#!/usr/bin/python'
87
+            echo '"""'
88
+            echo 'A simple application'
89
+            echo '"""'
90
+            echo ''
91
+            echo 'import sys'
92
+            echo ''
93
+            echo ''
94
+            echo 'class App(object):'
95
+            echo '    """'
96
+            echo '    Main application class'
97
+            echo '    """'
98
+            echo ''
99
+            echo '    def __init__(self, argv):'
100
+            echo '        self.argv = argv'
101
+            echo '        # agument decoding and further initializations'
102
+            echo ''
103
+            echo '    @classmethod'
104
+            echo '    def main(cls, argv):'
105
+            echo '        """'
106
+            echo '        Initialize and launch'
107
+            echo '        """'
108
+            echo '        app = cls(argv)'
109
+            echo '        app.run()'
110
+            echo ''
111
+            echo '    def run(self):'
112
+            echo '        """'
113
+            echo '        Run the application'
114
+            echo '        """'
115
+            echo '        # actual action (calling other methods)'
116
+            echo '        print self.argv'
117
+            echo '        print __doc__'
118
+            echo ''
119
+            echo ''
120
+            echo 'if __name__ == '__main__':'
121
+            echo '    App.main(sys.argv)'
122
+            ;;
123
+        +shellfu)
124
+            echo "#!/bin/bash"
125
+            echo ""
126
+            echo '. "$(shellfu-get path)" || exit 3'
127
+            echo ''
128
+            echo 'shellfu import pretty'
129
+            echo ''
130
+            echo 'PRETTY_DEBUG=${PRETTY_DEBUG:-true}'
131
+            echo ''
132
+            echo 'usage() {'
133
+            echo '    mkusage "arg..."'
134
+            echo '}'
135
+            echo ''
136
+            echo 'main() {'
137
+            echo '    while true; do case $1 in'
138
+            echo '        -*) usage ;;'
139
+            echo '        *)  break ;;'
140
+            echo '    esac done'
141
+            echo '}'
142
+            echo ''
143
+            echo 'main "$@"'
144
+            ;;
145
+        "")
146
+            mktemplate "$(guess_language)"
147
+            ;;
148
+        *)
149
+            die "unknown template or language: $Template"
150
+            ;;
151
+    esac
152
+}
153
+
154
+guess_language() {
155
+    #
156
+    # Guess intended language from filepath $FilePath
157
+    #
158
+    local fname     # file name
159
+    fname="$(basename "$FilePath")"
160
+    case "$fname" in
161
+        *.*)    echo "${fname##*.}" ;;
162
+        *)      echo "$MKX_DEFAULT_LANG" ;;
163
+    esac
164
+}
165
+
166
+
167
+#
168
+# Default language
169
+#
170
+MKX_DEFAULT_LANG=${MKX_DEFAULT_LANG:-sh}
171
+
172
+main() {
173
+    local FilePath  # destination file path
174
+    local Template  # built-in template name
175
+    local careful     # ignore existing file
176
+    careful=true
177
+    while true; do case $1 in
178
+        -f|--force) careful=false; shift ;;
179
+        -l|--list)  lstemplates; exit 0 ;;
180
+        -*) usage ;;
181
+        *)  break ;;
182
+    esac done
183
+    FilePath="$1"
184
+    Template="$2"
185
+    test -n "$FilePath" || usage
186
+    test -f "$FilePath" && $careful && die "file already exists: $FilePath"
187
+    mktemplate > "$FilePath"
188
+    chmod +x "$FilePath"
189
+}
190
+
191
+main "$@"