fief 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3543ddd3cd50e0eaee854ded81482f5055a33b802cab4e27698cfc93b7e9d7a4
4
+ data.tar.gz: 20b02a86929d62c77e177c3b1d7f495adc07a1d3463d80bf4361c0f379a64638
5
+ SHA512:
6
+ metadata.gz: d770b689daff2ed3ef9efa70789cdf2503a2f0c8b0ed82620782ce05b6e270676dd47b8f7a551ad5378a500e33ca385754e40a64ef096261727b58ee792c2650
7
+ data.tar.gz: f2a36f91fa8c01df22501c51ee2b49dffa88450da44f998c23965a5589b65852dc914f1c8a6e4d2dfdcc4ecc051999e82732bd3848bd342ba77af2910d0e8b01
data/.0pdd.yml ADDED
@@ -0,0 +1,9 @@
1
+ errors:
2
+ - yegor256@gmail.com
3
+ # alerts:
4
+ # github:
5
+ # - yegor256
6
+
7
+ tags:
8
+ - pdd
9
+ - bug
data/.gitattributes ADDED
@@ -0,0 +1,7 @@
1
+ # Check out all text files in UNIX format, with LF as end of line
2
+ # Don't change this file. If you have any ideas about it, please
3
+ # submit a separate issue about it and we'll discuss.
4
+
5
+ * text=auto eol=lf
6
+ *.java ident
7
+ *.xml ident
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: cron
3
+ on:
4
+ schedule:
5
+ - cron: "23 23 * * *"
6
+ push:
7
+ branches:
8
+ - master
9
+ concurrency:
10
+ group: cron
11
+ cancel-in-progress: true
12
+ jobs:
13
+ cron:
14
+ runs-on: ubuntu-20.04
15
+ steps:
16
+ - uses: actions/checkout@v3
17
+ - uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.7
20
+ - run: bundle install
21
+ - run: |
22
+ bin/fief --verbose --token ${{ secrets.TOKEN }} --to gh-pages \
23
+ --include jcabi/* \
24
+ --include yegor256/cactoos \
25
+ --include yegor256/takes \
26
+ --include yegor256/xembly
27
+ - run: mkdir -p gh-pages/$(date +'%Y/%m/%d')
28
+ - run: cp gh-pages/index.xml gh-pages/$(date +'%Y/%m/%d')/index.xml
29
+ - uses: JamesIves/github-pages-deploy-action@4.1.4
30
+ with:
31
+ branch: gh-pages
32
+ folder: gh-pages
33
+ clean: false
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: pdd
3
+ on:
4
+ push:
5
+ pull_request:
6
+ jobs:
7
+ pdd:
8
+ runs-on: ubuntu-20.04
9
+ steps:
10
+ - uses: actions/checkout@v3
11
+ - uses: g4s8/pdd-action@master
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: rake
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ branches:
9
+ - master
10
+ jobs:
11
+ test:
12
+ strategy:
13
+ matrix:
14
+ os: [ubuntu-20.04, macos-12]
15
+ ruby: ['2.7', '3.0']
16
+ runs-on: ${{ matrix.os }}
17
+ steps:
18
+ - uses: actions/checkout@v3
19
+ - uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby }}
22
+ - run: bundle update
23
+ - run: bundle exec rake
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: xcop
3
+ on:
4
+ push:
5
+ pull_request:
6
+ jobs:
7
+ xcop:
8
+ runs-on: ubuntu-20.04
9
+ steps:
10
+ - uses: actions/checkout@v3
11
+ - uses: g4s8/xcop-action@master
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ coverage/
2
+ Gemfile.lock
3
+ .idea/
4
+ *.gem
5
+ .bundle/
6
+ .DS_Store
7
+ rdoc/
8
+ /fief/
data/.pdd ADDED
@@ -0,0 +1,7 @@
1
+ --source=.
2
+ --verbose
3
+ --exclude target/**/*
4
+ --exclude coverage/**/*
5
+ --rule min-words:20
6
+ --rule min-estimate:15
7
+ --rule max-estimate:90
data/.rubocop.yml ADDED
@@ -0,0 +1,23 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'bin/**/*'
4
+ - 'assets/**/*'
5
+ DisplayCopNames: true
6
+ TargetRubyVersion: 2.2
7
+ NewCops: enable
8
+ SuggestExtensions: false
9
+
10
+ Metrics/CyclomaticComplexity:
11
+ Max: 10
12
+ Metrics/MethodLength:
13
+ Enabled: false
14
+ Layout/MultilineMethodCallIndentation:
15
+ Enabled: false
16
+ Metrics/AbcSize:
17
+ Enabled: false
18
+ Metrics/PerceivedComplexity:
19
+ Max: 15
20
+ Layout/EmptyLineAfterGuardClause:
21
+ Enabled: false
22
+ Style/ClassAndModuleChildren:
23
+ Enabled: false
data/.rultor.yml ADDED
@@ -0,0 +1,20 @@
1
+ docker:
2
+ image: yegor256/rultor-image:1.20.0
3
+ assets:
4
+ rubygems.yml: yegor256/home#assets/rubygems.yml
5
+ install: |
6
+ pdd -f /dev/null
7
+ sudo bundle install --no-color "--gemfile=$(pwd)/Gemfile"
8
+ release:
9
+ script: |-
10
+ bundle exec rake
11
+ rm -rf *.gem
12
+ sed -i "s/0\.0\.0/${tag}/g" lib/fief/version.rb
13
+ git add lib/fief/version.rb
14
+ git commit -m "version set to ${tag}"
15
+ gem build fief.gemspec
16
+ chmod 0600 ../rubygems.yml
17
+ gem push *.gem --config-file ../rubygems.yml
18
+ merge:
19
+ script: |-
20
+ bundle exec rake
data/.simplecov ADDED
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2023 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ if Gem.win_platform?
22
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
23
+ SimpleCov::Formatter::HTMLFormatter
24
+ ]
25
+ SimpleCov.start do
26
+ add_filter '/test/'
27
+ add_filter '/features/'
28
+ end
29
+ else
30
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
31
+ [SimpleCov::Formatter::HTMLFormatter]
32
+ )
33
+ SimpleCov.start do
34
+ add_filter '/test/'
35
+ add_filter '/features/'
36
+ minimum_coverage 20
37
+ end
38
+ end
data/Gemfile ADDED
@@ -0,0 +1,31 @@
1
+ # Copyright (c) 2023 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ source 'https://rubygems.org'
22
+ gemspec
23
+
24
+ gem 'cucumber', '8.0.0', require: false
25
+ gem 'minitest', '5.15.0', require: false
26
+ gem 'rake', '13.0.6', require: false
27
+ gem 'rdoc', '6.4.0', require: false
28
+ gem 'rubocop', '1.32.0', require: false
29
+ gem 'rubocop-rspec', '2.11.1', require: false
30
+ gem 'simplecov', '0.22.0', require: false
31
+ gem 'xcop', '0.7.1', require: false
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2023 Yegor Bugayenko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the 'Software'), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ <img alt="fief logo" src="/logo.svg" width="64px"/>
2
+
3
+ [![EO principles respected here](https://www.elegantobjects.org/badge.svg)](https://www.elegantobjects.org)
4
+ [![DevOps By Rultor.com](http://www.rultor.com/b/yegor256/fief)](http://www.rultor.com/p/yegor256/fief)
5
+ [![We recommend RubyMine](https://www.elegantobjects.org/rubymine.svg)](https://www.jetbrains.com/ruby/)
6
+
7
+ [![rake](https://github.com/yegor256/fief/actions/workflows/rake.yml/badge.svg)](https://github.com/yegor256/fief/actions/workflows/rake.yml)
8
+ [![PDD status](http://www.0pdd.com/svg?name=yegor256/fief)](http://www.0pdd.com/p?name=yegor256/fief)
9
+ [![Gem Version](https://badge.fury.io/rb/fief.svg)](http://badge.fury.io/rb/fief)
10
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/yegor256/fief/blob/master/LICENSE.txt)
11
+ [![Maintainability](https://api.codeclimate.com/v1/badges/396ec0584e0a84adc723/maintainability)](https://codeclimate.com/github/yegor256/fief/maintainability)
12
+ [![Test Coverage](https://img.shields.io/codecov/c/github/yegor256/fief.svg)](https://codecov.io/github/yegor256/fief?branch=master)
13
+ ![Lines of code](https://img.shields.io/tokei/lines/github/yegor256/fief)
14
+ [![Hits-of-Code](https://hitsofcode.com/github/yegor256/fief)](https://hitsofcode.com/view/github/yegor256/fief)
15
+
16
+ This simple script will help you collect statistics about your
17
+ GitHub repositories and generate a simple HTML report. First, install it:
18
+
19
+ ```bash
20
+ $ gem install fief
21
+ ```
22
+
23
+ Then, run it locally and read its output:
24
+
25
+ ```bash
26
+ $ fief --repo yegor256/fief --verbose
27
+ ```
28
+
29
+ ## How to contribute
30
+
31
+ Read [these guidelines](https://www.yegor256.com/2014/04/15/github-guidelines.html).
32
+ Make sure you build is green before you contribute
33
+ your pull request. You will need to have [Ruby](https://www.ruby-lang.org/en/) 2.3+ and
34
+ [Bundler](https://bundler.io/) installed. Then:
35
+
36
+ ```
37
+ $ bundle update
38
+ $ bundle exec rake
39
+ ```
40
+
41
+ If it's clean and you don't see any error messages, submit your pull request.
data/Rakefile ADDED
@@ -0,0 +1,83 @@
1
+ # Copyright (c) 2023 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'rubygems'
22
+ require 'rake'
23
+ require 'rdoc'
24
+ require 'rake/clean'
25
+
26
+ def name
27
+ @name ||= File.basename(Dir['*.gemspec'].first, '.*')
28
+ end
29
+
30
+ def version
31
+ Gem::Specification.load(Dir['*.gemspec'].first).version
32
+ end
33
+
34
+ task default: %i[clean test features rubocop xcop copyright]
35
+
36
+ require 'rake/testtask'
37
+ desc 'Run all unit tests'
38
+ Rake::TestTask.new(:test) do |test|
39
+ Rake::Cleaner.cleanup_files(['coverage'])
40
+ test.libs << 'lib' << 'test'
41
+ test.pattern = 'test/**/test_*.rb'
42
+ test.verbose = false
43
+ end
44
+
45
+ require 'rdoc/task'
46
+ desc 'Build RDoc documentation'
47
+ Rake::RDocTask.new do |rdoc|
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "#{name} #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
53
+
54
+ require 'rubocop/rake_task'
55
+ desc 'Run RuboCop on all directories'
56
+ RuboCop::RakeTask.new(:rubocop) do |task|
57
+ task.fail_on_error = true
58
+ task.requires << 'rubocop-rspec'
59
+ task.options = ['--display-cop-names']
60
+ end
61
+
62
+ require 'xcop/rake_task'
63
+ Xcop::RakeTask.new(:xcop) do |task|
64
+ task.license = 'LICENSE.txt'
65
+ task.includes = ['**/*.xml', '**/*.xsl', '**/*.xsd', '**/*.html']
66
+ task.excludes = ['fief/**', 'coverage/**']
67
+ end
68
+
69
+ require 'cucumber/rake/task'
70
+ Cucumber::Rake::Task.new(:features) do
71
+ Rake::Cleaner.cleanup_files(['coverage'])
72
+ end
73
+ Cucumber::Rake::Task.new(:'features:html') do |t|
74
+ t.profile = 'html_report'
75
+ end
76
+
77
+ task :copyright do
78
+ sh "grep -q -r '#{Date.today.strftime('%Y')}' \
79
+ --include '*.rb' \
80
+ --include '*.txt' \
81
+ --include 'Rakefile' \
82
+ ."
83
+ end
data/assets/index.xsl ADDED
@@ -0,0 +1,200 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ (The MIT License)
4
+
5
+ Copyright (c) 2023 Yegor Bugayenko
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the 'Software'), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
24
+ -->
25
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
26
+ <xsl:output method="xml" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes"/>
27
+ <xsl:strip-spaces select="*"/>
28
+ <xsl:param name="version"/>
29
+ <xsl:template match="/">
30
+ <html>
31
+ <head>
32
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
33
+ <title>fief</title>
34
+ <meta charset="UTF-8"/>
35
+ <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
36
+ <link rel="icon" href="https://raw.githubusercontent.com/yegor256/fief/master/logo.svg" type="image/svg"/>
37
+ <link href="https://cdn.jsdelivr.net/gh/yegor256/tacit@gh-pages/tacit-css.min.css" rel="stylesheet"/>
38
+ <link href="https://cdn.jsdelivr.net/gh/yegor256/drops@gh-pages/drops.min.css" rel="stylesheet"/>
39
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js">
40
+ <xsl:text> </xsl:text>
41
+ </script>
42
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.min.js">
43
+ <xsl:text> </xsl:text>
44
+ </script>
45
+ <script type="text/javascript">
46
+ $(function() {
47
+ $("#metrics").tablesorter({
48
+ textExtraction: function(node) {
49
+ var attr = $(node).attr('data-sort-value');
50
+ if (typeof attr !== 'undefined' &amp;&amp; attr !== false) {
51
+ return attr;
52
+ }
53
+ return $(node).text();
54
+ }
55
+ });
56
+ });
57
+ $(function() {
58
+ let params = (new URL(document.location)).searchParams;
59
+ let org = params.get('org');
60
+ if (org) {
61
+ $('#metrics tbody tr:not(:has(&gt;td.org-' + org + '))').hide();
62
+ $('#org').text('@' + org);
63
+ $('#org-head').css('visibility', 'visible');
64
+ console.log('Showing @' + org + ' org');
65
+ }
66
+ });
67
+ </script>
68
+ <style>
69
+ td, th { font-family: monospace; font-size: 18px; line-height: 1em; }
70
+ td.top { vertical-align: middle; }
71
+ .num { text-align: right; }
72
+ .left { border-bottom: 0; }
73
+ section { width: auto; }
74
+ header { text-align: center; }
75
+ footer { text-align: center; font-size: 0.8em; line-height: 1.2em; color: gray; }
76
+ article { border: 0; }
77
+ .subtitle { font-size: 0.8em; line-height: 1em; color: gray; }
78
+ .sorter { cursor: pointer; }
79
+ </style>
80
+ </head>
81
+ <body>
82
+ <section>
83
+ <header>
84
+ <p>
85
+ <a href="">
86
+ <img src="https://raw.githubusercontent.com/yegor256/fief/master/logo.svg" style="width:64px"/>
87
+ </a>
88
+ </p>
89
+ </header>
90
+ <article>
91
+ <table id="metrics">
92
+ <xsl:attribute name="data-sortlist">
93
+ <xsl:text>[[</xsl:text>
94
+ <xsl:for-each select="fief/titles/title">
95
+ <xsl:sort select="."/>
96
+ <xsl:value-of select="position() + 2"/>
97
+ </xsl:for-each>
98
+ <xsl:text>,1]]</xsl:text>
99
+ </xsl:attribute>
100
+ <colgroup>
101
+ <col style="width: 2.5em;"/>
102
+ <xsl:for-each select="fief/titles/title">
103
+ <xsl:sort select="."/>
104
+ <col/>
105
+ </xsl:for-each>
106
+ <col/>
107
+ </colgroup>
108
+ <thead>
109
+ <xsl:apply-templates select="fief/titles"/>
110
+ </thead>
111
+ <xsl:apply-templates select="fief/repositories"/>
112
+ <tfoot>
113
+ <!-- nothing yet -->
114
+ </tfoot>
115
+ </table>
116
+ </article>
117
+ <footer>
118
+ <p>
119
+ <xsl:for-each select="fief/titles/title[@subtitle]">
120
+ <xsl:if test="position() &gt; 1">
121
+ <xsl:text>, </xsl:text>
122
+ </xsl:if>
123
+ <xsl:text>"</xsl:text>
124
+ <xsl:value-of select="."/>
125
+ <xsl:text>"</xsl:text>
126
+ <xsl:if test="position() = 1">
127
+ <xsl:text> stands</xsl:text>
128
+ </xsl:if>
129
+ <xsl:text> for </xsl:text>
130
+ <xsl:value-of select="@subtitle"/>
131
+ </xsl:for-each>
132
+ <xsl:text>.</xsl:text>
133
+ </p>
134
+ <p>
135
+ <xsl:text>The page was generated by </xsl:text>
136
+ <a href="https://github.com/yegor256/fief">
137
+ <xsl:text>fief</xsl:text>
138
+ <xsl:text> </xsl:text>
139
+ <xsl:value-of select="$version"/>
140
+ </a>
141
+ <xsl:text> on </xsl:text>
142
+ <xsl:value-of select="fief/@time"/>
143
+ <xsl:text>. </xsl:text>
144
+ <br/>
145
+ <xsl:text>The XML with the data </xsl:text>
146
+ <a href="index.xml">
147
+ <xsl:text>is here</xsl:text>
148
+ </a>
149
+ <xsl:text>.</xsl:text>
150
+ </p>
151
+ </footer>
152
+ </section>
153
+ </body>
154
+ </html>
155
+ </xsl:template>
156
+ <xsl:template match="fief/titles">
157
+ <tr>
158
+ <th class="sorter">
159
+ <xsl:text>Repository</xsl:text>
160
+ </th>
161
+ <xsl:for-each select="title">
162
+ <xsl:sort select="."/>
163
+ <th class="sorter num">
164
+ <xsl:value-of select="."/>
165
+ </th>
166
+ </xsl:for-each>
167
+ </tr>
168
+ </xsl:template>
169
+ <xsl:template match="fief/repositories">
170
+ <tbody>
171
+ <xsl:apply-templates select="repository"/>
172
+ </tbody>
173
+ </xsl:template>
174
+ <xsl:template match="repository">
175
+ <tr>
176
+ <td class="top">
177
+ <a href="https://github.com/{@id}">
178
+ <xsl:value-of select="@id"/>
179
+ </a>
180
+ </td>
181
+ <xsl:for-each select="metrics/m">
182
+ <xsl:sort select="@id"/>
183
+ <xsl:apply-templates select="."/>
184
+ </xsl:for-each>
185
+ </tr>
186
+ </xsl:template>
187
+ <xsl:template match="m">
188
+ <td class="num">
189
+ <xsl:attribute name="data-sort-value">
190
+ <xsl:copy-of select="."/>
191
+ </xsl:attribute>
192
+ <xsl:copy-of select="."/>
193
+ </td>
194
+ </xsl:template>
195
+ <xsl:template match="node()|@*">
196
+ <xsl:copy>
197
+ <xsl:apply-templates select="node()|@*"/>
198
+ </xsl:copy>
199
+ </xsl:template>
200
+ </xsl:stylesheet>