Skip to content

Commit f8a64c4

Browse files
committed
Merge remote-tracking branch 'upstream/master' into bump-dep-versions
2 parents 39b201d + 79af685 commit f8a64c4

File tree

29 files changed

+401
-53
lines changed

29 files changed

+401
-53
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ matrix:
3939
allow_failures:
4040
- rust: nightly
4141
include:
42-
- rust: nightly-2017-09-20
42+
- rust: nightly-2017-11-07
4343
env: RUSTFMT=YESPLEASE
4444
script:
45-
- cargo install --force rustfmt-nightly --vers 0.2.7
45+
- cargo install --force rustfmt-nightly --vers 0.2.15
4646
- export LD_LIBRARY_PATH=$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH
4747
- rustfmt --version
4848
- cargo fmt -- --write-mode=diff
@@ -51,7 +51,7 @@ matrix:
5151
- cargo build
5252
- cargo test
5353
- npm test
54-
- rust: nightly-2017-09-20
54+
- rust: nightly-2017-11-07
5555
env: CLIPPY=YESPLEASE
5656
script:
5757
- cargo check --features "lint"

Cargo.lock

Lines changed: 14 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ diesel_full_text_search = "0.16.0"
5353
serde_json = "1.0.0"
5454
serde_derive = "1.0.0"
5555
serde = "1.0.0"
56-
clippy = { version = "=0.0.162", optional = true }
56+
clippy = { version = "=0.0.169", optional = true }
5757
chrono = { version = "0.4.0", features = ["serde"] }
5858
comrak = { version = "0.2.3", default-features = false }
5959
ammonia = "1.0.0-rc3"

app/adapters/crate.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,31 @@ export default ApplicationAdapter.extend({
55
return this.ajax(this.urlForFollowAction(id), 'PUT');
66
},
77

8+
inviteOwner(id, username) {
9+
return this.ajax(this.urlForOwnerAction(id), 'PUT', {
10+
data: {
11+
owners: [username],
12+
}
13+
});
14+
},
15+
16+
removeOwner(id, username) {
17+
return this.ajax(this.urlForOwnerAction(id), 'DELETE', {
18+
data: {
19+
owners: [username],
20+
}
21+
});
22+
},
23+
824
unfollow(id) {
925
return this.ajax(this.urlForFollowAction(id), 'DELETE');
1026
},
1127

1228
urlForFollowAction(id) {
1329
return `${this.buildURL('crate', id)}/follow`;
1430
},
31+
32+
urlForOwnerAction(id) {
33+
return `${this.buildURL('crate', id)}/owners`;
34+
}
1535
});

app/controllers/crate/owners.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import Controller, { inject as controller } from '@ember/controller';
2+
import { computed } from '@ember/object';
3+
4+
export default Controller.extend({
5+
crateController: controller('crate'),
6+
crate: computed.alias('crateController.model'),
7+
error: false,
8+
invited: false,
9+
removed: false,
10+
username: '',
11+
12+
actions: {
13+
addOwner() {
14+
this.set('error', false);
15+
this.set('invited', false);
16+
17+
const username = this.get('username');
18+
19+
if (!username) {
20+
this.set('error', 'Please enter a username');
21+
return false;
22+
}
23+
24+
return this.get('crate').inviteOwner(username).then(() => {
25+
this.set('invited', `An invite has been sent to ${username}`);
26+
}).catch((error) => {
27+
if (error.payload) {
28+
this.set('error',
29+
`Error sending invite: ${error.payload.errors[0].detail}`
30+
);
31+
} else {
32+
this.set('error', 'Error sending invite');
33+
}
34+
});
35+
},
36+
37+
removeOwner(user) {
38+
this.set('removed', false);
39+
40+
return this.get('crate').removeOwner(user.get('login')).then(() => {
41+
this.set('removed', `User ${user.get('login')} removed as crate owner`);
42+
43+
this.get('crate.owner_user').removeObject(user);
44+
}).catch((error) => {
45+
if (error.payload) {
46+
this.set('removed',
47+
`Error removing owner: ${error.payload.errors[0].detail}`
48+
);
49+
} else {
50+
this.set('removed', 'Error removing owner');
51+
}
52+
});
53+
}
54+
}
55+
});

