##// END OF EJS Templates
docs: move i18n how_to directly under docs
Thomas De Schampheleire -
r8260:a564e87a stable
parent child Browse files
Show More
@@ -1,255 +1,257 b''
1 .. _translations:
2
1 ============
3 ============
2 Translations
4 Translations
3 ============
5 ============
4
6
5 Translations are available on Hosted Weblate at the following URL:
7 Translations are available on Hosted Weblate at the following URL:
6
8
7 https://hosted.weblate.org/projects/kallithea/kallithea/
9 https://hosted.weblate.org/projects/kallithea/kallithea/
8
10
9 Registered users may contribute to the existing languages, or request a new
11 Registered users may contribute to the existing languages, or request a new
10 language translation.
12 language translation.
11
13
12
14
13 Translating using Weblate
15 Translating using Weblate
14 -------------------------
16 -------------------------
15
17
16 Weblate_ offers a simple and easy to use interface featuring glossary, machine
18 Weblate_ offers a simple and easy to use interface featuring glossary, machine
17 translation, suggestions based on similar translations in other projects,
19 translation, suggestions based on similar translations in other projects,
18 automatic checks etc. Weblate imports the source code tree directly from
20 automatic checks etc. Weblate imports the source code tree directly from
19 the version control system, and commits edits back from time to time.
21 the version control system, and commits edits back from time to time.
20
22
21 When registering at Weblate, make sure you use the name and email address you
23 When registering at Weblate, make sure you use the name and email address you
22 prefer to be used when your changes are committed. We can and probably will
24 prefer to be used when your changes are committed. We can and probably will
23 amend changesets coming from Weblate, but having things right from the beginning
25 amend changesets coming from Weblate, but having things right from the beginning
24 makes things easier.
26 makes things easier.
25
27
26 Weblate performs sanity checks all the time and tries to prevent you from ignoring
28 Weblate performs sanity checks all the time and tries to prevent you from ignoring
27 them. Most common mistakes are inconsistent punctuation, whitespace, missing or extra
29 them. Most common mistakes are inconsistent punctuation, whitespace, missing or extra
28 format parameters, untranslated strings copied into the translation. Please perform
30 format parameters, untranslated strings copied into the translation. Please perform
29 necessary corrections when they're needed, or override the false positives.
31 necessary corrections when they're needed, or override the false positives.
30
32
31
33
32 Merging translations from Weblate (admin-only)
34 Merging translations from Weblate (admin-only)
33 ----------------------------------------------
35 ----------------------------------------------
34
36
35 Weblate rebases its changes every time it pulls from our repository. Pulls are triggered
37 Weblate rebases its changes every time it pulls from our repository. Pulls are triggered
36 by a web hook from Our Own Kallithea every time it receives new commits. Usually merging
38 by a web hook from Our Own Kallithea every time it receives new commits. Usually merging
37 the new translations is a straightforward process consisting of a pull from the Weblate-hosted
39 the new translations is a straightforward process consisting of a pull from the Weblate-hosted
38 repository which is available under the Data Exports tab in the Weblate interface.
40 repository which is available under the Data Exports tab in the Weblate interface.
39
41
40 Weblate tries to minimise the number of commits, but that doesn't always work, especially
42 Weblate tries to minimise the number of commits, but that doesn't always work, especially
41 when two translators work with different languages at more or less the same time.
43 when two translators work with different languages at more or less the same time.
42 It makes sense sometimes to re-order or fold commits by the same author when they touch
44 It makes sense sometimes to re-order or fold commits by the same author when they touch
43 just the same language translation. That, however, may confuse Weblate sometimes, in
45 just the same language translation. That, however, may confuse Weblate sometimes, in
44 which case it should be manually convinced it has to discard the commits it created by
46 which case it should be manually convinced it has to discard the commits it created by
45 using its administrative interface.
47 using its administrative interface.
46
48
47
49
48 Regenerating translations after source code changes (admin-only)
50 Regenerating translations after source code changes (admin-only)
49 ----------------------------------------------------------------
51 ----------------------------------------------------------------
50
52
51 When the Kallithea source code changes, both the location as the content of
53 When the Kallithea source code changes, both the location as the content of
52 translation strings can change. It is therefore necessary to regularly
54 translation strings can change. It is therefore necessary to regularly
53 regenerate the `kallithea.pot` file containing these strings, as well as aligning
55 regenerate the `kallithea.pot` file containing these strings, as well as aligning
54 the translation files (`*.po`).
56 the translation files (`*.po`).
55
57
56 First update the translation strings::
58 First update the translation strings::
57
59
58 python3 setup.py extract_messages
60 python3 setup.py extract_messages
59
61
60 Then regenerate the translation files. This could either be done with `python3
62 Then regenerate the translation files. This could either be done with `python3
61 setup.py update_catalog` or with `msgmerge` from the `gettext` package. As
63 setup.py update_catalog` or with `msgmerge` from the `gettext` package. As
62 Weblate is also touching these translation files, it is preferred to use the
64 Weblate is also touching these translation files, it is preferred to use the
63 same tools (`msgmerge`) and settings as Weblate to minimize the diff::
65 same tools (`msgmerge`) and settings as Weblate to minimize the diff::
64
66
65 find kallithea/i18n -name kallithea.po | xargs -I '{}' \
67 find kallithea/i18n -name kallithea.po | xargs -I '{}' \
66 msgmerge --width=76 --backup=none --previous --update '{}' \
68 msgmerge --width=76 --backup=none --previous --update '{}' \
67 kallithea/i18n/kallithea.pot
69 kallithea/i18n/kallithea.pot
68
70
69
71
70 Manual creation of a new language translation
72 Manual creation of a new language translation
71 ---------------------------------------------
73 ---------------------------------------------
72
74
73 In the prepared development environment, run the following to ensure
75 In the prepared development environment, run the following to ensure
74 all translation strings are extracted and up-to-date::
76 all translation strings are extracted and up-to-date::
75
77
76 python3 setup.py extract_messages
78 python3 setup.py extract_messages
77
79
78 Create new language by executing following command::
80 Create new language by executing following command::
79
81
80 python3 setup.py init_catalog -l <new_language_code>
82 python3 setup.py init_catalog -l <new_language_code>
81
83
82 This creates a new translation under directory `kallithea/i18n/<new_language_code>`
84 This creates a new translation under directory `kallithea/i18n/<new_language_code>`
83 based on the translation template file, `kallithea/i18n/kallithea.pot`.
85 based on the translation template file, `kallithea/i18n/kallithea.pot`.
84
86
85 Edit the new PO file located in `LC_MESSAGES` directory with poedit or your
87 Edit the new PO file located in `LC_MESSAGES` directory with poedit or your
86 favorite PO files editor. After you finished with the translations, check the
88 favorite PO files editor. After you finished with the translations, check the
87 translation file for errors by executing::
89 translation file for errors by executing::
88
90
89 msgfmt -f -c kallithea/i18n/<new_language_code>/LC_MESSAGES/<updated_file.po>
91 msgfmt -f -c kallithea/i18n/<new_language_code>/LC_MESSAGES/<updated_file.po>
90
92
91 Finally, compile the translations::
93 Finally, compile the translations::
92
94
93 python3 setup.py compile_catalog -l <new_language_code>
95 python3 setup.py compile_catalog -l <new_language_code>
94
96
95
97
96 Manually updating translations
98 Manually updating translations
97 ------------------------------
99 ------------------------------
98
100
99 Extract the latest versions of strings for translation by running::
101 Extract the latest versions of strings for translation by running::
100
102
101 python3 setup.py extract_messages
103 python3 setup.py extract_messages
102
104
103 Update the PO file by doing::
105 Update the PO file by doing::
104
106
105 python3 setup.py update_catalog -l <new_language_code>
107 python3 setup.py update_catalog -l <new_language_code>
106
108
107 Edit the newly updated translation file. Repeat all steps after the
109 Edit the newly updated translation file. Repeat all steps after the
108 `init_catalog` step from the 'new translation' instructions above.
110 `init_catalog` step from the 'new translation' instructions above.
109
111
110
112
111 Testing translations
113 Testing translations
112 --------------------
114 --------------------
113
115
114 Edit `kallithea/tests/conftest.py` and set `i18n.lang` to `<new_language_code>`
116 Edit `kallithea/tests/conftest.py` and set `i18n.lang` to `<new_language_code>`
115 and run Kallithea tests by executing::
117 and run Kallithea tests by executing::
116
118
117 py.test
119 py.test
118
120
119
121
120 Managing translations with scripts/i18n tooling
122 Managing translations with scripts/i18n tooling
121 -----------------------------------------------
123 -----------------------------------------------
122
124
123 The general idea with the ``scripts/i18n`` tooling is to keep changes in the
125 The general idea with the ``scripts/i18n`` tooling is to keep changes in the
124 main repository focussed on actual and reviewable changes with minimal noise.
126 main repository focussed on actual and reviewable changes with minimal noise.
125 Noisy generated or redundant localization changes (that are useful when
127 Noisy generated or redundant localization changes (that are useful when
126 translations) are contained in the ``kallithea-i18n`` repo on the ``i18n``
128 translations) are contained in the ``kallithea-i18n`` repo on the ``i18n``
127 branch. The translation files in the main repository have no line numbers, no
129 branch. The translation files in the main repository have no line numbers, no
128 untranslated entries, no fuzzy entries, no unused entries, and no constantly
130 untranslated entries, no fuzzy entries, no unused entries, and no constantly
129 changing records of "latest" this and that (name, date, version, etc).
131 changing records of "latest" this and that (name, date, version, etc).
130
132
131 The branches in the main repo (``default`` and ``stable``) will thus only have
133 The branches in the main repo (``default`` and ``stable``) will thus only have
132 stripped ``.pot`` and ``.po`` files: an (almost) empty
134 stripped ``.pot`` and ``.po`` files: an (almost) empty
133 ``kallithea/i18n/kallithea.pot`` file, and minimal ``.po`` files. There are no
135 ``kallithea/i18n/kallithea.pot`` file, and minimal ``.po`` files. There are no
134 binary ``.mo`` files in any repo - these are only generated when packaging for
136 binary ``.mo`` files in any repo - these are only generated when packaging for
135 release (or locally if installing from source).
137 release (or locally if installing from source).
136
138
137 Generally, ``kallithea/i18n/`` should not be changed on the ``default`` and
139 Generally, ``kallithea/i18n/`` should not be changed on the ``default`` and
138 ``stable`` branches at all. The ``i18n`` branch should *only* change
140 ``stable`` branches at all. The ``i18n`` branch should *only* change
139 ``kallithea/i18n/`` . If there are changesets with exceptions from that, these
141 ``kallithea/i18n/`` . If there are changesets with exceptions from that, these
140 changesets should probably be grafted/redone in the "right" place.
142 changesets should probably be grafted/redone in the "right" place.
141
143
142 The basic flow is thus:
144 The basic flow is thus:
143
145
144 0. All weblate translation is done on the ``i18n`` branch which generally is
146 0. All weblate translation is done on the ``i18n`` branch which generally is
145 based on the ``stable`` branch.
147 based on the ``stable`` branch.
146 1. Graft the essential part of all new changes on the ``i18n`` branch to
148 1. Graft the essential part of all new changes on the ``i18n`` branch to
147 ``stable`` (while normalizing to current stripped state of stable).
149 ``stable`` (while normalizing to current stripped state of stable).
148 2. Merge from ``stable`` to ``i18n`` (while normalizing to the resulting
150 2. Merge from ``stable`` to ``i18n`` (while normalizing to the resulting
149 unstripped and fully ``msgmerge``'d state and ``.pot``-updating state).
151 unstripped and fully ``msgmerge``'d state and ``.pot``-updating state).
150 3. Verify that the content of the ``i18n`` branch will give exactly the content
152 3. Verify that the content of the ``i18n`` branch will give exactly the content
151 of the ``stable`` branch after stripping. If there is a diff, something has
153 of the ``stable`` branch after stripping. If there is a diff, something has
152 to be fixed in one way or the other ... and the whole process should
154 to be fixed in one way or the other ... and the whole process should
153 probably be redone.
155 probably be redone.
154
156
155 Translate
157 Translate
156 ^^^^^^^^^
158 ^^^^^^^^^
157
159
158 First land full translation changes in the ``kallithea-i18n`` repo on the
160 First land full translation changes in the ``kallithea-i18n`` repo on the
159 ``i18n`` branch. That can be done in pretty much any way you want. If changes
161 ``i18n`` branch. That can be done in pretty much any way you want. If changes
160 for some reason have to be grafted or merged, there might be odd conflicts due
162 for some reason have to be grafted or merged, there might be odd conflicts due
161 to all the noise. Conflicts on the full ``i18n`` branch can perhaps be resolved
163 to all the noise. Conflicts on the full ``i18n`` branch can perhaps be resolved
162 more easily using non-stripping normalization before merging::
164 more easily using non-stripping normalization before merging::
163
165
164 python3 setup.py extract_messages && cp kallithea/i18n/kallithea.pot full.pot && hg revert kallithea/i18n/kallithea.pot -r .
166 python3 setup.py extract_messages && cp kallithea/i18n/kallithea.pot full.pot && hg revert kallithea/i18n/kallithea.pot -r .
165 hg resolve kallithea/i18n/ --tool X --config merge-tools.X.executable=python3 --config merge-tools.X.args='scripts/i18n normalized-merge --merge-pot-file full.pot $local $base $other $output'
167 hg resolve kallithea/i18n/ --tool X --config merge-tools.X.executable=python3 --config merge-tools.X.args='scripts/i18n normalized-merge --merge-pot-file full.pot $local $base $other $output'
166
168
167 Land in main repository - stripped
169 Land in main repository - stripped
168 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
170 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
169
171
170 When the full i18n changes have landed on the ``i18n`` branch, prepare to land
172 When the full i18n changes have landed on the ``i18n`` branch, prepare to land
171 them on ``stable``::
173 them on ``stable``::
172
174
173 hg up -cr stable
175 hg up -cr stable
174 python3 setup.py extract_messages && cp kallithea/i18n/kallithea.pot full.pot && hg revert kallithea/i18n/kallithea.pot
176 python3 setup.py extract_messages && cp kallithea/i18n/kallithea.pot full.pot && hg revert kallithea/i18n/kallithea.pot
175
177
176 Consider all new ``i18n`` changes since last merge from ``stable``::
178 Consider all new ``i18n`` changes since last merge from ``stable``::
177
179
178 hg log -G --style compact -r 'only("i18n", children(::stable))'
180 hg log -G --style compact -r 'only("i18n", children(::stable))'
179
181
180 Graft them one by one (or in collapsed chunks) while normalizing.
182 Graft them one by one (or in collapsed chunks) while normalizing.
181
183
182 If the graft has conflicts, use the ``scripts/i18n`` normalization tool to
184 If the graft has conflicts, use the ``scripts/i18n`` normalization tool to
183 apply ``msgmerge`` and strip before doing 3-way merge and resolving conflicts::
185 apply ``msgmerge`` and strip before doing 3-way merge and resolving conflicts::
184
186
185 hg resolve kallithea/i18n/ --tool X --config merge-tools.X.executable=python3 --config merge-tools.X.args='scripts/i18n normalized-merge --merge-pot-file full.pot --strip $local $base $other $output'
187 hg resolve kallithea/i18n/ --tool X --config merge-tools.X.executable=python3 --config merge-tools.X.args='scripts/i18n normalized-merge --merge-pot-file full.pot --strip $local $base $other $output'
186
188
187 When all conflicts have been resolved, continue the graft::
189 When all conflicts have been resolved, continue the graft::
188
190
189 hg graft --continue
191 hg graft --continue
190
192
191 Then make sure any non-conflicting files are normalized and stripped too::
193 Then make sure any non-conflicting files are normalized and stripped too::
192
194
193 scripts/i18n normalize-po-files --strip --merge-pot-file full.pot kallithea/i18n/*/LC_MESSAGES/kallithea.po
195 scripts/i18n normalize-po-files --strip --merge-pot-file full.pot kallithea/i18n/*/LC_MESSAGES/kallithea.po
194 hg ci --amend --config ui.editor=true
196 hg ci --amend --config ui.editor=true
195
197
196 When things have been grafted to the ``stable`` branch, clean up history if
198 When things have been grafted to the ``stable`` branch, clean up history if
197 necessary: clean up the author and commit message when necessary, and perhaps
199 necessary: clean up the author and commit message when necessary, and perhaps
198 merge multiple changesets from same contributor.
200 merge multiple changesets from same contributor.
199
201
200 Merge back to ``i18n``
202 Merge back to ``i18n``
201 ^^^^^^^^^^^^^^^^^^^^^^
203 ^^^^^^^^^^^^^^^^^^^^^^
202
204
203 For any i18n changes that for some reason have been done on the ``stable``
205 For any i18n changes that for some reason have been done on the ``stable``
204 branch, apply them manually on the ``i18n`` branch too - perhaps by grafting
206 branch, apply them manually on the ``i18n`` branch too - perhaps by grafting
205 and editing manually. The merge done in this step will `not` take care of it.
207 and editing manually. The merge done in this step will `not` take care of it.
206 If the verification step done a bit later points out that something has been
208 If the verification step done a bit later points out that something has been
207 missed, strip and go back to this point.
209 missed, strip and go back to this point.
208
210
209 Then merge back to the ``i18n`` branch using normalization while keeping the
211 Then merge back to the ``i18n`` branch using normalization while keeping the
210 full ``.po`` files, and updating the full ``.pot`` and ``.po`` to current
212 full ``.po`` files, and updating the full ``.pot`` and ``.po`` to current
211 state::
213 state::
212
214
213 hg up -cr i18n
215 hg up -cr i18n
214 hg merge stable --tool internal:fail
216 hg merge stable --tool internal:fail
215 hg revert kallithea/i18n/*/LC_MESSAGES/*.po -r .
217 hg revert kallithea/i18n/*/LC_MESSAGES/*.po -r .
216 hg resolve -m kallithea/i18n/*/LC_MESSAGES/*.po
218 hg resolve -m kallithea/i18n/*/LC_MESSAGES/*.po
217 hg resolve -l # verify all conflicts have been resolved
219 hg resolve -l # verify all conflicts have been resolved
218 python3 setup.py extract_messages && cp kallithea/i18n/kallithea.pot full.pot
220 python3 setup.py extract_messages && cp kallithea/i18n/kallithea.pot full.pot
219 scripts/i18n normalize-po-files --merge-pot-file full.pot kallithea/i18n/*/LC_MESSAGES/kallithea.po
221 scripts/i18n normalize-po-files --merge-pot-file full.pot kallithea/i18n/*/LC_MESSAGES/kallithea.po
220 hg commit # "Merge from stable"
222 hg commit # "Merge from stable"
221
223
222 Note: ``normalize-po-files`` can also pretty much be done manually with::
224 Note: ``normalize-po-files`` can also pretty much be done manually with::
223
225
224 for po in kallithea/i18n/*/LC_MESSAGES/kallithea.po; do msgmerge --width=76 --backup=none --previous --update $po full.pot ; done
226 for po in kallithea/i18n/*/LC_MESSAGES/kallithea.po; do msgmerge --width=76 --backup=none --previous --update $po full.pot ; done
225
227
226 Note: Additional merges from ``stable`` to ``i18n`` can be done any time.
228 Note: Additional merges from ``stable`` to ``i18n`` can be done any time.
227
229
228 Verify
230 Verify
229 ^^^^^^
231 ^^^^^^
230
232
231 Verify things are in sync between the full ``i18n`` branch and the stripped
233 Verify things are in sync between the full ``i18n`` branch and the stripped
232 ``stable`` branch::
234 ``stable`` branch::
233
235
234 hg up -cr stable
236 hg up -cr stable
235 hg revert -a -r i18n
237 hg revert -a -r i18n
236 python3 setup.py extract_messages && cp kallithea/i18n/kallithea.pot full.pot && hg revert kallithea/i18n/kallithea.pot
238 python3 setup.py extract_messages && cp kallithea/i18n/kallithea.pot full.pot && hg revert kallithea/i18n/kallithea.pot
237 scripts/i18n normalize-po-files --strip --merge-pot-file full.pot kallithea/i18n/*/LC_MESSAGES/kallithea.po
239 scripts/i18n normalize-po-files --strip --merge-pot-file full.pot kallithea/i18n/*/LC_MESSAGES/kallithea.po
238 hg diff
240 hg diff
239
241
240 If there is a diff, figure out where it came from, go back and fix the root
242 If there is a diff, figure out where it came from, go back and fix the root
241 cause, and redo the graft/merge.
243 cause, and redo the graft/merge.
242
244
243 Push
245 Push
244 ^^^^
246 ^^^^
245
247
246 The changes on the ``stable`` branch should now be ready for pushing - verify
248 The changes on the ``stable`` branch should now be ready for pushing - verify
247 the actual changes with a thorough review of::
249 the actual changes with a thorough review of::
248
250
249 hg out -pvr stable
251 hg out -pvr stable
250
252
251 When ``stable`` changes have been pushed, also push the ``i18n`` branch to the
253 When ``stable`` changes have been pushed, also push the ``i18n`` branch to the
252 ``kallithea-i18n`` repo so Weblate can see it.
254 ``kallithea-i18n`` repo so Weblate can see it.
253
255
254
256
255 .. _Weblate: http://weblate.org/
257 .. _Weblate: http://weblate.org/
@@ -1,89 +1,89 b''
1 .. _index:
1 .. _index:
2
2
3 #######################
3 #######################
4 Kallithea Documentation
4 Kallithea Documentation
5 #######################
5 #######################
6
6
7 * :ref:`genindex`
7 * :ref:`genindex`
8 * :ref:`search`
8 * :ref:`search`
9
9
10
10
11 Readme
11 Readme
12 ******
12 ******
13
13
14 .. toctree::
14 .. toctree::
15 :maxdepth: 1
15 :maxdepth: 1
16
16
17 readme
17 readme
18
18
19
19
20 Administrator guide
20 Administrator guide
21 *******************
21 *******************
22
22
23 **Installation and upgrade**
23 **Installation and upgrade**
24
24
25 .. toctree::
25 .. toctree::
26 :maxdepth: 1
26 :maxdepth: 1
27
27
28 overview
28 overview
29 installation
29 installation
30 installation_win
30 installation_win
31 installation_win_old
31 installation_win_old
32 installation_iis
32 installation_iis
33 installation_puppet
33 installation_puppet
34 upgrade
34 upgrade
35
35
36 **Setup and configuration**
36 **Setup and configuration**
37
37
38 .. toctree::
38 .. toctree::
39 :maxdepth: 1
39 :maxdepth: 1
40
40
41 setup
41 setup
42 administrator_guide/auth
42 administrator_guide/auth
43 administrator_guide/vcs_setup
43 administrator_guide/vcs_setup
44 usage/email
44 usage/email
45 usage/customization
45 usage/customization
46
46
47 **Maintenance**
47 **Maintenance**
48
48
49 .. toctree::
49 .. toctree::
50 :maxdepth: 1
50 :maxdepth: 1
51
51
52 usage/backup
52 usage/backup
53 usage/performance
53 usage/performance
54 usage/debugging
54 usage/debugging
55 usage/troubleshooting
55 usage/troubleshooting
56
56
57
57
58 User guide
58 User guide
59 **********
59 **********
60
60
61 .. toctree::
61 .. toctree::
62 :maxdepth: 1
62 :maxdepth: 1
63
63
64 usage/general
64 usage/general
65 usage/vcs_notes
65 usage/vcs_notes
66 usage/statistics
66 usage/statistics
67 api/api
67 api/api
68
68
69
69
70 Developer guide
70 Developer guide
71 ***************
71 ***************
72
72
73 .. toctree::
73 .. toctree::
74 :maxdepth: 1
74 :maxdepth: 1
75
75
76 contributing
76 contributing
77 dev/translation
77 dev/i18n
78 dev/dbmigrations
78 dev/dbmigrations
79
79
80
80
81 .. _python: http://www.python.org/
81 .. _python: http://www.python.org/
82 .. _django: http://www.djangoproject.com/
82 .. _django: http://www.djangoproject.com/
83 .. _mercurial: https://www.mercurial-scm.org/
83 .. _mercurial: https://www.mercurial-scm.org/
84 .. _bitbucket: http://bitbucket.org/
84 .. _bitbucket: http://bitbucket.org/
85 .. _subversion: http://subversion.tigris.org/
85 .. _subversion: http://subversion.tigris.org/
86 .. _git: http://git-scm.com/
86 .. _git: http://git-scm.com/
87 .. _celery: http://celeryproject.org/
87 .. _celery: http://celeryproject.org/
88 .. _Sphinx: http://sphinx.pocoo.org/
88 .. _Sphinx: http://sphinx.pocoo.org/
89 .. _vcs: http://pypi.python.org/pypi/vcs
89 .. _vcs: http://pypi.python.org/pypi/vcs
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now