cknife 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/README.md +112 -326
- data/VERSION +1 -1
- data/bin/cknifewcdir +59 -20
- data/cknife.gemspec +3 -4
- metadata +1 -3
- data/bin/cknifezerigo +0 -97
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e24f7e41e3ed98f6d61a0d360b26f096862b121
|
4
|
+
data.tar.gz: fa9e6591fa5c4ac455e161f8a0766c254fb3aa56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8678596a96eeff55e41a21af3c1b6ac27ed1c5749451c839e33d9051041c507bd17668c548049fce8588126a26d3f9ad2789ebb2755cf267156fcc807481a255
|
7
|
+
data.tar.gz: 1510e3040a671d69d988f3cbfa7c0631f9ab68601b40d3aa1593bd1024995b70e4e39c677fea89ceaa172a35d5a8ada9124bb681606a0a5aaa802f6fb8635996
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.4
|
data/README.md
CHANGED
@@ -1,361 +1,147 @@
|
|
1
1
|
|
2
|
-
#
|
2
|
+
# Quickstart
|
3
3
|
|
4
|
-
cknife
|
5
|
-
to help with some system administration tasks.
|
6
|
-
|
7
|
-
# Requirements
|
8
|
-
|
9
|
-
Ruby >= 2.1.
|
10
|
-
|
11
|
-
# Installation
|
12
|
-
|
13
|
-
Install ruby and possibly bundler:
|
4
|
+
cknife is a set of command line tools. They...do different things.
|
14
5
|
|
15
6
|
> \curl -sSL https://get.rvm.io | bash -s stable --ruby
|
16
|
-
> gem install
|
17
|
-
|
18
|
-
Create a Gemfile with cknife and its git repository.
|
19
|
-
|
20
|
-
|
21
|
-
source "http://rubygems.org"
|
22
|
-
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
23
|
-
|
24
|
-
gem "cknife", '~> 1.1.0'
|
25
|
-
|
26
|
-
Run bundle.
|
27
|
-
|
28
|
-
> bundle
|
29
|
-
|
30
|
-
# Monitor
|
31
|
-
|
32
|
-
This sends out a PUT request every fifteen minutes to a server
|
33
|
-
you configure.
|
34
|
-
|
35
|
-
> bundle exec cknifemon
|
36
|
-
Tasks:
|
37
|
-
cknifemon help [TASK] # Describe available tasks or one specific task
|
38
|
-
cknifemon restart # Restart monitor.
|
39
|
-
cknifemon start # Start monitor.
|
40
|
-
cknifemon status # Show status of monitor.
|
41
|
-
cknifemon stop # Stop monitor.
|
42
|
-
|
43
|
-
It is designed to work with M. Rivera CRM, but you can configure the
|
44
|
-
url to be any endpoint for your own monitoring purposes. You can
|
45
|
-
configure alerts on the server that you create as the target endpoint
|
46
|
-
of the monitor.
|
47
|
-
|
48
|
-
The configuration is as follows:
|
49
|
-
|
50
|
-
mon:
|
51
|
-
url: http://some.server.com/monitored_computers/heartbeat
|
52
|
-
api_key: someapikey
|
53
|
-
|
54
|
-
# Amazon Web Services (AWS) Command Line Interface
|
55
|
-
|
56
|
-
> bundle exec cknifeaws help
|
57
|
-
Tasks:
|
58
|
-
cknifeaws afew [BUCKET_NAME] # Show first 5 files in bucket
|
59
|
-
cknifeaws create [BUCKET_NAME] # Create a bucket
|
60
|
-
cknifeaws create_cloudfront [BUCKET_NAME] # Create a cloudfront distribution (a CDN)
|
61
|
-
cknifeaws delete [BUCKET_NAME] # Destroy a bucket
|
62
|
-
cknifeaws download [BUCKET_NAME] # Download all files in a bucket to CWD. Or one file.
|
63
|
-
cknifeaws fdelete [BUCKET_NAME] [FILE_NAME] # Delete a file in a bucket.
|
64
|
-
cknifeaws fupload [BUCKET_NAME] [LOCAL_FILE] # Upload a file to a bucket. Path to file is ignored.
|
65
|
-
cknifeaws help [TASK] # Describe available tasks or one specific task
|
66
|
-
cknifeaws list # Show all buckets
|
67
|
-
cknifeaws list_cloudfront # List cloudfront distributions (CDNs)
|
68
|
-
cknifeaws list_servers # Show all servers
|
69
|
-
cknifeaws show [BUCKET_NAME] # Show info about bucket
|
70
|
-
cknifeaws start_server [SERVER_ID] # Start a given EC2 server
|
71
|
-
cknifeaws stop_server [SERVER_ID] # Stop a given EC2 server (does not terminate it)
|
72
|
-
cknifeaws upsync [BUCKET_NAME] [DIRECTORY] # Push local files matching glob PATTERN into bucket. Ignore unchanged files.
|
73
|
-
|
74
|
-
### AWS Key and Secret Configuration
|
75
|
-
|
76
|
-
Setup your AWS key and secret in any of these methods, in order of priority:
|
77
|
-
|
78
|
-
- $CWD/cknife.yml
|
79
|
-
- $CWD/tmp/cknife.yml
|
80
|
-
- environment variables: `KEY`, `SECRET`
|
81
|
-
- environment variables: `AMAZON_ACCESS_KEY_ID`, `AMAZON_SECRET_ACCESS_KEY`
|
7
|
+
> gem install cknife
|
82
8
|
|
83
|
-
|
84
|
-
is as follows:
|
9
|
+
Create `$CWD/tmp/cknife.yml` and put in a AWS key-secret pair:
|
85
10
|
|
86
11
|
---
|
87
12
|
key: AKIAblahblahb...
|
88
13
|
secret: 8xILhOsecretsecretsecretsecret...
|
89
14
|
|
90
|
-
|
91
|
-
|
92
|
-
Usage:
|
93
|
-
cknifeaws upsync [BUCKET_NAME] [DIRECTORY]
|
94
|
-
|
95
|
-
Options:
|
96
|
-
[--public]
|
97
|
-
[--region=REGION]
|
98
|
-
# Default: us-east-1
|
99
|
-
[--noprompt=NOPROMPT]
|
100
|
-
[--glob=GLOB]
|
101
|
-
# Default: **/*
|
102
|
-
[--backups-retain]
|
103
|
-
[--days-retain=N]
|
104
|
-
# Default: 30
|
105
|
-
[--months-retain=N]
|
106
|
-
# Default: 3
|
107
|
-
[--weeks-retain=N]
|
108
|
-
# Default: 5
|
109
|
-
[--dry-run]
|
110
|
-
|
111
|
-
Some examples:
|
112
|
-
|
113
|
-
Upload and sync `/tmp/*.sql` into `my-frog-app-backups`
|
114
|
-
bucket. Treat the files as backup files, and keep one backup
|
115
|
-
file for each of the last 5 months, 10 weeks, and 30 days.
|
116
|
-
|
117
|
-
> cknifeaws upsync my-frog-app-backups ./tmp --glob "*.sql" --noprompt --backups-retain true --months-retain 5 --weeks-retain 10 --days-retain 30
|
118
|
-
|
119
|
-
As above, but now do redis backup files (`./tmp/*.rdb`). these will
|
120
|
-
not produce namespace collisions with the sql files, and thus the same
|
121
|
-
bucket can be used to store backups for both .sql and .rdb files.
|
122
|
-
|
123
|
-
> cknifeaws upsync my-frog-app-backups ./tmp --glob "*.rdb" --noprompt --backups-retain true --months-retain 5 --weeks-retain 10 --days-retain 30
|
124
|
-
|
125
|
-
**DO NOT DO THIS INSTEAD OF THE ABOVE 2 COMMANDS, THINKING IT WILL
|
126
|
-
TREAT .SQL AND .RDB FILES SEPARATELY. INSTEAD, YOU WILL LOSE
|
127
|
-
SOME OF YOUR BACKUP FILES.**
|
128
|
-
|
129
|
-
> cknifeaws upsync my-frog-app-backups ./tmp --glob "*" --noprompt --backups-retain true --months-retain 5 --weeks-retain 10 --days-retain 30
|
130
|
-
|
131
|
-
Dry run mode. Try one of the prior backups retain commands, but
|
132
|
-
let's see what will happen, first.
|
133
|
-
|
134
|
-
> cknifeaws upsync my-frog-app-backups ./tmp --glob "*.sql" --noprompt --backups-retain true --months-retain 5 --weeks-retain 10 --days-retain 30 --dry-run
|
135
|
-
|
136
|
-
This is the premier feature of the gem.
|
137
|
-
|
138
|
-
Uses multipart uploads with a chunksize of 10 megabytes to keep RAM
|
139
|
-
usage down.
|
140
|
-
|
141
|
-
It can be used to run a backups schedule with multiple classes of
|
142
|
-
files (partitioned by a glob pattern). **It is your responsibility to
|
143
|
-
generate one uniquely-named backup file per day**, as this tool does
|
144
|
-
not do that part for you.
|
145
|
-
|
146
|
-
If you *don't* use the `backups-retain` option, then its like a very
|
147
|
-
weak **rsync** that can upload from a local filesystem into a bucket.
|
148
|
-
Which is also pretty useful.
|
149
|
-
|
150
|
-
The glob allows you to determine whether you want to recursively
|
151
|
-
upload an entire directory, or just a set of *.dat or *.sql files,
|
152
|
-
ignoring whatever else may be in the specified directory. This glob
|
153
|
-
pattern is appended to the directory you specify.
|
154
|
-
|
155
|
-
For determining whether to upload a file, it uses the file's local
|
156
|
-
filesystem modification time, and if there is a mismatch then it does
|
157
|
-
an md5 checksum comparison, and if there is a mismatch there, then the
|
158
|
-
local file will replace the remote one in S3. The file's local
|
159
|
-
filesystem modification time is stored on S3 in the S3 object's
|
160
|
-
metadata when the file is uploaded.
|
161
|
-
|
162
|
-
### Download an S3 bucket to a local directory
|
163
|
-
|
164
|
-
Sometimes you want to download an entire S3 bucket to your local
|
165
|
-
directory - a set of photos, for example.
|
166
|
-
|
167
|
-
> cknifeaws help download
|
168
|
-
Usage:
|
169
|
-
cknifeaws download [BUCKET_NAME]
|
15
|
+
Then invoke the `cknifeaws` tool.
|
170
16
|
|
171
|
-
|
172
|
-
[--region=REGION]
|
173
|
-
# Default: us-east-1
|
174
|
-
[--one=ONE]
|
17
|
+
> cknifeaws afew your-bucket-name
|
175
18
|
|
176
|
-
|
19
|
+
That will show you a few files in that Amazon S3 bucket of yours
|
20
|
+
named `your-bucket-name`.
|
177
21
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
#
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
line utilities.
|
241
|
-
|
242
|
-
It requires the following Rails-style configuration in the
|
243
|
-
configuration file:
|
244
|
-
|
245
|
-
pg:
|
246
|
-
host: localhost
|
247
|
-
database: dbname
|
248
|
-
username: dbuser
|
249
|
-
password: dbpassword
|
250
|
-
|
251
|
-
**Warning:** do not use a colon in your password, or the password
|
252
|
-
configuration will not work. This is a shortcoming of this project and
|
253
|
-
a consequence of the `.pgpass` file format used by PostgreSQL.
|
254
|
-
|
255
|
-
Then you can capture a snapshot of your database. You can also restore
|
256
|
-
it using this tool.
|
257
|
-
|
258
|
-
> bundle exec cknifepg help
|
259
|
-
Tasks:
|
260
|
-
cknifepg capture # Capture a dump of the database to db(current timestamp).dump.
|
261
|
-
cknifepg disconnect # Disconnect all sessions from the database. You must have a superuser configured for this to work.
|
262
|
-
cknifepg help [TASK] # Describe available tasks or one specific task
|
263
|
-
cknifepg restore # Restore a file. Use the one with the most recent mtime by default. Searches for db*.dump files in the CWD.
|
264
|
-
cknifepg sessions # List active sessions in this database and provide a string suitable for giving to kill for stopping those sessions.
|
265
|
-
|
266
|
-
This generates and deletes a `.pgpass` file before and after the
|
267
|
-
command line session. Be aware that if this process is interrupted,
|
268
|
-
the `.pgpass` file may be left on disk in the CWD.
|
269
|
-
|
270
|
-
# MySQL Backups
|
271
|
-
|
272
|
-
Like pg, this requires a similar setup in the configuration:
|
273
|
-
|
274
|
-
mysql:
|
275
|
-
host: localhost
|
276
|
-
database: dbname
|
277
|
-
username: dbuser
|
278
|
-
password: dbpassword
|
279
|
-
|
280
|
-
Then you can capture a snapshot of your database.
|
22
|
+
> cknifeaws afew my-bucket --count=50
|
23
|
+
|
24
|
+
That will show you 50 of them.
|
25
|
+
|
26
|
+
# Why bother?
|
27
|
+
|
28
|
+
What do you do when you don't want to write
|
29
|
+
[bash](https://www.tldp.org/LDP/Bash-Beginners-Guide/html/Bash-Beginners-Guide.html),
|
30
|
+
your `.bash_profile` already has more aliases than you can manage, and
|
31
|
+
yet you still find it silly to be going to the same [old documentation
|
32
|
+
websites](https://www.postgresql.org/docs/9.5/static/backup-dump.html)
|
33
|
+
for things you are certain you once knew how to do?
|
34
|
+
|
35
|
+
Well, you can write a script in something other than
|
36
|
+
bash to automate the precise command line invocation
|
37
|
+
that you used to accomplish a task. But when you
|
38
|
+
move to a different project, how can you take your
|
39
|
+
scripts with you? Why not design your scripts
|
40
|
+
to be robust enough so that they are conventional?
|
41
|
+
|
42
|
+
Why can't a [Stackoverflow](https://stackoverflow.com) question's
|
43
|
+
answer be captured in a form that can be configured and called by you
|
44
|
+
(or someone who was in your position before), so that you don't have
|
45
|
+
to enter the same question into
|
46
|
+
[google.com](https://www.google.com/?q=LOL%20HALP%20ME%20CODE) again
|
47
|
+
later down the road?
|
48
|
+
|
49
|
+
Why make a browser bookmark if you can skip the browser entirely?
|
50
|
+
It's not like the browser bookmark can compile the answer into machine
|
51
|
+
code for you, anyway.
|
52
|
+
|
53
|
+
If someone turns the answer into a programmed tool, what if your IDE
|
54
|
+
is no better than the command line when it comes to invoking it?
|
55
|
+
|
56
|
+
I created cknife to have a set of scripts to fall back on when
|
57
|
+
confronted with the above encounter I've been having for years. cknife
|
58
|
+
is a toolset that encapsulates common command line expressions that
|
59
|
+
developers use when at work.
|
60
|
+
|
61
|
+
I've never used [chef](https://www.chef.io), but were I to grow
|
62
|
+
cknife, I wouldn't be surprised to see it overlap with it.
|
63
|
+
|
64
|
+
cknife currently has some wrappers around Amazon's EC2 and S3
|
65
|
+
services. It has others around MySQL and PostgreSQL. It has a trivial
|
66
|
+
one around [du](http://man7.org/linux/man-pages/man1/du.1.html). The
|
67
|
+
`cknifemon` tool, meanwhile, is a daemon that can launch PUT HTTP
|
68
|
+
requests to an endpoint you configure, on a schedule.
|
69
|
+
|
70
|
+
It can be used for system administration, but it can be also be used
|
71
|
+
to aid developers as they acclimate themselves to a piece of
|
72
|
+
technology with which they may not be familiar, and for which
|
73
|
+
documentation may be a little scattered. It can be used
|
74
|
+
to bang on a piece of technology for the sake of your own
|
75
|
+
learning, too.
|
76
|
+
|
77
|
+
To be precise, cknife consists of command line executables. These
|
78
|
+
tools often require more information from the user, which can be put
|
79
|
+
into a configuration file, `cknife.yml`, in YAML format, and found by
|
80
|
+
cknife in the current working directory ($CWD) when it is invoked.
|
81
|
+
|
82
|
+
See the [Wiki](https://github.com/mikedll/cknife/wiki) for
|
83
|
+
details on the tools cknife has.
|
281
84
|
|
282
|
-
|
283
|
-
Tasks:
|
284
|
-
cknifemysql capture # Capture a dump of the database to db(current timestamp).sql.
|
285
|
-
cknifemysql help [TASK] # Describe available tasks or one specific task
|
286
|
-
cknifemysql restore # Restore a file. Use the one with the most recent mtime by default. Searches for db*.sql files in the CWD.
|
85
|
+
# Requirements
|
287
86
|
|
288
|
-
|
87
|
+
- Ruby >= 2.4. Older versions work to some extent with older rubies.
|
289
88
|
|
290
|
-
|
291
|
-
|
292
|
-
Captured db20150617125335.sql.
|
89
|
+
The cknife executables are implemented with the Ruby
|
90
|
+
[Thor](https://github.com/erikhuda/thor) gem.
|
293
91
|
|
294
|
-
|
92
|
+
# Installation
|
295
93
|
|
296
|
-
|
297
|
-
Restore db20150617125335.sql? y
|
298
|
-
Doing restore...
|
299
|
-
mysql --defaults-file=my.cnf -h localhost -P 3306 -u dbuser dbname
|
300
|
-
source db20150617125335.sql;
|
301
|
-
Restored db20150617125335.sql
|
94
|
+
Install Ruby and possibly bundler:
|
302
95
|
|
303
|
-
|
304
|
-
|
305
|
-
executing. This keeps your password off of the command line and
|
306
|
-
hidden from certain `top` or `ps` invocations by other users who may
|
307
|
-
be on the same machine. This rational is taken from the PostgreSQL
|
308
|
-
PGPASSFILE documentation. If this command error's-out, you'll be
|
309
|
-
warned to remove this file yourself for security purposes.
|
96
|
+
> \curl -sSL https://get.rvm.io | bash -s stable --ruby
|
97
|
+
> gem install bundler
|
310
98
|
|
311
|
-
|
99
|
+
Add cknife to a Gemfile.
|
312
100
|
|
313
|
-
|
314
|
-
|
101
|
+
source "http://rubygems.org"
|
102
|
+
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
315
103
|
|
316
|
-
|
317
|
-
37.0G .
|
318
|
-
23.0G ./Personal
|
319
|
-
14.0G ./Library
|
320
|
-
673.0M ./Work
|
321
|
-
0.0B ./Colloquy Transcripts
|
104
|
+
gem "cknife", '~> 1.1.0'
|
322
105
|
|
323
|
-
|
106
|
+
Run bundle.
|
324
107
|
|
325
|
-
|
108
|
+
> bundle
|
326
109
|
|
327
|
-
#
|
110
|
+
# Usage
|
328
111
|
|
329
|
-
|
330
|
-
|
331
|
-
|
112
|
+
The cknife tools make use of a common configuration file. It uses a
|
113
|
+
YAML format. It is named `cknife.yml` and the tools look for it in
|
114
|
+
these two places, in order:
|
332
115
|
|
333
|
-
|
116
|
+
- $CWD/cknife.yml
|
117
|
+
- $CWD/tmp/cknife.yml
|
334
118
|
|
335
|
-
|
119
|
+
Here are the command line executables:
|
336
120
|
|
337
|
-
|
121
|
+
- cknifeaws
|
122
|
+
- cknifedub
|
123
|
+
- cknifemail
|
124
|
+
- cknifemon
|
125
|
+
- cknifemysql
|
126
|
+
- cknifenowtimestamp
|
127
|
+
- cknifepg
|
128
|
+
- cknifewcdir
|
338
129
|
|
339
|
-
|
130
|
+
You can invoke any of them like this:
|
340
131
|
|
341
|
-
|
342
|
-
|
343
|
-
Which can be used with the following sample [crontab](http://en.wikipedia.org/wiki/Cron#Examples),
|
344
|
-
executing once a day at 2am:
|
132
|
+
bundle exec cknifeaws
|
345
133
|
|
346
|
-
|
347
|
-
# │ │ │ │ │
|
348
|
-
# │ │ │ │ │
|
349
|
-
# │ │ │ │ └───── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
|
350
|
-
# │ │ │ └────────── month (1 - 12)
|
351
|
-
# │ │ └─────────────── day of month (1 - 31)
|
352
|
-
# │ └──────────────────── hour (0 - 23)
|
353
|
-
# └───────────────────────── min (0 - 59)
|
134
|
+
# Security Awareness
|
354
135
|
|
355
|
-
|
136
|
+
Since the `cknife.yml` holds sensitive information in the name of
|
137
|
+
convenience, you may choose to erase it after you're done with what
|
138
|
+
you're doing with it. It depends on your use, of course. You probably
|
139
|
+
want to add it to your `.gitignore` file if you're using it on a
|
140
|
+
per-project basis.
|
356
141
|
|
142
|
+
# Development
|
357
143
|
|
358
|
-
|
144
|
+
## Making a release
|
359
145
|
|
360
146
|
One of the following, like patch. This will create a git commit.
|
361
147
|
|
@@ -366,7 +152,7 @@ One of the following, like patch. This will create a git commit.
|
|
366
152
|
Do a git flow release. Create the gem spec and commit it:
|
367
153
|
|
368
154
|
bundle exec rake gemspec:generate
|
369
|
-
git commit -am "Generated gemspec for version
|
155
|
+
git commit -am "Generated gemspec for version 1.3.0"
|
370
156
|
|
371
157
|
Do a git flow finish release. Push to github. You can
|
372
158
|
then do a release to Rubygems. This command will
|
@@ -375,7 +161,7 @@ since the gemspec is already valid.
|
|
375
161
|
|
376
162
|
rake release
|
377
163
|
|
378
|
-
|
164
|
+
## Building Locally (Optional)
|
379
165
|
|
380
166
|
You may build a local gem:
|
381
167
|
|
@@ -385,7 +171,7 @@ And remove it:
|
|
385
171
|
|
386
172
|
rm pkg/cknife-0.1.6.gem
|
387
173
|
|
388
|
-
|
174
|
+
## Invoking commands without clobbering the gemspec
|
389
175
|
|
390
176
|
You can uncommente the 'gem cknife' line in the Gemfile.
|
391
177
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.3.0
|
data/bin/cknifewcdir
CHANGED
@@ -1,28 +1,67 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
wccmd = `find . -ipath #{ARGV[0]} -exec wc -l {} \\;`
|
5
|
-
|
6
|
-
comps = []
|
7
|
-
|
8
|
-
total = 0
|
9
|
-
wccmd.split(/\n/).each do |l|
|
10
|
-
l =~ /\s*(\d+(\.\d+)?)\s+(.*)$/
|
11
|
-
size = $1
|
12
|
-
path = $3
|
13
|
-
comps << [size.to_i, path]
|
14
|
-
total += size.to_i
|
15
|
-
end
|
3
|
+
require 'thor'
|
16
4
|
|
17
|
-
|
18
|
-
|
19
|
-
|
5
|
+
class CKnifeWcdir < Thor
|
6
|
+
|
7
|
+
default_task :count
|
8
|
+
|
9
|
+
class_option :verbose, :default => false, :type => :boolean, :desc => "Show which commands are invoked, any input given to them, and any output they give back."
|
10
|
+
|
11
|
+
desc "count [PATTERNS] or simply [PATTERNS] without count will work", "Count lines of code in files matching the [PATTERNS] in the $CWD. Use patterns like this: *.rb, *.php."
|
12
|
+
long_desc <<-LONGDESC
|
13
|
+
Counts lines of code in the $CWD. Prints the files found, and
|
14
|
+
their line counts, in descending order of line count.
|
15
|
+
|
16
|
+
Requires patterns such as *.rb, or *.php, so that it knows what
|
17
|
+
files to count (it doesn't use a default file type).
|
18
|
+
|
19
|
+
You can supply directory names to exclude from consideration,
|
20
|
+
such as 'vendor' or 'node_modules'.
|
21
|
+
|
22
|
+
--skip=vendor node_modules
|
23
|
+
|
24
|
+
> cknifewcdir *.rb *.js --skip=vendor node_modules
|
25
|
+
\x5(...results...)
|
20
26
|
|
21
|
-
|
22
|
-
|
27
|
+
This is a wrapper around the find and wc posix commands.
|
28
|
+
LONGDESC
|
29
|
+
method_option :start, :type => :string, :default => "", :desc => "location to begin your search"
|
30
|
+
method_option :skip, :type => :array, :default => [], :desc => "names of directories to skip"
|
31
|
+
def count(*patterns)
|
32
|
+
start_point = options[:start].empty? ? "." : options[:start].chomp('/')
|
33
|
+
|
34
|
+
pattern_s = "\\( " + patterns.map { |p| "-name #{p}" }.join(' -o ') + " \\) "
|
35
|
+
skip_s = options[:skip].empty? ? "" : "-type d \\( " + options[:skip].map { |dir| "-path #{start_point}/#{dir.chomp('/')}" }.join(' -o ') + " \\) -prune -o "
|
36
|
+
|
37
|
+
# note patterns must go after the skips (after the -prune -o)
|
38
|
+
cmd = "find #{start_point} #{skip_s}#{pattern_s} -exec wc -l {} \\;"
|
39
|
+
|
40
|
+
puts cmd if options[:verbose]
|
41
|
+
wccmd = `#{cmd}`
|
42
|
+
|
43
|
+
comps = []
|
44
|
+
|
45
|
+
total = 0
|
46
|
+
wccmd.split(/\n/).each do |l|
|
47
|
+
l =~ /\s*(\d+(\.\d+)?)\s+(.*)$/
|
48
|
+
size = $1
|
49
|
+
path = $3
|
50
|
+
comps << [size.to_i, path]
|
51
|
+
total += size.to_i
|
52
|
+
end
|
53
|
+
|
54
|
+
comps.sort! do |a, b|
|
55
|
+
b[0] <=> a[0]
|
56
|
+
end
|
57
|
+
|
58
|
+
print_table([["LOC", "File"]] + comps)
|
59
|
+
|
60
|
+
puts "Total: #{total}"
|
23
61
|
end
|
24
62
|
|
25
|
-
puts "Total: #{total}"
|
26
63
|
end
|
27
64
|
|
28
|
-
|
65
|
+
ARGV.unshift(CKnifeWcdir.default_task) unless CKnifeWcdir.all_tasks.has_key?(ARGV[0])
|
66
|
+
CKnifeWcdir.start(ARGV)
|
67
|
+
|
data/cknife.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: cknife 1.
|
5
|
+
# stub: cknife 1.3.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "cknife".freeze
|
9
|
-
s.version = "1.
|
9
|
+
s.version = "1.3.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.date = "2018-10-10"
|
15
15
|
s.description = "A collection of command line tools, especially for popular API services.".freeze
|
16
16
|
s.email = "soymrmike@gmail.com".freeze
|
17
|
-
s.executables = ["cknifeaws".freeze, "cknifedub".freeze, "cknifemail".freeze, "cknifemon".freeze, "cknifemysql".freeze, "cknifenowtimestamp".freeze, "cknifepg".freeze, "cknifewcdir".freeze
|
17
|
+
s.executables = ["cknifeaws".freeze, "cknifedub".freeze, "cknifemail".freeze, "cknifemon".freeze, "cknifemysql".freeze, "cknifenowtimestamp".freeze, "cknifepg".freeze, "cknifewcdir".freeze]
|
18
18
|
s.extra_rdoc_files = [
|
19
19
|
"LICENSE",
|
20
20
|
"README.md"
|
@@ -36,7 +36,6 @@ Gem::Specification.new do |s|
|
|
36
36
|
"bin/cknifenowtimestamp",
|
37
37
|
"bin/cknifepg",
|
38
38
|
"bin/cknifewcdir",
|
39
|
-
"bin/cknifezerigo",
|
40
39
|
"cknife.gemspec",
|
41
40
|
"cknife.yml.sample",
|
42
41
|
"doc/remote_ubuntu_machine.md",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cknife
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Rivera
|
@@ -227,7 +227,6 @@ executables:
|
|
227
227
|
- cknifenowtimestamp
|
228
228
|
- cknifepg
|
229
229
|
- cknifewcdir
|
230
|
-
- cknifezerigo
|
231
230
|
extensions: []
|
232
231
|
extra_rdoc_files:
|
233
232
|
- LICENSE
|
@@ -249,7 +248,6 @@ files:
|
|
249
248
|
- bin/cknifenowtimestamp
|
250
249
|
- bin/cknifepg
|
251
250
|
- bin/cknifewcdir
|
252
|
-
- bin/cknifezerigo
|
253
251
|
- cknife.gemspec
|
254
252
|
- cknife.yml.sample
|
255
253
|
- doc/remote_ubuntu_machine.md
|
data/bin/cknifezerigo
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'rest-client'
|
4
|
-
require 'thor'
|
5
|
-
require 'active_support/all'
|
6
|
-
|
7
|
-
class Zerigo < Thor
|
8
|
-
|
9
|
-
ENDPOINT = "https://ns.zerigo.com/api/1.1"
|
10
|
-
USERNAME = ENV['ZERIGO_USERNAME']
|
11
|
-
PASSWORD = ENV['ZERIGO_PASSWORD']
|
12
|
-
DOMAIN = ENV['ZERIGO_DEFAULT_DOMAIN']
|
13
|
-
|
14
|
-
|
15
|
-
no_tasks do
|
16
|
-
def zerigo
|
17
|
-
@zerigo ||= RestClient::Resource.new ENDPOINT, USERNAME, PASSWORD
|
18
|
-
end
|
19
|
-
|
20
|
-
def show_hosts(response)
|
21
|
-
fmt = "%6.5s %30.29s %40.39s %12.11s"
|
22
|
-
|
23
|
-
puts sprintf(fmt,
|
24
|
-
"Type",
|
25
|
-
"Hostname",
|
26
|
-
"Data",
|
27
|
-
"ID")
|
28
|
-
|
29
|
-
Nokogiri::XML( response.body ).css('host').each do |host|
|
30
|
-
puts sprintf(fmt,
|
31
|
-
host.at_css('host-type').text,
|
32
|
-
host.at_css('hostname').text,
|
33
|
-
host.at_css('data').text,
|
34
|
-
host.at_css('id').text)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def zone
|
39
|
-
if @zone.nil?
|
40
|
-
zones = []
|
41
|
-
response = zerigo['/zones.xml'].get
|
42
|
-
unless response.code.to_s !~ /2\d{2}/
|
43
|
-
Nokogiri::XML( response.body ).css('zone').each do |zone|
|
44
|
-
zones << {
|
45
|
-
:id => zone.css('id').first.text,
|
46
|
-
:domain => zone.css('domain').first.text,
|
47
|
-
}
|
48
|
-
end
|
49
|
-
end
|
50
|
-
found = zones.select { |z| z[:domain] == DOMAIN }.first
|
51
|
-
raise "Unable to find zone matching domain #{DOMAIN}" unless found
|
52
|
-
|
53
|
-
@zone = found[:id]
|
54
|
-
end
|
55
|
-
@zone
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
module HostTypes
|
60
|
-
CNAME = "CNAME"
|
61
|
-
ARECORD = "A"
|
62
|
-
MX = "MX"
|
63
|
-
end
|
64
|
-
|
65
|
-
desc "list", "List available host names."
|
66
|
-
def list
|
67
|
-
response = zerigo["/zones/#{zone}/hosts.xml"].get
|
68
|
-
unless response.code.to_s !~ /2\d{2}/
|
69
|
-
show_hosts( response )
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
desc "create [HOST_NAME]", "Create a host"
|
74
|
-
method_options :data => "proxy.heroku.com"
|
75
|
-
method_options :host_type => HostTypes::CNAME
|
76
|
-
def create(hostname = "")
|
77
|
-
new_host = { :data => options[:data], :host_type => options[:host_type], :hostname => hostname }
|
78
|
-
|
79
|
-
response = zerigo["/zones/#{zone}/hosts.xml"].post new_host.to_xml(:root => "host"), :content_type => "application/xml"
|
80
|
-
if response.code.to_s =~ /201/
|
81
|
-
puts "Created a host."
|
82
|
-
show_hosts( response )
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
|
87
|
-
desc "delete [ID]", "Delete an entry by id"
|
88
|
-
def delete(id)
|
89
|
-
response = zerigo["/hosts/#{id}.xml"].delete
|
90
|
-
if response.code.to_s =~ /200/
|
91
|
-
puts "Delete a host with id #{id}"
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
|
97
|
-
Zerigo.start
|