app/controllers/crate/version.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ export default Controller.extend({
2626
keywords: computed.alias('crate.keywords'),
2727
categories: computed.alias('crate.categories'),
2828
badges: computed.alias('crate.badges'),
29+
isOwner: computed('crate.owner_user', function() {
30+
return this.get('crate.owner_user').findBy('login', this.session.get('currentUser.login'));
31+
}),
2932

3033
sortedVersions: computed.readOnly('crate.versions'),
3134

app/models/crate.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ export default DS.Model.extend({
3838
return this.store.adapterFor('crate').follow(this.get('id'));
3939
},
4040

41+
inviteOwner(username) {
42+
return this.store.adapterFor('crate').inviteOwner(this.get('id'), username);
43+
},
44+
45+
removeOwner(username) {
46+
return this.store.adapterFor('crate').removeOwner(this.get('id'), username);
47+
},
48+
4149
unfollow() {
4250
return this.store.adapterFor('crate').unfollow(this.get('id'));
4351
},

app/router.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Router.map(function() {
2121

2222
this.route('reverse_dependencies');
2323

24+
this.route('owners');
25+
2426
// Well-known routes
2527
this.route('docs');
2628
this.route('repo');

app/templates/components/api-token-row.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
<div class='row new-token'>
6666
<div>
6767
Please record this token somewhere, you cannot retrieve
68-
its value again. For use on the command line you can save it to <code>~/.cargo/config</code>
68+
its value again. For use on the command line you can save it to <code>~/.cargo/credentials</code>
6969
with:
7070

7171
<pre>cargo login {{ api_token.token }}</pre>

app/templates/crate/owners.hbs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{{ title 'Manage Crate Owners' }}
2+
3+
<div id='crates-heading'>
4+
{{svg-jar "gear"}}
5+
<h1>Manage Crate Owners</h1>
6+
<h2>{{ crate.name }}</h2>
7+
</div>
8+
9+
<div id="me-email">
10+
<h2>Add Owner</h2>
11+
12+
<div class="row">
13+
<div class="label">
14+
<dt>Username</dt>
15+
</div>
16+
17+
<form class="email-form" {{action 'addOwner' on='submit'}}>
18+
{{input type='text' value=username placeholder='Username' class='form-control space-right' name='username'}}
19+
20+
{{#if error}}
21+
<div class='error'>
22+
<p class='small-text error'>{{error}}</p>
23+
</div>
24+
{{/if}}
25+
26+
{{#if invited}}
27+
<div class='invited'>
28+
<p>{{invited}}</p>
29+
</div>
30+
{{/if}}
31+
32+
<div class="actions">
33+
<button id="add-owner" type="submit" class="small yellow-button space-right">Save</button>
34+
</div>
35+
</form>
36+
</div>
37+
</div>
38+
39+
<h2>Owners</h2>
40+
41+
{{#if removed}}
42+
<div class='removed'>
43+
<p>{{removed}}</p>
44+
</div>
45+
{{/if}}
46+
47+
<div class='owners white-rows'>
48+
{{#each crate.owner_user as |user|}}
49+
<div class='crate row'>
50+
<div>
51+
{{#link-to user.kind user.login}}
52+
{{user-avatar user=user size='medium-small'}}
53+
{{/link-to}}
54+
</div>
55+
<div>
56+
{{#link-to user.kind user.login}}
57+
{{ user.name }}
58+
{{/link-to}}
59+
</div>
60+
<div class='stats'>
61+
{{{ if user.email user.email "&nbsp;" }}}
62+
</div>
63+
<div class='stats downloads'>
64+
<button class='remove-owner small yellow-button' {{action 'removeOwner' user}}>Remove</button>
65+
</div>
66+
</div>
67+
{{/each}}
68+
</div>

app/templates/crate/version.hbs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,17 @@
167167
{{/if}}
168168
{{/unless}}
169169

170-
<div>
170+
<div id='crate-owners'>
171171
<h3>Owners</h3>
172+
173+
{{#if isOwner}}
174+
<p>
175+
{{#link-to 'crate.owners' crate}}
176+
Manage owners
177+
{{/link-to}}
178+
</p>
179+
{{/if}}
180+
172181
<ul class='owners' data-test-owners>
173182
{{#each crate.owner_team as |team|}}
174183
<li>

mirage/config.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,44 @@ export default function() {
206206
let user = schema.users.findBy({ login });
207207
return user ? user : notFound();
208208
});
209+
210+
this.put('/crates/:crate_id/owners', (schema, request) => {
211+
const crateId = request.params.crate_id;
212+
const crate = schema.crates.find(crateId);
213+
214+
if (!crate) {
215+
return notFound();
216+
}
217+
218+
const body = JSON.parse(request.requestBody);
219+
const [ownerId] = body.owners;
220+
const user = schema.users.findBy({ login: ownerId });
221+
222+
if (!user) {
223+
return notFound();
224+
}
225+
226+
return { ok: true };
227+
});
228+
229+
this.delete('/crates/:crate_id/owners', (schema, request) => {
230+
const crateId = request.params.crate_id;
231+
const crate = schema.crates.find(crateId);
232+
233+
if (!crate) {
234+
return notFound();
235+
}
236+
237+
const body = JSON.parse(request.requestBody);
238+
const [ownerId] = body.owners;
239+
const user = schema.users.findBy({ login: ownerId });
240+
241+
if (!user) {
242+
return notFound();
243+
}
244+
245+
return {};
246+
});
209247
}
210248

211249
function notFound() {

mirage/fixtures/users.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,11 @@ export default [{
1313
"login": "thehydroimpulse",
1414
"name": "Daniel Fagnan",
1515
"url": "https://github.com/thehydroimpulse"
16+
}, {
17+
"avatar": "https://avatars3.githubusercontent.com/u/1179195?v=3",
18+
"email": "[email protected]",
19+
"id": 10982,
20+
"login": "iain8",
21+
"name": "Iain Buchanan",
22+
"url": "https://github.com/iain8"
1623
}];

src/badge.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ impl Badge {
107107
delete(badges::table)
108108
.filter(badges::crate_id.eq(krate.id))
109109
.execute(conn)?;
110-
insert_into(badges::table).values(&new_badges).execute(conn)?;
110+
insert_into(badges::table)
111+
.values(&new_badges)
112+
.execute(conn)?;
111113
Ok(invalid_badges)
112114
})
113115
}

0 commit comments

Comments
 (0)