Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show Contents of Readme on Crate Pages #869

Merged
merged 39 commits into from
Aug 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
6fa43f7
Add server-side rendering of the crate's READMEs
kureuil Jul 8, 2017
b15403b
Add readme_path to EncodableVersion & create associated route
kureuil Jul 9, 2017
ed9e413
Display README content on crate page if it's available
kureuil Jul 9, 2017
c938b0f
Don't upload rendered README to S3 if crate has no README file
kureuil Jul 9, 2017
501cef8
Fix ESLint complains & add proper error handling if no readme
kureuil Jul 9, 2017
827ff65
Sanitize rendered html with ammonia
kureuil Jul 9, 2017
59e92ad
Styling issues
kureuil Jul 9, 2017
14e6b3e
Minimal documentation
kureuil Jul 9, 2017
61f6431
Test readme upload
kureuil Jul 9, 2017
e56b118
Add tests for the new render module
kureuil Jul 10, 2017
ad88f8a
Extracted file upload into its own method
kureuil Jul 14, 2017
756505e
Add a render-readmes script
kureuil Jul 14, 2017
425439e
Remove needless borrow
kureuil Jul 14, 2017
8e27297
Add syntax highlighting to markdown rendering
kureuil Jul 15, 2017
40b1d0d
Remove syntax highlighting from the render module
kureuil Jul 26, 2017
08f62a7
Factor out config initialization into a Default implementation
kureuil Jul 26, 2017
738be0a
Documentation comments in the uploaders and render modules
kureuil Jul 26, 2017
27c6c42
Move render unit tests out of the integration tests module
kureuil Jul 26, 2017
27ddfd5
Replace unwrap_or by unwrap_or_default
kureuil Jul 26, 2017
88990e7
Remove leading slash in the path of the uploaded file
kureuil Jul 27, 2017
82e4a13
Tests formatting
kureuil Jul 27, 2017
06b2b41
Syntax highlighting is now done client-side
kureuil Jul 30, 2017
143f987
Replace pattern matcing by expect in find_file_by_path
kureuil Jul 30, 2017
c53325f
Merge remote-tracking branch 'upstream/master' into 81-show-crate-readme
carols10cents Aug 5, 2017
0675378
Allow a missing debug; the Ammonia type doesn't implement debug
carols10cents Aug 5, 2017
5e0968a
Commit package-lock.json changes
carols10cents Aug 9, 2017
c72d11b
Switch to sudo: required to get more memory
carols10cents Aug 10, 2017
b73fab6
Merge remote-tracking branch 'upstream/master' into 81-show-crate-readme
carols10cents Aug 13, 2017
65c0bd6
Include the s3 URL as a whitelisted value in the CSP headers
carols10cents Aug 13, 2017
24da2e2
Oops this really is only the host and doesn't include the protocol
carols10cents Aug 13, 2017
6babc00
cargo fmt
carols10cents Aug 13, 2017
8c4c433
Try new layout for crate version page
kureuil Aug 14, 2017
746e0cf
Merge branch '81-show-crate-readme' of github.com:kureuil/crates.io i…
kureuil Aug 14, 2017
578c5bf
Have uploader take a curl::Easy handle instead of an App
carols10cents Aug 16, 2017
b0f014d
Get a diesel connection from connect_now instead of app
carols10cents Aug 16, 2017
f25fbd6
Get uploader from config instead of app
carols10cents Aug 16, 2017
79ba3ae
cargo fmt
carols10cents Aug 17, 2017
21b3767
Merge remote-tracking branch 'upstream/master' into 81-show-crate-readme
carols10cents Aug 17, 2017
e28e48f
No more postgres crate
carols10cents Aug 17, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
256 changes: 235 additions & 21 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ git2 = "0.6.4"
flate2 = "0.2"
semver = "0.5"
url = "1.2.1"
tar = "0.4.13"

r2d2 = "0.7.0"
openssl = "0.9.9"
Expand All @@ -47,6 +48,8 @@ serde_derive = "1.0.0"
serde = "1.0.0"
clippy = { version = "=0.0.142", optional = true }
chrono = "0.4.0"
pulldown-cmark = { version = "0.0.15", default-features = false }
ammonia = "0.5.0"

conduit = "0.8"
conduit-conditional-get = "0.8"
Expand Down
11 changes: 11 additions & 0 deletions app/components/crate-readme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Ember from 'ember';

