dot_usage 0.1.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 +7 -0
- data/.gitignore +11 -0
- data/.travis.yml +5 -0
- data/.usage.yml +10 -0
- data/Gemfile +4 -0
- data/README.md +102 -0
- data/Rakefile +10 -0
- data/_config.yml +30 -0
- data/bin/console +14 -0
- data/bin/generate_site +12 -0
- data/bin/setup +8 -0
- data/data/example.usage.yml +15 -0
- data/dot_usage.gemspec +25 -0
- data/exe/dot_usage +123 -0
- data/index.md +108 -0
- data/lib/dot_usage.rb +143 -0
- data/lib/dot_usage/markdown.rb +62 -0
- data/lib/dot_usage/version.rb +3 -0
- data/site/css/modest.css +221 -0
- metadata +119 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 3755f4c87fb8d99aca2dfdf9a6e235ea969137ab
|
|
4
|
+
data.tar.gz: 49b60a77f0626cae034c9961a84a7a1faa534ebb
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 86589255a119b3b6b58709ce8ba97f8904533300a0953323e102fa1d600837c700da733302e9af88bf132fc295f25f93562e012522a19fce6a29fd3328826205
|
|
7
|
+
data.tar.gz: 69e746e3805555b533f028a7b301f41f5fa326e285ae4c2e239bb482ea87bc55cb104c3c3b9904e0f9bbcfc8f64493a86b101834da12bebe1781194d286ba749
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/.usage.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# [dot_usage](https://beneills.github.io/dot_usage/)
|
|
2
|
+
|
|
3
|
+
_a file format and utility to control building, running and testing source code_
|
|
4
|
+
|
|
5
|
+
1) __Define__ some targets for your project either explicitly, or by pointing to existing documentation:
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
# .usage.yml
|
|
9
|
+
|
|
10
|
+
install:
|
|
11
|
+
- gem install dot_usage
|
|
12
|
+
|
|
13
|
+
test:
|
|
14
|
+
- rake test
|
|
15
|
+
|
|
16
|
+
help:
|
|
17
|
+
README.md: "## Getting Help"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2) Then your users can safely __execute__ the targets:
|
|
21
|
+
|
|
22
|
+
```shell
|
|
23
|
+
$ gem install dot_usage
|
|
24
|
+
|
|
25
|
+
$ cd my_project && ls -a
|
|
26
|
+
.usage.yml ...
|
|
27
|
+
|
|
28
|
+
$ dot_usage install
|
|
29
|
+
Installing dot_usage (guided)
|
|
30
|
+
> Run `gem install dot_usage` [Y/n]? y
|
|
31
|
+
Successfully installed.
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Rationale
|
|
35
|
+
|
|
36
|
+
We present a single interface for users to interact with your repository, without learning/remembering incantations for twenty different build systems. This makes is quicker for them to get started using or contributing.
|
|
37
|
+
|
|
38
|
+
## Features
|
|
39
|
+
|
|
40
|
+
*dot_usage* allows project maintainers to easily communicate how to interact with a repository, in a way that a machine can understand. This can be used to supplement the usual human-readable instructions in _README.md_. Crucially, we permit linking to code snippets in Markdown documents, meaning no code duplication.
|
|
41
|
+
|
|
42
|
+
We allow arbitrary targets, but recommend using __install__, __build__, __test__, and __help__.
|
|
43
|
+
|
|
44
|
+
### Target Recipes
|
|
45
|
+
```yaml
|
|
46
|
+
# Define recipes as a list of shell commands
|
|
47
|
+
target-one:
|
|
48
|
+
- echo "command one"
|
|
49
|
+
- echo "command two"
|
|
50
|
+
|
|
51
|
+
# Or as a link to a Markdown section with a single code snippet
|
|
52
|
+
target-two:
|
|
53
|
+
README.md: "### Doing thing two"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Guided Invocation
|
|
57
|
+
```shell
|
|
58
|
+
# Prompt before every command
|
|
59
|
+
$ dot_usage install
|
|
60
|
+
Installing dot_usage (guided)
|
|
61
|
+
> Run `gem install dot_usage` [Y/n]? y
|
|
62
|
+
Successfully installed.
|
|
63
|
+
|
|
64
|
+
# Or run them blindly
|
|
65
|
+
$ dot_usage install -y
|
|
66
|
+
Installing dot_usage (guided)
|
|
67
|
+
> Running `gem install dot_usage`
|
|
68
|
+
Successfully installed.
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Listing Targets
|
|
72
|
+
```
|
|
73
|
+
# Run with -v for full command listing
|
|
74
|
+
$ dot_usage
|
|
75
|
+
Available targets:
|
|
76
|
+
- install
|
|
77
|
+
- test
|
|
78
|
+
- help
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Generating a dotfile
|
|
82
|
+
```
|
|
83
|
+
$ cd my_project
|
|
84
|
+
$ dot_usage
|
|
85
|
+
Generated .usage.yml
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Getting Help
|
|
89
|
+
|
|
90
|
+
```shell
|
|
91
|
+
dot_usage -h
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Development
|
|
95
|
+
|
|
96
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
97
|
+
|
|
98
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
99
|
+
|
|
100
|
+
## Contributing
|
|
101
|
+
|
|
102
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/beneills/dot_usage.
|
data/Rakefile
ADDED
data/_config.yml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Welcome to Jekyll!
|
|
2
|
+
#
|
|
3
|
+
# This config file is meant for settings that affect your whole blog, values
|
|
4
|
+
# which you are expected to set up once and rarely need to edit after that.
|
|
5
|
+
# For technical reasons, this file is *NOT* reloaded automatically when you use
|
|
6
|
+
# 'jekyll serve'. If you change this file, please restart the server process.
|
|
7
|
+
|
|
8
|
+
# Site settings
|
|
9
|
+
title: dot_usage
|
|
10
|
+
description: a file format and utility to control building, running and testing source code
|
|
11
|
+
github_username: beneills
|
|
12
|
+
|
|
13
|
+
exclude:
|
|
14
|
+
- bin
|
|
15
|
+
- data
|
|
16
|
+
- exe
|
|
17
|
+
- lib
|
|
18
|
+
- test
|
|
19
|
+
- Gemfile
|
|
20
|
+
- Gemfile.lock
|
|
21
|
+
- README.md
|
|
22
|
+
- Rakefile
|
|
23
|
+
- dot_usage.gemspec
|
|
24
|
+
|
|
25
|
+
include:
|
|
26
|
+
- index.md
|
|
27
|
+
|
|
28
|
+
# Build settings
|
|
29
|
+
markdown: kramdown
|
|
30
|
+
highlighter: rouge
|
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "dot_usage"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start
|
data/bin/generate_site
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
cat > index.md <<- EOM
|
|
4
|
+
---
|
|
5
|
+
---
|
|
6
|
+
<link rel="stylesheet" type="text/css" href="site/css/modest.css">
|
|
7
|
+
|
|
8
|
+
<a href="https://github.com/beneills/dot_usage"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/e7bbb0521b397edbd5fe43e7f760759336b5e05f/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677265656e5f3030373230302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png"></a>
|
|
9
|
+
|
|
10
|
+
EOM
|
|
11
|
+
|
|
12
|
+
cat README.md >> index.md
|
data/bin/setup
ADDED
data/dot_usage.gemspec
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'dot_usage/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "dot_usage"
|
|
8
|
+
spec.version = DotUsage::VERSION
|
|
9
|
+
spec.licenses = ['MIT']
|
|
10
|
+
spec.authors = ["Ben Eills"]
|
|
11
|
+
spec.email = ["ben@beneills.com"]
|
|
12
|
+
|
|
13
|
+
spec.summary = %q{File format and utility to control building, running and testing source code.}
|
|
14
|
+
spec.homepage = "https://github.com/beneills/dot_usage"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
17
|
+
spec.bindir = "exe"
|
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
|
22
|
+
spec.add_development_dependency "jekyll", "~> 3.1"
|
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
24
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
|
25
|
+
end
|
data/exe/dot_usage
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'optparse'
|
|
5
|
+
require 'optparse/time'
|
|
6
|
+
require 'ostruct'
|
|
7
|
+
require 'pp'
|
|
8
|
+
|
|
9
|
+
require 'dot_usage'
|
|
10
|
+
require 'dot_usage/version'
|
|
11
|
+
|
|
12
|
+
DEFAULT_DOT_USAGE_FILE = '.usage.yml'
|
|
13
|
+
EXAMPLE_FILE = 'data/example.usage.yml'
|
|
14
|
+
|
|
15
|
+
class DotUsageOptparse
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
# Return a structure describing the options after consuming some of args.
|
|
19
|
+
#
|
|
20
|
+
def self.parse(args)
|
|
21
|
+
# The options specified on the command line will be collected in *options*.
|
|
22
|
+
# We set default values here.
|
|
23
|
+
options = OpenStruct.new
|
|
24
|
+
options.file = DEFAULT_DOT_USAGE_FILE
|
|
25
|
+
options.yes = false
|
|
26
|
+
options.verbose = false
|
|
27
|
+
|
|
28
|
+
opt_parser = OptionParser.new do |opts|
|
|
29
|
+
opts.banner = "Usage: dot_usage [TARGET [options]]"
|
|
30
|
+
|
|
31
|
+
opts.separator ""
|
|
32
|
+
opts.separator "Specific options:"
|
|
33
|
+
|
|
34
|
+
opts.on("-f", "--file FILE",
|
|
35
|
+
"Use a custom dot_usage file") do |f|
|
|
36
|
+
options.file = f
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
opts.on("-y", "--yes", "Run target blindly without prompting") do |v|
|
|
40
|
+
options.yes = v
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
|
44
|
+
options.verbose = v
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
opts.separator ""
|
|
48
|
+
opts.separator "Common options:"
|
|
49
|
+
|
|
50
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
|
51
|
+
puts opts
|
|
52
|
+
exit
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
opts.on_tail("--version", "Show version") do
|
|
56
|
+
puts DotUsage::VERSION
|
|
57
|
+
exit
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
opt_parser.parse! args
|
|
62
|
+
options
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# List targets in current directory.
|
|
68
|
+
#
|
|
69
|
+
def list(options)
|
|
70
|
+
DotUsage.list_targets options
|
|
71
|
+
|
|
72
|
+
0
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
#
|
|
76
|
+
# Generate a dotfile in current directory.
|
|
77
|
+
#
|
|
78
|
+
def generate(options)
|
|
79
|
+
# Check for existing dotfile
|
|
80
|
+
if File.exists? DEFAULT_DOT_USAGE_FILE
|
|
81
|
+
STDERR.puts "#{DEFAULT_DOT_USAGE_FILE} already exists!"
|
|
82
|
+
return 1
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
FileUtils.copy EXAMPLE_FILE, DEFAULT_DOT_USAGE_FILE
|
|
86
|
+
|
|
87
|
+
puts "Generated #{DEFAULT_DOT_USAGE_FILE}"
|
|
88
|
+
|
|
89
|
+
0
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
#
|
|
93
|
+
# Run a given target
|
|
94
|
+
#
|
|
95
|
+
def run_target(target, options)
|
|
96
|
+
DotUsage.run_target target, options
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# Main entry point.
|
|
101
|
+
#
|
|
102
|
+
def main
|
|
103
|
+
options = DotUsageOptparse.parse(ARGV)
|
|
104
|
+
|
|
105
|
+
ret = case ARGV.length
|
|
106
|
+
when 0
|
|
107
|
+
if File.exists? options.file
|
|
108
|
+
list options
|
|
109
|
+
else
|
|
110
|
+
generate options
|
|
111
|
+
end
|
|
112
|
+
when 1
|
|
113
|
+
target = ARGV.pop
|
|
114
|
+
run_target target, options
|
|
115
|
+
else
|
|
116
|
+
puts 'bad'
|
|
117
|
+
1
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
exit ret
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
main
|
data/index.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
---
|
|
3
|
+
<link rel="stylesheet" type="text/css" href="site/css/modest.css">
|
|
4
|
+
|
|
5
|
+
<a href="https://github.com/beneills/dot_usage"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/e7bbb0521b397edbd5fe43e7f760759336b5e05f/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677265656e5f3030373230302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png"></a>
|
|
6
|
+
|
|
7
|
+
# dot_usage
|
|
8
|
+
|
|
9
|
+
_a file format and utility to control building, running and testing source code_
|
|
10
|
+
|
|
11
|
+
1) __Define__ some targets for your project either explicitly, or by pointing to existing documentation:
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
# .usage.yml
|
|
15
|
+
|
|
16
|
+
install:
|
|
17
|
+
- gem install dot_usage
|
|
18
|
+
|
|
19
|
+
test:
|
|
20
|
+
- rake test
|
|
21
|
+
|
|
22
|
+
help:
|
|
23
|
+
README.md: "## Getting Help"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
2) Then your users can safely __execute__ the targets:
|
|
27
|
+
|
|
28
|
+
```shell
|
|
29
|
+
$ gem install dot_usage
|
|
30
|
+
|
|
31
|
+
$ cd my_project && ls -a
|
|
32
|
+
.usage.yml ...
|
|
33
|
+
|
|
34
|
+
$ dot_usage install
|
|
35
|
+
Installing dot_usage (guided)
|
|
36
|
+
> Run `gem install dot_usage` [Y/n]? y
|
|
37
|
+
Successfully installed.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Rationale
|
|
41
|
+
|
|
42
|
+
We present a single interface for users to interact with your repository, without learning/remembering incantations for twenty different build systems. This makes is quicker for them to get started using or contributing.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
*dot_usage* allows project maintainers to easily communicate how to interact with a repository, in a way that a machine can understand. This can be used to supplement the usual human-readable instructions in _README.md_. Crucially, we permit linking to code snippets in Markdown documents, meaning no code duplication.
|
|
47
|
+
|
|
48
|
+
We allow arbitrary targets, but recommend using __install__, __build__, __test__, and __help__.
|
|
49
|
+
|
|
50
|
+
### Target Recipes
|
|
51
|
+
```yaml
|
|
52
|
+
# Define recipes as a list of shell commands
|
|
53
|
+
target-one:
|
|
54
|
+
- echo "command one"
|
|
55
|
+
- echo "command two"
|
|
56
|
+
|
|
57
|
+
# Or as a link to a Markdown section with a single code snippet
|
|
58
|
+
target-two:
|
|
59
|
+
README.md: "### Doing thing two"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Guided Invocation
|
|
63
|
+
```shell
|
|
64
|
+
# Prompt before every command
|
|
65
|
+
$ dot_usage install
|
|
66
|
+
Installing dot_usage (guided)
|
|
67
|
+
> Run `gem install dot_usage` [Y/n]? y
|
|
68
|
+
Successfully installed.
|
|
69
|
+
|
|
70
|
+
# Or run them blindly
|
|
71
|
+
$ dot_usage install -y
|
|
72
|
+
Installing dot_usage (guided)
|
|
73
|
+
> Running `gem install dot_usage`
|
|
74
|
+
Successfully installed.
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Listing Targets
|
|
78
|
+
```
|
|
79
|
+
# Run with -v for full command listing
|
|
80
|
+
$ dot_usage
|
|
81
|
+
Available targets:
|
|
82
|
+
- install
|
|
83
|
+
- test
|
|
84
|
+
- help
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Generating a dotfile
|
|
88
|
+
```
|
|
89
|
+
$ cd my_project
|
|
90
|
+
$ dot_usage
|
|
91
|
+
Generated .usage.yml
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Getting Help
|
|
95
|
+
|
|
96
|
+
```shell
|
|
97
|
+
dot_usage -h
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Development
|
|
101
|
+
|
|
102
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
103
|
+
|
|
104
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
105
|
+
|
|
106
|
+
## Contributing
|
|
107
|
+
|
|
108
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/beneills/dot_usage.
|
data/lib/dot_usage.rb
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require 'open3'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
require "dot_usage/markdown"
|
|
5
|
+
require "dot_usage/version"
|
|
6
|
+
|
|
7
|
+
module DotUsage
|
|
8
|
+
class DotUsageFile
|
|
9
|
+
def initialize(filename)
|
|
10
|
+
@filename = filename
|
|
11
|
+
@data = YAML.load_file filename
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def targets
|
|
15
|
+
@data.keys
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def recipe(target)
|
|
19
|
+
content = @data[target]
|
|
20
|
+
|
|
21
|
+
if content.instance_of? Array
|
|
22
|
+
content
|
|
23
|
+
elsif content.instance_of? String
|
|
24
|
+
[content]
|
|
25
|
+
elsif content.instance_of? Hash
|
|
26
|
+
unless 1 == content.length
|
|
27
|
+
STDERR.puts content
|
|
28
|
+
STDERR.puts 'Error: hash may only have one entry!'
|
|
29
|
+
return 1
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
md = MarkdownFile.new content.keys.first
|
|
33
|
+
|
|
34
|
+
md.snippet content.values.first
|
|
35
|
+
else
|
|
36
|
+
STDERR.puts content
|
|
37
|
+
STDERR.puts 'Error: invalid recipe!'
|
|
38
|
+
1
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class Target
|
|
44
|
+
def initialize(name)
|
|
45
|
+
@name = name
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def recipe(options)
|
|
49
|
+
file = DotUsageFile.new(options.file)
|
|
50
|
+
|
|
51
|
+
file.recipe @name
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def run(options)
|
|
55
|
+
recipe(options).each do |cmd|
|
|
56
|
+
status = Command.new(cmd).run(options)
|
|
57
|
+
|
|
58
|
+
unless status
|
|
59
|
+
STDERR.puts '> Command failed. Aborting!'
|
|
60
|
+
return 1
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
0
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
class Command
|
|
69
|
+
def initialize(cmd)
|
|
70
|
+
@cmd = cmd
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def run(options)
|
|
74
|
+
if options.yes
|
|
75
|
+
run_without_prompt(options)
|
|
76
|
+
else
|
|
77
|
+
run_with_prompt(options)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
def execute(cmd)
|
|
84
|
+
system cmd
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def run_without_prompt(options)
|
|
88
|
+
puts "> Running `#{@cmd}`"
|
|
89
|
+
|
|
90
|
+
execute @cmd
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def run_with_prompt(options)
|
|
94
|
+
print "> Run `#{@cmd}` [Y/n]? "
|
|
95
|
+
|
|
96
|
+
go = case gets.chomp
|
|
97
|
+
when "y", "Y", "yes", ""
|
|
98
|
+
true
|
|
99
|
+
when "n", "N", "no"
|
|
100
|
+
false
|
|
101
|
+
else
|
|
102
|
+
STDERR.puts '> Invalid choice!'
|
|
103
|
+
false
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
if go
|
|
107
|
+
execute @cmd
|
|
108
|
+
else
|
|
109
|
+
puts "Quitting!"
|
|
110
|
+
1
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
# List targets
|
|
117
|
+
#
|
|
118
|
+
def self.list_targets(options)
|
|
119
|
+
file = DotUsageFile.new options.file
|
|
120
|
+
|
|
121
|
+
puts "Available targets:"
|
|
122
|
+
file.targets.each do |target|
|
|
123
|
+
puts " - #{target}"
|
|
124
|
+
|
|
125
|
+
if options.verbose
|
|
126
|
+
Target.new(target).recipe(options).each do |cmd|
|
|
127
|
+
puts " `#{cmd}`"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
0
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
#
|
|
136
|
+
# Run a given target
|
|
137
|
+
#
|
|
138
|
+
def self.run_target(target, options)
|
|
139
|
+
target = Target.new target
|
|
140
|
+
|
|
141
|
+
target.run options
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
INDENTATION = " "
|
|
2
|
+
|
|
3
|
+
class MarkdownFile
|
|
4
|
+
def initialize(filename)
|
|
5
|
+
@filename = filename
|
|
6
|
+
@contents = File.read filename
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def section(heading)
|
|
10
|
+
after_heading_regexp = /^#{heading}$(?<after>.+)/m
|
|
11
|
+
next_heading_regexp = /(?<section>.+)^#+/m
|
|
12
|
+
|
|
13
|
+
after_match_data = after_heading_regexp.match @contents
|
|
14
|
+
return nil unless after_match_data
|
|
15
|
+
|
|
16
|
+
after_heading = after_match_data[:after]
|
|
17
|
+
|
|
18
|
+
before_match_data = next_heading_regexp.match after_heading
|
|
19
|
+
return nil unless before_match_data
|
|
20
|
+
|
|
21
|
+
before_match_data[:section]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def snippet(heading)
|
|
25
|
+
s = section heading
|
|
26
|
+
return nil if s.nil?
|
|
27
|
+
|
|
28
|
+
[extract_quoted_snippet(s), extract_indented_snippet(s)].select { |r| ! r.nil? }.first
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
# Try to extract a triple quoted snippet from the section
|
|
34
|
+
#
|
|
35
|
+
# Otherwise, return nil
|
|
36
|
+
def extract_quoted_snippet(section)
|
|
37
|
+
quoted_snipped_regexp = /^```\S*$(?<quoted_snippet>.+?)^```$/m
|
|
38
|
+
|
|
39
|
+
match_data = quoted_snipped_regexp.match(section)
|
|
40
|
+
|
|
41
|
+
if match_data
|
|
42
|
+
match_data[:quoted_snippet].strip.split "\n"
|
|
43
|
+
else
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Try to extract an indented snippet from the section
|
|
49
|
+
#
|
|
50
|
+
# Otherwise, return nil
|
|
51
|
+
def extract_indented_snippet(section)
|
|
52
|
+
indentation_regexp = /^(?<after>#{INDENTATION}.+)$/m
|
|
53
|
+
|
|
54
|
+
match_data = indentation_regexp.match(section)
|
|
55
|
+
|
|
56
|
+
if match_data
|
|
57
|
+
match_data[:after].lines.take_while { |line| line.strip.empty? or line.start_with? INDENTATION }.map { |l| l.strip }.select { |l| ! l.empty?}
|
|
58
|
+
else
|
|
59
|
+
nil
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
data/site/css/modest.css
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# From https://github.com/markdowncss/modest
|
|
2
|
+
|
|
3
|
+
@media print {
|
|
4
|
+
*,
|
|
5
|
+
*:before,
|
|
6
|
+
*:after {
|
|
7
|
+
background: transparent !important;
|
|
8
|
+
color: #000 !important;
|
|
9
|
+
box-shadow: none !important;
|
|
10
|
+
text-shadow: none !important;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
a,
|
|
14
|
+
a:visited {
|
|
15
|
+
text-decoration: underline;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
a[href]:after {
|
|
19
|
+
content: " (" attr(href) ")";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
abbr[title]:after {
|
|
23
|
+
content: " (" attr(title) ")";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
a[href^="#"]:after,
|
|
27
|
+
a[href^="javascript:"]:after {
|
|
28
|
+
content: "";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
pre,
|
|
32
|
+
blockquote {
|
|
33
|
+
border: 1px solid #999;
|
|
34
|
+
page-break-inside: avoid;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
thead {
|
|
38
|
+
display: table-header-group;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
tr,
|
|
42
|
+
img {
|
|
43
|
+
page-break-inside: avoid;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
img {
|
|
47
|
+
max-width: 100% !important;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
p,
|
|
51
|
+
h2,
|
|
52
|
+
h3 {
|
|
53
|
+
orphans: 3;
|
|
54
|
+
widows: 3;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
h2,
|
|
58
|
+
h3 {
|
|
59
|
+
page-break-after: avoid;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
pre,
|
|
64
|
+
code {
|
|
65
|
+
font-family: Menlo, Monaco, "Courier New", monospace;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
pre {
|
|
69
|
+
padding: .5rem;
|
|
70
|
+
line-height: 1.25;
|
|
71
|
+
overflow-x: scroll;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
a,
|
|
75
|
+
a:visited {
|
|
76
|
+
color: #3498db;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
a:hover,
|
|
80
|
+
a:focus,
|
|
81
|
+
a:active {
|
|
82
|
+
color: #2980b9;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.modest-no-decoration {
|
|
86
|
+
text-decoration: none;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
html {
|
|
90
|
+
font-size: 12px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@media screen and (min-width: 32rem) and (max-width: 48rem) {
|
|
94
|
+
html {
|
|
95
|
+
font-size: 15px;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@media screen and (min-width: 48rem) {
|
|
100
|
+
html {
|
|
101
|
+
font-size: 16px;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
body {
|
|
106
|
+
line-height: 1.85;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
p,
|
|
110
|
+
.modest-p {
|
|
111
|
+
font-size: 1rem;
|
|
112
|
+
margin-bottom: 1.3rem;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
h1,
|
|
116
|
+
.modest-h1,
|
|
117
|
+
h2,
|
|
118
|
+
.modest-h2,
|
|
119
|
+
h3,
|
|
120
|
+
.modest-h3,
|
|
121
|
+
h4,
|
|
122
|
+
.modest-h4 {
|
|
123
|
+
margin: 1.414rem 0 .5rem;
|
|
124
|
+
font-weight: inherit;
|
|
125
|
+
line-height: 1.42;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
h1,
|
|
129
|
+
.modest-h1 {
|
|
130
|
+
margin-top: 0;
|
|
131
|
+
font-size: 3.998rem;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
h2,
|
|
135
|
+
.modest-h2 {
|
|
136
|
+
font-size: 2.827rem;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
h3,
|
|
140
|
+
.modest-h3 {
|
|
141
|
+
font-size: 1.999rem;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
h4,
|
|
145
|
+
.modest-h4 {
|
|
146
|
+
font-size: 1.414rem;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
h5,
|
|
150
|
+
.modest-h5 {
|
|
151
|
+
font-size: 1.121rem;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
h6,
|
|
155
|
+
.modest-h6 {
|
|
156
|
+
font-size: .88rem;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
small,
|
|
160
|
+
.modest-small {
|
|
161
|
+
font-size: .707em;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* https://github.com/mrmrs/fluidity */
|
|
165
|
+
|
|
166
|
+
img,
|
|
167
|
+
canvas,
|
|
168
|
+
iframe,
|
|
169
|
+
video,
|
|
170
|
+
svg,
|
|
171
|
+
select,
|
|
172
|
+
textarea {
|
|
173
|
+
max-width: 100%;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@import url(http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700);
|
|
177
|
+
|
|
178
|
+
@import url(http://fonts.googleapis.com/css?family=Arimo:700,700italic);
|
|
179
|
+
|
|
180
|
+
html {
|
|
181
|
+
font-size: 18px;
|
|
182
|
+
max-width: 100%;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
body {
|
|
186
|
+
color: #444;
|
|
187
|
+
font-family: 'Open Sans Condensed', sans-serif;
|
|
188
|
+
font-weight: 300;
|
|
189
|
+
margin: 0 auto;
|
|
190
|
+
max-width: 48rem;
|
|
191
|
+
line-height: 1.45;
|
|
192
|
+
padding: .25rem;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
h1,
|
|
196
|
+
h2,
|
|
197
|
+
h3,
|
|
198
|
+
h4,
|
|
199
|
+
h5,
|
|
200
|
+
h6 {
|
|
201
|
+
font-family: Arimo, Helvetica, sans-serif;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
h1,
|
|
205
|
+
h2,
|
|
206
|
+
h3 {
|
|
207
|
+
border-bottom: 2px solid #fafafa;
|
|
208
|
+
margin-bottom: 1.15rem;
|
|
209
|
+
padding-bottom: .5rem;
|
|
210
|
+
text-align: center;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
blockquote {
|
|
214
|
+
border-left: 8px solid #fafafa;
|
|
215
|
+
padding: 1rem;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
pre,
|
|
219
|
+
code {
|
|
220
|
+
background-color: #fafafa;
|
|
221
|
+
}
|
metadata
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dot_usage
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ben Eills
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-07-29 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.12'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.12'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: jekyll
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.1'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.1'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '10.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '10.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: minitest
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '5.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '5.0'
|
|
69
|
+
description:
|
|
70
|
+
email:
|
|
71
|
+
- ben@beneills.com
|
|
72
|
+
executables:
|
|
73
|
+
- dot_usage
|
|
74
|
+
extensions: []
|
|
75
|
+
extra_rdoc_files: []
|
|
76
|
+
files:
|
|
77
|
+
- ".gitignore"
|
|
78
|
+
- ".travis.yml"
|
|
79
|
+
- ".usage.yml"
|
|
80
|
+
- Gemfile
|
|
81
|
+
- README.md
|
|
82
|
+
- Rakefile
|
|
83
|
+
- _config.yml
|
|
84
|
+
- bin/console
|
|
85
|
+
- bin/generate_site
|
|
86
|
+
- bin/setup
|
|
87
|
+
- data/example.usage.yml
|
|
88
|
+
- dot_usage.gemspec
|
|
89
|
+
- exe/dot_usage
|
|
90
|
+
- index.md
|
|
91
|
+
- lib/dot_usage.rb
|
|
92
|
+
- lib/dot_usage/markdown.rb
|
|
93
|
+
- lib/dot_usage/version.rb
|
|
94
|
+
- site/css/modest.css
|
|
95
|
+
homepage: https://github.com/beneills/dot_usage
|
|
96
|
+
licenses:
|
|
97
|
+
- MIT
|
|
98
|
+
metadata: {}
|
|
99
|
+
post_install_message:
|
|
100
|
+
rdoc_options: []
|
|
101
|
+
require_paths:
|
|
102
|
+
- lib
|
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
|
+
requirements:
|
|
105
|
+
- - ">="
|
|
106
|
+
- !ruby/object:Gem::Version
|
|
107
|
+
version: '0'
|
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
|
+
requirements:
|
|
110
|
+
- - ">="
|
|
111
|
+
- !ruby/object:Gem::Version
|
|
112
|
+
version: '0'
|
|
113
|
+
requirements: []
|
|
114
|
+
rubyforge_project:
|
|
115
|
+
rubygems_version: 2.5.1
|
|
116
|
+
signing_key:
|
|
117
|
+
specification_version: 4
|
|
118
|
+
summary: File format and utility to control building, running and testing source code.
|
|
119
|
+
test_files: []
|