gliffy 0.0.9 → 0.0.10
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/README.md +63 -0
- data/bin/gliffy-cli +50 -0
- data/lib/gliffy/api.rb +3 -3
- data/lib/gliffy/api/facade.rb +7 -6
- data/lib/gliffy/cli.rb +6 -0
- data/lib/gliffy/cli/task.rb +59 -0
- data/lib/gliffy/cli/task/user.rb +2 -0
- data/lib/gliffy/cli/task/user/list.rb +11 -0
- data/spec/lib/gliffy/cli/task/user/list_spec.rb +67 -0
- data/spec/lib/gliffy/cli/task/user_spec.rb +4 -0
- data/spec/lib/gliffy/cli/task_spec.rb +134 -0
- data/spec/spec_helper.rb +1 -0
- metadata +41 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6949d3523318bb17a56dae26086d4d8035c8845
|
4
|
+
data.tar.gz: 5de50165043f8ca7e8dc97a03132463851be7572
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f10b34b25b22def22fcb9e5b994dc316e312e59605e06216aeb1e8bff552a2f4723feaae839ed43a42a4b1dfd50d7d133616dc5bf43c6b62f13c37bb278371f
|
7
|
+
data.tar.gz: ae784af337dde2e08a02f10e3cea1dd32cb847e3ae3f3edee2ad05b112c1994a53603fb3bba7c27e601d60cbfcfce984f8fffff2867c7f0c913e21888ed79d30
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@ Gliffy API wrapper
|
|
3
3
|
|
4
4
|
[](http://badge.fury.io/rb/gliffy)
|
5
5
|
[](https://codeclimate.com/github/bkon/gliffy)
|
6
|
+
[](https://bitdeli.com/free "Bitdeli Badge")
|
6
7
|
|
7
8
|
Basic usage
|
8
9
|
-----------
|
@@ -69,3 +70,65 @@ Basic usage
|
|
69
70
|
user.admin = true
|
70
71
|
|
71
72
|
user.accessible_folders
|
73
|
+
|
74
|
+
Command-line client
|
75
|
+
-------------------
|
76
|
+
|
77
|
+
### Authenticating yourself to gliffy API
|
78
|
+
|
79
|
+
CLI client looks for credentials in `~/.gliffy-cli` file by default. It is
|
80
|
+
a YAML file with a following simple structure:
|
81
|
+
|
82
|
+
gliffy:
|
83
|
+
account: <YOUR ACCOUNT ID>
|
84
|
+
oauth:
|
85
|
+
consumer_key: <YOUR OAUTH CONSUMER KEY>
|
86
|
+
consumer_secret: <YOUR OAUTH CONSUMER SECRET>
|
87
|
+
|
88
|
+
An alternative ways to specify API credentials are:
|
89
|
+
* use `--credentials` flag
|
90
|
+
```
|
91
|
+
gliffy-cli --credentials <PATH TO CREDENTIALS FILE> ...
|
92
|
+
```
|
93
|
+
* use `--account-id`, `--consumer-key` and `--consumer-secret` flags
|
94
|
+
```
|
95
|
+
gliffy-cli --account-id <ID> --consumer-key <KEY> --consumer-secret <SECRET> ...
|
96
|
+
```
|
97
|
+
|
98
|
+
The next step is to impersonate an user:
|
99
|
+
|
100
|
+
```
|
101
|
+
gliffy-cli ... --user <USERNAME> ...
|
102
|
+
```
|
103
|
+
|
104
|
+
Keep in mind that new users are provisioned automatically, so if
|
105
|
+
`<USERNAME>` does not exists, it will be created for you by Gliffy.
|
106
|
+
|
107
|
+
### List of available commands:
|
108
|
+
|
109
|
+
* `user add <USERNAME>`
|
110
|
+
* `user delete <USERNAME>`
|
111
|
+
* `user list`
|
112
|
+
* `user update email <USERNAME>`
|
113
|
+
* `user update password <USERNAME>`
|
114
|
+
* `user admin grant <USERNAME>`
|
115
|
+
* `user admin revoke <USERNAME>`
|
116
|
+
* `document add`
|
117
|
+
* `document content <ID>.<FORMAT>`
|
118
|
+
* `document name <ID>.<FORMAT>`
|
119
|
+
* `document delete <ID>`
|
120
|
+
* `document rename <ID> <NAME>`
|
121
|
+
* `document access public <ID>`
|
122
|
+
* `document access private <ID>`
|
123
|
+
* `folder documents <PATH>`
|
124
|
+
* `folder folders <PATH>`
|
125
|
+
* `folder users <PATH>`
|
126
|
+
* `folder access grant <PATH> <USERNAME>`
|
127
|
+
* `folder access revoke <PATH> <USERNAME>`
|
128
|
+
* `folder document create <PATH> <DOCUMENT>`
|
129
|
+
* `folder create <PATH>`
|
130
|
+
* `folder delete <PATH>`
|
131
|
+
|
132
|
+
### Misc functionality
|
133
|
+
|
134
|
+
* `--log-http` enables HTTP requests and response logging to STDERR
|
data/bin/gliffy-cli
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
#!ruby
|
2
|
+
|
3
|
+
require 'gliffy'
|
4
|
+
require 'gliffy/cli'
|
5
|
+
require 'gli'
|
6
|
+
require 'yaml'
|
7
|
+
require 'http_logger'
|
8
|
+
require 'logger'
|
9
|
+
require 'pp'
|
10
|
+
|
11
|
+
include GLI::App
|
12
|
+
|
13
|
+
program_desc "Gliffy API Client"
|
14
|
+
version "0.0.9"
|
15
|
+
|
16
|
+
subcommand_option_handling :normal
|
17
|
+
|
18
|
+
desc "Location of the credentials file (YAML)"
|
19
|
+
arg_name "FILENAME"
|
20
|
+
default_value File.join(Dir.home, ".gliffy-cli")
|
21
|
+
flag [:credentials]
|
22
|
+
|
23
|
+
desc "Account ID"
|
24
|
+
arg_name "ID"
|
25
|
+
flag ["account-id"]
|
26
|
+
|
27
|
+
desc "Gliffy API consumer key"
|
28
|
+
arg_name "KEY"
|
29
|
+
flag ["consumer-key"]
|
30
|
+
|
31
|
+
desc "Gliffy API consumer secret"
|
32
|
+
arg_name "SECRET"
|
33
|
+
flag ["consumer-secret"]
|
34
|
+
|
35
|
+
desc "User to impersonate"
|
36
|
+
arg_name "NAME"
|
37
|
+
flag [:user]
|
38
|
+
|
39
|
+
desc "Enable HTTP logging"
|
40
|
+
switch "log-http"
|
41
|
+
|
42
|
+
command :user do |c|
|
43
|
+
c.command :list do |sub|
|
44
|
+
sub.action do |global_options, options, args|
|
45
|
+
Gliffy::CLI::Task::User::List.new(global_options, options, args).run
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
exit run(ARGV)
|
data/lib/gliffy/api.rb
CHANGED
@@ -39,8 +39,8 @@ module Gliffy
|
|
39
39
|
|
40
40
|
def web(url, params)
|
41
41
|
consumer.create_signed_request(
|
42
|
-
:get,
|
43
|
-
url + '?' + query(params),
|
42
|
+
:get,
|
43
|
+
url + '?' + query(params),
|
44
44
|
token
|
45
45
|
).path
|
46
46
|
end
|
@@ -58,7 +58,7 @@ module Gliffy
|
|
58
58
|
:action => 'create',
|
59
59
|
:description => application_name
|
60
60
|
)
|
61
|
-
|
61
|
+
|
62
62
|
token.token = response.string('//g:oauth-token')
|
63
63
|
token.secret = response.string('//g:oauth-token-secret')
|
64
64
|
end
|
data/lib/gliffy/api/facade.rb
CHANGED
@@ -59,17 +59,18 @@ module Gliffy
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def grant_access_to_folder(username, path)
|
62
|
-
|
63
|
-
:action => "update",
|
64
|
-
:read => "true",
|
65
|
-
:write => "true")
|
62
|
+
update_access_to_folder(username, path, "true")
|
66
63
|
end
|
67
64
|
|
68
65
|
def revoke_access_to_folder(username, path)
|
66
|
+
update_access_to_folder(username, path, "false")
|
67
|
+
end
|
68
|
+
|
69
|
+
def update_access_to_folder(username, path, value)
|
69
70
|
post("/accounts/#{account_id}/folders/#{escape_path path}/users/#{username}.xml",
|
70
71
|
:action => "update",
|
71
|
-
:read =>
|
72
|
-
:write =>
|
72
|
+
:read => value,
|
73
|
+
:write => value)
|
73
74
|
end
|
74
75
|
|
75
76
|
def get_users(account_id)
|
data/lib/gliffy/cli.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'http_logger'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
module Gliffy
|
5
|
+
class CLI::Task
|
6
|
+
def initialize(options)
|
7
|
+
if options["log-http"]
|
8
|
+
enable_http_logging
|
9
|
+
end
|
10
|
+
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def enable_http_logging
|
15
|
+
HttpLogger.logger = Logger.new(STDERR)
|
16
|
+
HttpLogger.colorize = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def stdout
|
20
|
+
STDOUT
|
21
|
+
end
|
22
|
+
|
23
|
+
def account
|
24
|
+
@account ||= load_account(@options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_account(options)
|
28
|
+
account_id, consumer_key, consumer_secret = load_credentials(options)
|
29
|
+
api = Gliffy::API.new(account_id,
|
30
|
+
consumer_key,
|
31
|
+
consumer_secret)
|
32
|
+
|
33
|
+
api.impersonate(options["user"])
|
34
|
+
api.account
|
35
|
+
end
|
36
|
+
|
37
|
+
def load_credentials(options)
|
38
|
+
if has_custom_credentials? options
|
39
|
+
account_id = options["account-id"]
|
40
|
+
consumer_key = options["consumer-key"]
|
41
|
+
consumer_secret = options["consumer-secret"]
|
42
|
+
else
|
43
|
+
credentials = YAML.load_file(options["credentials"])
|
44
|
+
|
45
|
+
account_id = credentials["gliffy"]["account"]
|
46
|
+
consumer_key = credentials["gliffy"]["oauth"]["consumer_key"]
|
47
|
+
consumer_secret = credentials["gliffy"]["oauth"]["consumer_secret"]
|
48
|
+
end
|
49
|
+
|
50
|
+
[account_id, consumer_key, consumer_secret]
|
51
|
+
end
|
52
|
+
|
53
|
+
def has_custom_credentials?(options)
|
54
|
+
["account-id",
|
55
|
+
"consumer-key",
|
56
|
+
"consumer-secret"].all? { |k| not options[k].nil? }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gliffy::CLI::Task::User::List do
|
4
|
+
let(:user1) do
|
5
|
+
double(Gliffy::User,
|
6
|
+
:username => "username1",
|
7
|
+
:email => "email1@test.com")
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:user2) do
|
11
|
+
double(Gliffy::User,
|
12
|
+
:username => "username2",
|
13
|
+
:email => "email2@test.com")
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:account) do
|
17
|
+
double(Gliffy::Account)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:stdout) do
|
21
|
+
stdout = double(STDOUT)
|
22
|
+
stdout.stub(:puts)
|
23
|
+
stdout
|
24
|
+
end
|
25
|
+
|
26
|
+
subject do
|
27
|
+
Gliffy::CLI::Task::User::List
|
28
|
+
.any_instance
|
29
|
+
.stub(:account)
|
30
|
+
.and_return(account)
|
31
|
+
|
32
|
+
Gliffy::CLI::Task::User::List
|
33
|
+
.new({ "account-id" => "ID",
|
34
|
+
"consumer-key" => "KEY",
|
35
|
+
"consumer-secret" => "SECRET",
|
36
|
+
"user" => "USERNAME" },
|
37
|
+
{},
|
38
|
+
{})
|
39
|
+
end
|
40
|
+
|
41
|
+
before :each do
|
42
|
+
account.stub(:users).and_return([user1, user2])
|
43
|
+
subject.stub(:stdout).and_return(stdout)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "loads a list of users" do
|
47
|
+
subject.run
|
48
|
+
|
49
|
+
expect(account).to have_received :users
|
50
|
+
end
|
51
|
+
|
52
|
+
it "displays users" do
|
53
|
+
subject.run
|
54
|
+
|
55
|
+
expect(stdout).to have_received(:puts)
|
56
|
+
.with(match(user1.username))
|
57
|
+
|
58
|
+
expect(stdout).to have_received(:puts)
|
59
|
+
.with(match(user1.email))
|
60
|
+
|
61
|
+
expect(stdout).to have_received(:puts)
|
62
|
+
.with(match(user2.username))
|
63
|
+
|
64
|
+
expect(stdout).to have_received(:puts)
|
65
|
+
.with(match(user2.email))
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
describe Gliffy::CLI::Task do
|
5
|
+
let(:account) do
|
6
|
+
double(Gliffy::Account)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:api) do
|
10
|
+
api = double(Gliffy::API, :account => account)
|
11
|
+
api.stub(:impersonate)
|
12
|
+
api
|
13
|
+
end
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
Gliffy::API
|
17
|
+
.stub(:new)
|
18
|
+
.and_return(api)
|
19
|
+
|
20
|
+
Gliffy::CLI::Task.any_instance.stub(:load_account).and_call_original
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when initialized" do
|
24
|
+
let(:options) do
|
25
|
+
{ "log-http" => false }
|
26
|
+
end
|
27
|
+
|
28
|
+
subject {
|
29
|
+
Gliffy::CLI::Task.new(options)
|
30
|
+
}
|
31
|
+
|
32
|
+
it "loads account data" do
|
33
|
+
Gliffy::CLI::Task.any_instance.stub(:load_credentials)
|
34
|
+
.and_return("ID", "KEY", "SECRET")
|
35
|
+
|
36
|
+
subject.account
|
37
|
+
expect(subject).to have_received(:load_account).once
|
38
|
+
end
|
39
|
+
|
40
|
+
it "caches account data" do
|
41
|
+
Gliffy::CLI::Task.any_instance.stub(:load_credentials)
|
42
|
+
|
43
|
+
subject.account
|
44
|
+
subject.account
|
45
|
+
expect(subject).to have_received(:load_account).once
|
46
|
+
end
|
47
|
+
|
48
|
+
it "has a reference to the output stream" do
|
49
|
+
expect(subject).to respond_to :stdout
|
50
|
+
expect(subject.stdout).to be_instance_of IO
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when user provided custom credentials" do
|
54
|
+
let(:options) do
|
55
|
+
{
|
56
|
+
"account-id" => "ID",
|
57
|
+
"consumer-key" => "KEY",
|
58
|
+
"consumer-secret" => "SECRET"
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
it "knows it" do
|
63
|
+
expect(subject.has_custom_credentials?(options)).to be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
it "uses credentials from the command line" do
|
67
|
+
credentials = subject.load_credentials(options)
|
68
|
+
|
69
|
+
expect(credentials).to eq ["ID", "KEY", "SECRET"]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when user does not provide custom credentials" do
|
74
|
+
let(:credentials_file_name) { "test.yaml" }
|
75
|
+
let(:credentials_file_contents) do
|
76
|
+
%Q{
|
77
|
+
gliffy:
|
78
|
+
account: 222
|
79
|
+
oauth:
|
80
|
+
consumer_key: "KEY2"
|
81
|
+
consumer_secret: "SECRET2"
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
let(:options) do
|
86
|
+
{
|
87
|
+
"account-id" => nil,
|
88
|
+
"consumer-key" => nil,
|
89
|
+
"consumer-secret" => nil,
|
90
|
+
"credentials" => credentials_file_name
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
it "knows it" do
|
95
|
+
expect(subject.has_custom_credentials?(options)).to be_false
|
96
|
+
end
|
97
|
+
|
98
|
+
it "loads credentials from the credentials file" do
|
99
|
+
YAML.stub(:load_file).and_return(YAML.load(credentials_file_contents))
|
100
|
+
|
101
|
+
credentials = subject.load_credentials(options)
|
102
|
+
|
103
|
+
expect(credentials).to eq [222, "KEY2", "SECRET2"]
|
104
|
+
expect(YAML).to have_received(:load_file).with(credentials_file_name)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "during the initialization" do
|
110
|
+
context "when log-http switch is on" do
|
111
|
+
let(:options) do
|
112
|
+
{ "log-http" => true }
|
113
|
+
end
|
114
|
+
|
115
|
+
it "enables HTTP logging" do
|
116
|
+
HttpLogger.stub(:logger=)
|
117
|
+
subject = Gliffy::CLI::Task.new(options)
|
118
|
+
expect(HttpLogger).to have_received :logger=
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "when log-http switch is off" do
|
123
|
+
let(:options) do
|
124
|
+
{ "log-http" => false }
|
125
|
+
end
|
126
|
+
|
127
|
+
it "does not enable HTTP logging" do
|
128
|
+
HttpLogger.stub(:logger=)
|
129
|
+
subject = Gliffy::CLI::Task.new(options)
|
130
|
+
expect(HttpLogger).to_not have_received :logger=
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gliffy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Burnaev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oauth
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: gli
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,12 +150,28 @@ dependencies:
|
|
136
150
|
- - '>='
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rake
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
139
167
|
description: A simple Gliffy REST API wrapper.
|
140
168
|
email: kbourn@gmail.com
|
141
|
-
executables:
|
169
|
+
executables:
|
170
|
+
- gliffy-cli
|
142
171
|
extensions: []
|
143
172
|
extra_rdoc_files: []
|
144
173
|
files:
|
174
|
+
- lib/gliffy/cli.rb
|
145
175
|
- lib/gliffy/folder.rb
|
146
176
|
- lib/gliffy/document/presentation.rb
|
147
177
|
- lib/gliffy/document/presentation/png.rb
|
@@ -153,6 +183,9 @@ files:
|
|
153
183
|
- lib/gliffy/account.rb
|
154
184
|
- lib/gliffy/api.rb
|
155
185
|
- lib/gliffy/user.rb
|
186
|
+
- lib/gliffy/cli/task.rb
|
187
|
+
- lib/gliffy/cli/task/user/list.rb
|
188
|
+
- lib/gliffy/cli/task/user.rb
|
156
189
|
- lib/gliffy/document.rb
|
157
190
|
- lib/gliffy/oauth/helper.rb
|
158
191
|
- lib/gliffy.rb
|
@@ -177,12 +210,16 @@ files:
|
|
177
210
|
- spec/lib/gliffy/api/response_spec.rb
|
178
211
|
- spec/lib/gliffy/api/facade_spec.rb
|
179
212
|
- spec/lib/gliffy/api/error_spec.rb
|
213
|
+
- spec/lib/gliffy/cli/task_spec.rb
|
214
|
+
- spec/lib/gliffy/cli/task/user_spec.rb
|
215
|
+
- spec/lib/gliffy/cli/task/user/list_spec.rb
|
180
216
|
- spec/lib/gliffy/document_spec.rb
|
181
217
|
- spec/lib/gliffy/account_spec.rb
|
182
218
|
- spec/lib/gliffy/folder_spec.rb
|
183
219
|
- spec/lib/gliffy_spec.rb
|
184
220
|
- README.md
|
185
221
|
- LICENSE
|
222
|
+
- bin/gliffy-cli
|
186
223
|
homepage: https://github.com/bkon/gliffy
|
187
224
|
licenses:
|
188
225
|
- MIT
|
@@ -208,3 +245,4 @@ signing_key:
|
|
208
245
|
specification_version: 4
|
209
246
|
summary: Gliffy API client
|
210
247
|
test_files: []
|
248
|
+
has_rdoc:
|