export default Ember.Component.extend({
rendered: '',
didRender() {
this._super(...arguments);
this.$('pre > code').each(function() {
window.Prism.highlightElement(this);
});
}
});
1 change: 1 addition & 0 deletions app/models/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import DS from 'ember-data';
export default DS.Model.extend({
num: DS.attr('string'),
dl_path: DS.attr('string'),
readme_path: DS.attr('string'),
created_at: DS.attr('date'),
updated_at: DS.attr('date'),
downloads: DS.attr('number'),
Expand Down
21 changes: 20 additions & 1 deletion app/routes/crate/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,28 @@ export default Route.extend({
`Version '${params.version_num}' of crate '${crate.get('name')}' does not exist`);
}

return version ||
const result = version ||
versions.find(version => version.get('num') === maxVersion) ||
versions.objectAt(0);
if (result.get('readme_path')) {
this.get('ajax').request(result.get('readme_path'))
.then((r) => this.get('ajax').raw(r.url, {
method: 'GET',
dataType: 'html',
headers: {
// We need to force the Accept header, otherwise crates.io won't return
// the readme file when not using S3.
Accept: '*/*',
},
}))
.then((r) => {
crate.set('readme', r.payload);
})
.catch(() => {
crate.set('readme', null);
});
}
return result;
});
},

Expand Down
8 changes: 8 additions & 0 deletions app/styles/crate.scss
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@
.docs {
@include flex(7);
padding-right: 40px;
max-width: 600px;
}
.authorship {
@include flex(3);
Expand Down Expand Up @@ -302,6 +303,13 @@
color: red;
}
}
.crate-readme {
line-height: 1.5;

pre {
overflow-x: scroll;
}
}
.last-update {
color: $main-color-light;
font-size: 90%;
Expand Down
1 change: 1 addition & 0 deletions app/templates/components/crate-readme.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{{rendered}}}
158 changes: 69 additions & 89 deletions app/templates/crate/version.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,28 @@
<div class="quick-links">
<ul>
{{#if crate.homepage}}
<li><a href="{{crate.homepage}}">Homepage</a></li>
<li><a href="{{crate.homepage}}">Homepage</a></li>
{{/if}}
{{#if crate.wiki}}
<li><a href="{{crate.wiki}}">Wiki</a></li>
{{/if}}
{{#if crate.mailing_list}}
<li><a href="{{crate.mailing_list}}">Mailing list</a></li>
{{/if}}
{{#if crate.documentation}}
<li><a href="{{crate.documentation}}">Documentation</a></li>
<li><a href="{{crate.documentation}}">Documentation</a></li>
{{/if}}
{{#if crate.repository}}
<li><a href="{{crate.repository}}">Repository</a></li>
<li><a href="{{crate.repository}}">Repository</a></li>
{{/if}}
{{#if crate.reverse_dependencies}}
<li>
{{#link-to 'crate.reverse_dependencies' (query-params dependency=crate.crate_id)}}
Dependent crates
{{/link-to}}
</li>
{{else}}
<li>No dependent crates</li>
{{/if}}
</ul>
</div>
Expand All @@ -54,12 +69,6 @@
{{else}}
<div class='crate-info'>
<div class='docs'>
{{#if crate.description}}
<div class='about'>
<h3>About This Package</h3>
<p>{{ crate.description }}</p>
</div>
{{/if}}
<div class='install'>
<div class='action'>Cargo.toml</div>
<code id="crate-toml">{{ crate.name }} = "{{ currentVersion.num }}"</code>
Expand All @@ -82,6 +91,11 @@
{{/if}}
</span>
</div>
{{#if crate.readme}}
<div class="crate-readme">
{{crate-readme rendered=crate.readme}}
</div>
{{/if}}
</div>
<div class='authorship'>
<div class='top'>
Expand Down Expand Up @@ -166,88 +180,54 @@
{{/each}}
</ul>
</div>
</div>
</div>
</div>

<div id='crate-links'>
{{#if anyLinks}}
<div class='section'>
<h3>Links</h3>
<ul>
{{#if crate.homepage}}
<li><a href="{{crate.homepage}}">Homepage</a></li>
{{/if}}
{{#if crate.wiki}}
<li><a href="{{crate.wiki}}">Wiki</a></li>
{{/if}}
{{#if crate.mailing_list}}
<li><a href="{{crate.mailing_list}}">Mailing list</a></li>
{{/if}}
{{#if crate.documentation}}
<li><a href="{{crate.documentation}}">Documentation</a></li>
{{/if}}
{{#if crate.repository}}
<li><a href="{{crate.repository}}">Repository</a></li>
{{/if}}
{{#if crate.reverse_dependencies}}
<li>
{{#link-to 'crate.reverse_dependencies' (query-params dependency=crate.crate_id)}}
Dependent crates
{{/link-to}}
</li>
{{else}}
<li>No dependent crates</li>
{{/if}}
</ul>
</div>
{{/if}}
<div class='section' id='crate-versions'>
<h3>Versions</h3>
<ul>
{{#each smallSortedVersions as |version|}}
<li>
{{#link-to 'crate.version' version.num}}
{{ version.num }}
{{/link-to}}
<span class='date'>{{moment-format version.created_at 'll'}}</span>
{{#if version.yanked}}
<span class='yanked'>yanked</span>
{{/if}}
</li>
{{/each}}
</ul>
<span class='small'>
{{#if hasMoreVersions}}
{{#link-to 'crate.versions' crate}}
show all {{ crate.versions.length }} versions
{{/link-to}}
{{/if}}
</span>
</div>

<div class='section' id='crate-dependencies'>
<h3>Dependencies</h3>
<ul>
{{#each currentDependencies as |dep|}}
{{link-to-dep dep=dep}}
{{else}}
<li>None</li>
{{/each}}
</ul>
</div>
<div class='section' id='crate-dependencies'>
<h3>Dependencies</h3>
<ul>
{{#each currentDependencies as |dep|}}
{{link-to-dep dep=dep}}
{{else}}
<li>None</li>
{{/each}}
</ul>
</div>

{{#if currentDevDependencies}}
<div class='section' id='crate-dev-dependencies'>
<h3>Dev-Dependencies</h3>
<ul>
{{#each currentDevDependencies as |dep|}}
{{link-to-dep dep=dep}}
{{/each}}
</ul>
{{#if currentDevDependencies}}
<div class='section' id='crate-dev-dependencies'>
<h3>Dev-Dependencies</h3>
<ul>
{{#each currentDevDependencies as |dep|}}
{{link-to-dep dep=dep}}
{{/each}}
</ul>
</div>
{{/if}}
</div>
</div>
{{/if}}

<div class='section' id='crate-versions'>
<h3>Versions</h3>
<ul>
{{#each smallSortedVersions as |version|}}
<li>
{{#link-to 'crate.version' version.num}}
{{ version.num }}
{{/link-to}}
<span class='date'>{{moment-format version.created_at 'll'}}</span>
{{#if version.yanked}}
<span class='yanked'>yanked</span>
{{/if}}
</li>
{{/each}}
</ul>
<span class='small'>
{{#if hasMoreVersions}}
{{#link-to 'crate.versions' crate}}
show all {{ crate.versions.length }} versions
{{/link-to}}
{{/if}}
</span>
</div>
</div>

<div id='crate-downloads'>
Expand All @@ -256,14 +236,14 @@
<div class='stat'>
<span class='num'>
{{svg-jar "download"}}
{{ format-num downloadsContext.downloads }}
{{format-num downloadsContext.downloads}}
</span>
<span class='desc small'>Downloads all time</span>
</div>
<div class='stat'>
<span class="{{if crate.versions.isPending 'loading'}} num">
{{svg-jar "crate"}}
{{ crate.versions.length }}
{{crate.versions.length}}
</span>
<span class='desc small'>Versions published</span>
</div>
Expand Down
21 changes: 21 additions & 0 deletions ember-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,31 @@
const EmberApp = require('ember-cli/lib/broccoli/ember-app');

module.exports = function(defaults) {
const highlightedLanguages = [
'bash',
'clike',
'glsl',
'go',
'ini',
'javascript',
'json',
'markup',
'protobuf',
'ruby',
'rust',
'scss',
'sql',
'yaml'
];

let app = new EmberApp(defaults, {
babel6: {
plugins: ['transform-object-rest-spread'],
},
'ember-prism': {
theme: 'twilight',
components: highlightedLanguages,
}
});

// Use `app.import` to add additional libraries to the generated
Expand Down
Loading