pax_global_header00006660000000000000000000000064142337763240014525gustar00rootroot0000000000000052 comment=168d3d5df282d16c9059d08faedc5a323254d951 ghp-import-2.1.0/000077500000000000000000000000001423377632400136135ustar00rootroot00000000000000ghp-import-2.1.0/.circleci/000077500000000000000000000000001423377632400154465ustar00rootroot00000000000000ghp-import-2.1.0/.circleci/config.yml000066400000000000000000000007071423377632400174420ustar00rootroot00000000000000version: 2 jobs: test: docker: - image: circleci/python steps: - checkout - run: make install - run: git config --global user.name "ghp-import-bot" && git config --global user.email "ghp@import.bot" - run: make -e DOCS_BRANCH="test-circleci-$CIRCLE_BUILD_NUM" docs clean workflows: version: 2 main: jobs: - test: filters: branches: only: - master ghp-import-2.1.0/.github/000077500000000000000000000000001423377632400151535ustar00rootroot00000000000000ghp-import-2.1.0/.github/workflows/000077500000000000000000000000001423377632400172105ustar00rootroot00000000000000ghp-import-2.1.0/.github/workflows/cd.yaml000066400000000000000000000014771423377632400204730ustar00rootroot00000000000000name: CD on: push: branches: - master jobs: gh-pages: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: '3.9' - run: git remote set-url --push origin "https://:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: make install - run: make docs pypi: runs-on: ubuntu-latest if: "startsWith(github.event.head_commit.message, 'This is ')" steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: '3.9' - run: make install - run: make release env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} ghp-import-2.1.0/.github/workflows/ci.yaml000066400000000000000000000007301423377632400204670ustar00rootroot00000000000000name: CI on: [pull_request] jobs: ci: runs-on: ${{ matrix.os }}-latest strategy: matrix: python-version: ['2.7', '3.9'] os: [ubuntu, windows, macos] opts: ['--shell', ''] steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - run: make install - run: make lint - run: make -e DOCS_OPTS="${{ matrix.opts }}" docs ghp-import-2.1.0/.gitignore000066400000000000000000000001331423377632400156000ustar00rootroot00000000000000.idea/ .vscode/ build/ dist/ venv/ *.pyc __pycache__/ ghp_import.egg-info/ docs/index.html ghp-import-2.1.0/.travis.yml000066400000000000000000000006111423377632400157220ustar00rootroot00000000000000language: python branches: only: - master install: - make install before_script: - git remote add github "https://${GITHUB_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git" 2>&1 >/dev/null - export GIT_COMMITTER_NAME="ghp-import-bot" - export GIT_COMMITTER_EMAIL="ghp@import.bot" script: - make -e DOCS_BRANCH="test-travis-${TRAVIS_BUILD_NUMBER}" -e DOCS_REMOTE=github docs clean ghp-import-2.1.0/LICENSE000066400000000000000000000261561423377632400146320ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [2020] [Paul Davis ] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ghp-import-2.1.0/MANIFEST.in000066400000000000000000000000421423377632400153450ustar00rootroot00000000000000include LICENSE include README.md ghp-import-2.1.0/Makefile000066400000000000000000000011051423377632400152500ustar00rootroot00000000000000DOCS_BRANCH := gh-pages DOCS_REMOTE := origin DOCS_OPTS := -p install: pip install -e .[dev] lint: flake8 ./ghp_import.py ./setup.py ./docs/build.py docs: python ./docs/build.py ghp-import $(DOCS_OPTS) docs/ -b $(DOCS_BRANCH) -r $(DOCS_REMOTE) -m "Update docs [skip ci]" -o clean: python -c "import os; os.remove(os.path.join('docs', 'index.html'))" git branch -D $(DOCS_BRANCH) git push $(DOCS_REMOTE) --delete $(DOCS_BRANCH) release: python setup.py sdist bdist_wheel twine upload --skip-existing --non-interactive ./dist/* .PHONY: docs lint install clean release ghp-import-2.1.0/README.md000066400000000000000000000141271423377632400150770ustar00rootroot00000000000000GitHub Pages Import =================== [![CI status](https://github.com/davisp/ghp-import/workflows/CI/badge.svg)](https://github.com/davisp/ghp-import/actions?query=workflow%3Aci) [![CircleCI](https://circleci.com/gh/c-w/ghp-import/tree/master.svg?style=svg)](https://circleci.com/gh/c-w/ghp-import/tree/master) [![TravisCI](https://travis-ci.org/c-w/ghp-import.svg?branch=master)](https://travis-ci.org/c-w/ghp-import) [![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0) [![Version](https://img.shields.io/pypi/v/ghp-import.svg)](https://pypi.org/project/ghp-import/) As part of [gunicorn][gunicorn], [Benoit Chesneau][benoit] and [Paul Davis][davisp] were looking at how to host documentation. There's the obvious method of using [GitHub's post-receive hook][github-post] to trigger doc builds and rsync to a webserver, but we ended up wanting to try out github's hosting to make the whole interface a bit more robust. [GitHub Pages][gh-pages] is a pretty awesome service that GitHub provides for hosting project documentation. The only thing is that it requires a `gh-pages` branch that is the site's document root. This means that keeping documentation sources in the branch with code is a bit difficult. And it really turns into a head scratcher for things like [Sphinx][sphinx] that want to access documentation sources and code sources at the same time. Then we stumbled across an interesting looking package called [github-tools][github-tools] that looked almost like what we wanted. It was a tad complicated and more involved than we wanted but it gave us an idea. Why not just write a script that can copy a directory to the `gh-pages` branch of the repository. This saves us from even having to think about the branch and everything becomes magical. This is what `ghp-import` was written for. [gunicorn]: http://www.gunicorn.com/ "Gunicorn" [benoit]: http://github.com/benoitc "Benoît Chesneau" [davisp]: http://github.com/davisp "Paul J. Davis" [github-post]: https://help.github.com/articles/post-receive-hooks "GitHub Post-Receive Hook" [gh-pages]: http://pages.github.com/ "GitHub Pages" [sphinx]: http://sphinx.pocoo.org/ "Sphinx Documentation" [github-tools]: http://dinoboff.github.com/github-tools/ "github-tools" Big Fat Warning --------------- This will **DESTROY** your `gh-pages` branch. If you love it, you'll want to take backups before playing with this. This script assumes that `gh-pages` is 100% derivative. You should never edit files in your `gh-pages` branch by hand if you're using this script because you will lose your work. When used with a prefix, only files below the set prefix will be destroyed, limiting the above warning to just that directory and everything below it. Usage ----- ``` Usage: ghp-import [OPTIONS] DIRECTORY Options: -n, --no-jekyll Include a .nojekyll file in the branch. -c CNAME, --cname=CNAME Write a CNAME file with the given CNAME. -m MESG, --message=MESG The commit message to use on the target branch. -p, --push Push the branch to origin/{branch} after committing. -x PREFIX, --prefix=PREFIX The prefix to add to each file that gets pushed to the remote. Only files below this prefix will be cleared out. [none] -f, --force Force the push to the repository. -o, --no-history Force new commit without parent history. -r REMOTE, --remote=REMOTE The name of the remote to push to. [origin] -b BRANCH, --branch=BRANCH Name of the branch to write to. [gh-pages] -s, --shell Use the shell when invoking Git. [False] -l, --follow-links Follow symlinks when adding files. [False] -h, --help show this help message and exit ``` Its pretty simple. Inside your repository just run `ghp-import $DOCS_DIR` where `$DOCS_DIR` is the path to the **built** documentation. This will write a commit to your `gh-pages` branch with the current documents in it. If you specify `-p` it will also attempt to push the `gh-pages` branch to GitHub. By default it'll just run `git push origin gh-pages`. You can specify a different remote using the `-r` flag. The `-o` option will discard any previous history and ensure that only a single commit is always pushed to the `gh-pages` branch. This is useful to avoid bloating the repository size and is **highly recommended**. You can specify a different branch with `-b`. This is useful for user and organization page, which are served from the `master` branch. Some Windows users report needing to pass Git commands through the shell which can be accomplished by passing `-s`. The `-l` option will cause the import to follow symlinks for users that have odd configurations that include symlinking outside of their documentation directory. Python Usage ------------ You can also call ghp_import directly from your Python code as a library. The library has one public function `ghp_import.ghp_import`, which accepts the following arguments: * `srcdir`: The path to the **built** documentation (required). * `remote`: The name of the remote to push to. Default: `origin`. * `branch`: Name of the branch to write to. Default: `gh-pages`. * `mesg`: The commit message to use on the target branch. Default: `Update documentation`. * `push`: Push the branch to {remote}/{branch} after committing. Default: `False`. * `prefix`: The prefix to add to each file that gets pushed to the remote. Default: `None`. * `force`: Force the push to the repository. Default: `False`. * `no_history`: Force new commit without parent history. Default: `False`. * `use_shell`: Default: Use the shell when invoking Git. `False`. * `followlinks`: Follow symlinks when adding files. Default: `False`. * `cname`: Write a CNAME file with the given CNAME. Default: `None`. * `nojekyll`: Include a .nojekyll file in the branch. Default: `False`. With Python's current working directory (cwd) inside your repository, do the following: ```python from ghp_import import ghp_import ghp_import('docs', push=True, cname='example.com') ``` ghp-import-2.1.0/docs/000077500000000000000000000000001423377632400145435ustar00rootroot00000000000000ghp-import-2.1.0/docs/build.py000077500000000000000000000013051423377632400162160ustar00rootroot00000000000000#!/usr/bin/env python import io import os from markdown import markdown def main(): base = os.path.abspath(os.path.dirname(__file__)) readme_path = os.path.join(os.path.dirname(base), "README.md") with io.open(readme_path, encoding="utf-8") as fobj: readme = fobj.read() template_path = os.path.join(base, "index.html.tmpl") with io.open(template_path, encoding="utf-8") as fobj: template = fobj.read() index_path = os.path.join(base, "index.html") with io.open(index_path, mode="w", encoding="utf-8") as fobj: html = markdown(readme, extensions=["fenced_code"]) fobj.write(template.format(body=html)) if __name__ == "__main__": main() ghp-import-2.1.0/docs/images/000077500000000000000000000000001423377632400160105ustar00rootroot00000000000000ghp-import-2.1.0/docs/images/bg_hr.png000066400000000000000000000016571423377632400176100ustar00rootroot00000000000000PNG  IHDRa{O@tEXtSoftwareAdobe ImageReadyqe<"iTXtXML:com.adobe.xmp $;#IDATxb?2`b@FA&8d` ]CIENDB`ghp-import-2.1.0/docs/images/blacktocat.png000066400000000000000000000026241423377632400206310ustar00rootroot00000000000000PNG  IHDR;0tEXtSoftwareAdobe ImageReadyqe<"iTXtXML:com.adobe.xmp tIDATxWm0 >N}/#df6h:Ao6`Fpp7lФr'}% !bDZlӿ%9M25KvdCǁ"ZCQ*pp/ّ|#oE`#֑] @+{\(?6 3dT1t>*w"U츋aQaz1Q]3\; σ%H?Y ڃz^= "pk =SAGjτ)PVIȌx; ;v^s<.*tj&[!]8'Yձ)̀^"V;!iV UOLC@6ЫTy#Prp:Nh~}ņM>b!E`tHT=1xXySϭ2s(iOxкӥpzI -PH$~C^H [E IENDB`ghp-import-2.1.0/docs/images/icon_download.png000066400000000000000000000022121423377632400213320ustar00rootroot00000000000000PNG  IHDR;0tEXtSoftwareAdobe ImageReadyqe<"iTXtXML:com.adobe.xmp ,IDATxb?@& x߾}l@J''4$ #@l;ǣZ< W,, 1 $S ,X~c @*LK?.K 5P Dߡ +т} $+2Zh_Q )N8Hb64&hq & R,%ZHAM[ H @ tY&w^Nr0h~bZ +{8IENDB`ghp-import-2.1.0/docs/images/sprite_download.png000066400000000000000000000406371423377632400217250ustar00rootroot00000000000000PNG  IHDRtEXtSoftwareAdobe ImageReadyqe<"iTXtXML:com.adobe.xmp 8{>IDATx}iW̪R/ I. n٘YBÀacisػai`i1f3[693M4Ueٍe%UefdD̽y}edsr/w}wlCbZkD&Mb"3cEZG6őyYnj 8{epd4p$]rlqdV;\$Gq0͡܏o;aU&ļ[d 1@iRb{8 # ,Q;9%fcp&ܫiT?U "bT/1٤yUv3Ӳ9/svu][|m%l$`$l| rz Gg}s>d`W6yY} VYwDoM;q=Q'W/1a:YYb0Kk/0c 7X,.EId9q'Oĝe aVg@x3k8E1?v A ,nVǾQ;bU3#1@$=eNxiL=Ƶ1?o2qh!5'wnjf^b~iz<;$*Dd^< 4/{/&ŮYp}chTwo{x-Jգf 1XEbֽ]9/.[w9_nfc/Qq\L>~bLih: 0H$hX*@̝Iwl4?fncIq%=.$Nc}3޻ فOۦv.RgsgI^+N\-Gk խg jZK$as}) NzX\L{jG}Cix%Dk~ysf&@ cIfAp8$s͙`d=_ 0YZfv* :.ήs5-Aγa1?-lnH]Mm]/g6XڀI]RG\a8AuS]n*YC& Ĩ0mj/O /~pUY*lNФ;'Nw>A 8sH䟻~CxܝgQ,EFo50f7C'Etm/vރk-- TG7Z-HTs4 |#̊ȩ 2Պ|J/rgQs܅_x#iHDh=}ͥ}ܹ*8K 1ί E xIbD' ˠ׵,a#Q ק6t]PDNv&ǁFIҁ圸}\}M,jtzm;N9ap,:n/?C~>,=%}58ƦJ+X3Cׅ"cPp( F܏gN5mIf{шѪ;$fӥOXz ϘT2 s2;SEPf})(u懮n&iq&$+W%eNF[ ?.8Ȫu}BaE3 I#F~.x|!5G=pWH pe( MN2tq'u>ULq[n 9#%1%ZVJAZy(*P$_;U5ëR+~\ED Y|[#|7ϚU l;]ҫĝd繘 n,溤 P\fJj2dh>T KF~}N\:L#o>'=b0:i/gq 4n -*P`5 xVr&P~q)4KRZsw/P9zwnd thEzik`KB~J)w)rUIUB-Ykyz9<1Gbw)1C9|ʖӓ>uCKjY*WTP@Y]:2L)e%I[ ]}9+#|TVI83G'j!+H35Ǻ\22\ʈ.Dr+Ih۔8Q8kGoY%P'hȹ[ė܄4:&Kv4ģ\=me:& 8PuV,vv#%:i5wH|]`lZ֠..:lht<Q, @p+'H7Xkk}:7h}sn#C.5 =sˆsFع/&2wP|Cޏjڕ|hӣKO;IOl_mA#RGi|H5(FW ŢLtY y8P;,m.רtȄxgp<[9mfWlNShr!%w3I?&hIjeiuK4"Dlнܺ;|_ҸȂ, ,w3cǻ켟4Ϙlb@%pky @&*q>yA˜8!j P\; y9a(6;V7JܢX6]e Vd~CMBR?dqOj=4 ªqYun6nFNfZ..zHK4&4n"!uZ$ZЮFo= KfCphrۥ-oշAdP`U@PWy˃ AC=벵3 ;Dm"gG̞pFaa[oG;`@vr\DjֳҌ wq/ԁĴERt+ɺՙQ\6;q6JZ$&Ѕsh,ia/ PCCWLnku=xV{ո>:z*IR?2epAtkI8tVrw; Ɠ|3>U\H2<[UPà˗'b`$ɽ0w8|+'sdibVrd%A@2(Pu!SPZ*eek ߡ\jr޽V,:jyQ$adH42f<2[-<3dș*KNi2K0ZxnkUF-]\-p`{Mo,;I"re0 H<1Yf_Y@b ׉qeݴj7j<,H!m;g^ng R̴g:T(>[ۇcoH=B4,I3 ->mÊhYÐpd΃_c hк;ߏΛ6?]hD<}~wg̩ˌٲߘטZ e*p;Yw 7^?mGn6>c|y?|ګ%߽;9m׮P&*sřk"Ms:,ߺǘn7RvϿ3j&&T1ӝ)#b"Fsk;%I˛AΥ\Nog&>5H߿̘~ZM/Ä /Ȇ">VV|QiWn,u!ݲc6r˅ cdt-߇#MG^$(؂jKyx,ָ(]5md|s{w͇YCDnHsP `+8IX6Ɠ?|u~^󡭠Gk^V/tI$J('5mC(?9v/1/Ɲ8ye ޠӪb`Y'+Jj;%qJU窄ߑIfQ{m[5Z*!},^m|61!kHP!b3T[f76YtUЧWm'FlН{!ٺuټekYBq7ܼhzYb$V" [a^aR E'^m9~6j9e USȤuYвA(Zv,|7zڳӽj?=M(f}{]]m|o?|Q5 0L N-pJ PA+h",nO_.^A]Ji" >Ԕ+~h1y4m|SN|ԟ:q MZ\w<Y˿sx^?/vzT7dKٳA mU)Y5G㸡@6H!5}t*XUcf_ѾLluzuMv:&q*r^}w7BYn$^V T ~hawX! d2m(Z*2P+;.a!%|eNPWR5edU@PEA?6yFW/$sm59pU}rҳ߮1ەn vu9c7Օ[ݓ3f_v\i_s^:4'/~CY F$ft] g '(T |aYO ᛚLp۹}thY=z9R, r swSiErr ѽ8 > T):Yq`p3b]]`ވ̲{9.1p5~avD|`\j*2\M=:` oW2qE}*|y91(gI)+ţA \WV cZRW>xEovR۶t@Te_.ך>^WMؼ3Z4WGgZ59'7{ ^m֝N6kO}< ׭⛇!#+nPpV-*Ek$"Ddtp$NUƼSh9#7ߌ穩\"kSo._:r C hYTЌ02I[n(gu.A@QE/zBB}m8'MtjK @kN*%p_vORQ Q-sFM=Hv : $uTk5yzTI^I E|kgͽ #:fa S ozB##|7M[F V9jmevFqb~ݛqgFQ q'nX"I/+ooKXhJ_+aoupQ3G5sjy?dVvX|mն_}$=qkL|;KM"bKch I؏Xnݻ M0^WDyEfۿ5N)~OKQyfnpMYc \ZCW|1vsڝwmT]'ՆMٿ-2t4j@4uap(sǀd6*stȂWԅ,aZ.FaYh1@(񐠧Vg7AZx7 ko6*O&Va Fn=̤CHҵF"ӎ[yo%ߓ#)Fu:|uDaD2arq$WfUrѦn:74JJq4}.3gs 9Gt\bnDa!YŽ=q[sj'f<w;(8u ı9d"TAGŽ+xnaxlM^+OnڴիWޯ?•NډF>WgtijZWބ (#yF_ρ0j'/\Jj(Q|#皳^LbL}O$oK>W+<Ǣ%K\n <[Z{ |}GE[7o*l U1r ,±5w=s,JLCu& ,]t9r L@Ws lY".:U"\Q2抾`61 b5rz18>p[ȑDx1 ^rܓ?#ty˗?4Zrl@Ĝ0b z3Os =^=B{c/Vȸ]CB΅6a:%Q+THxp '|ɗ(83#%'.WtA,Z38;vxOc_w.8\YAÄXjz>6݂ܝ>,Ռ'x)ߕ/H _<#÷O?|?o2Ј/ ~hI1sYb>s6ZSSSυH63DJEq} ]333wsnklxE1MH}&tUގ0r-6\1svvV8no2]? x;Oxb>SO4aߏ2N%A0b|E֮]p|fJ]Mm*n& jI>Ss3?~bR}^0{&pv΁d#|u|,Xp9EX)>*1 ~CPt ">|O܁e{Ӽ}p{KJG";˖-Cޮp3>mo_x_]Tx{,J/! :p1`"`.)msHT#%nDr3?', (> -x;ȵH`K)"Osb0z ԁ=,Y q/cϞ=? u죃TD%BA?A329CWMr<)Fr2 0`;(\Dsݻw8.H(DNq?ǹ뉍0-ēS9%?s|﬷9LNC;\4==}.o_x%hsxGŊrDGr?4^%/ 3\5P8=ݓa[h4j 8 aԌg_071oR)]_rR iЍpF Kz(\g90|O"8!=4(eh܏˔P|?{.0|-eflp9!ܢC[SA} g||RhAv?f9cH">oC3J|mI1pY1;Oi~hz] "Q@/ <#]G!  (ιE/u?Jth)o.^C#Ĭ3sŌ_trC*Gom?M{I02r%2]@kJW@p89GFR+"nܔ3G2B/H堅^/Y^rWVJCn*V|dZ#|ƷYoM҈"֮04X2OAd_F,5CE="=)j8DokU/]$A:5qJ٦q)4xB6 :ڽ4XPxЬX?#|0+VJ5Q;eRiNy-/?zy "\fli\B8Ғ ztք";w8|3O(I}YJJrE>$"hQ.-ij0dt.7Rq$Ц|3-;4¡Oqe2Lr52d9X|\=ZRP̞% Z=w8|_/*72pBF1Fy$u3g/P- &@K^)<2d-G {ɖ_UF>n|~\TexSJ!-VrhFԻ/|J$:r<? #|÷ˁˌZQJ(M܂[| $MiPp!܃Z-i^JKD8:tY?ԎC>x`303(1Es Ntj /Eac<ZN(- =M99|ps@J7R~Rv)>1J쇯;&jTE[ .Ҁ֒5_)C ._KWUUE-;hvPFaμ-iGK/HknAZ֕,>g17ؒA&#g2%E=y=K08w(|;߾ZZ-h= Wő=-C2WZs_K29H RQhY `10#-zVD'$yUH - 0r%MjI:ԆHO,ʅG|CH燾?)Ռp\h]4>)$n$l <rD4A83r$ ߪĢ#o=8W|sbx=33„V0H]K:LW\|U\Z>~ы^d=\/b}~++Wݻw桇*ńX͈~/>=y}֟{|k{ߣZ\y[oլ^^7DXm K"t?2WU*(~*|JD_S`BuwY´\1rfZkR\ja_S.eĝ?CRpǪU[Kw$"|NR:yg'w6Ұ|_]0^k |?g\_]TW@{rrFrj YrrxCB$Z 9 E΁ʈ_yK^bM\4"pD%)/̸&>)sEWGTȍZW_]0=!rn\r/,g?k.Ba?CcOėDۋ6UxK<|q%VVhrUrzŲzV\_p<D_Wlr0p`DT/ vZ|1_r!9mV64^ٟM7?яC2^)[ #Z% NE U%! '&Phʍm _[Oi>jԗxֳe<IH#Rz^?~-x{}X/f3&P` %ra%@Y#X&! E%+H!;WUJ»2 $q+|9gh CCc 'V@RMtkWT[F!LN 5CvH\5BMtȪbߒRy饗V;y5x|0fj 4W;#D϶ 6Ԙm-!}h ALrTjrarx8Ԫh[^Y^%e4K3Y4Kn8ԉQ'G:`:P,K,+VI X+U-<[3"7TDNwho +?+4|*;m)dVeP'~*&ޗo(w-^8s/O~MXΒǷYahW/?sHC#Z)=`$>D M"L9ు믿>o* 50~b(dtdTM8z/@0r2'Z$X B+HЪWc=e8Q`g{-&>y9-Xd7h>/^#+hwuF7K_aҭe^-*7PYiX?._5R|ZVOQ!Pm3YE =OrOu`j[ɜp$w]zHDnÇKwr˛o߾>Bsh _w ezh"~z۶mbTD&` uvﭷFh ߁tb=Irf" #LHm5Ǒʚ6?,'+sbBD]78JN&J!q%ƞ⋮8T% ao6Yc\ХU^HEH [@ryԋ[г7Uxl9hgR&eR:ZZR-mjj[Ik_yӛdaPAo>uk!(R2qp_5^BPϕjQ $u- O[2Gz(l{mo{[iŇ,+y]|NE\ _Y~*!wV}ڐ67R93ٰ JKLM&}[܀@񭼤%Ͻ t"4E3IDROJ v"tASH-~*́#o &. 93;>@ e_Z4:h=>oUrq';dr<U9ڮD4lv|6755߁M1ѥCUɒ.<@[<\J>CU&Ʌ\lq,Η!qі1~~ TEc##| %X0*Gxay曖/_~;1.RVvan2BpDU+ %kĬ0 "AUwHlrd&rfλ:x]iҥws mF&2G5TVmڸx-zxЍ'%Fjk|j IIqe !:4ξ={+^ 7GFU6Α >' @rd4~yI') m>yqLBA'Gp~wHeL 34^L@"<%j_QA%NʑƗ{RF|67bLB g|Z36٣Gǭ1}9a`Ε@;1}?7´7燎'" Tuy *F12M?qX!>szϡX;:ʓKDOBjB$D,q2 #fyS׎[ 02^CIENDB`ghp-import-2.1.0/docs/index.html.tmpl000066400000000000000000000030271423377632400175150ustar00rootroot00000000000000 ghp-import - GitHub Pages import tool
View on GitHub

ghp-import

Easily import docs to your gh-pages branch.

Download this project as a .zip file Download this project as a tar.gz file
{body}
ghp-import-2.1.0/docs/style.css000066400000000000000000000165571423377632400164330ustar00rootroot00000000000000/******************************************************************************* Slate Theme for GitHub Pages by Jason Costello, @jsncostello *******************************************************************************/ @import url(pygment_trac.css); /******************************************************************************* MeyerWeb Reset *******************************************************************************/ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } ol, ul { list-style: none; } blockquote, q { } table { border-collapse: collapse; border-spacing: 0; } a:focus { outline: none; } /******************************************************************************* Theme Styles *******************************************************************************/ body { box-sizing: border-box; color:#373737; background: #212121; font-size: 16px; font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif; line-height: 1.5; -webkit-font-smoothing: antialiased; } h1, h2, h3, h4, h5, h6 { margin: 10px 0; font-weight: 700; color:#222222; font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif; letter-spacing: -1px; } h1 { font-size: 36px; font-weight: 700; } h2 { padding-bottom: 10px; font-size: 32px; background: url('../images/bg_hr.png') repeat-x bottom; } h3 { font-size: 24px; } h4 { font-size: 21px; } h5 { font-size: 18px; } h6 { font-size: 16px; } p { margin: 10px 0 15px 0; } footer p { color: #f2f2f2; } a { text-decoration: none; color: #007edf; text-shadow: none; transition: color 0.5s ease; transition: text-shadow 0.5s ease; -webkit-transition: color 0.5s ease; -webkit-transition: text-shadow 0.5s ease; -moz-transition: color 0.5s ease; -moz-transition: text-shadow 0.5s ease; -o-transition: color 0.5s ease; -o-transition: text-shadow 0.5s ease; -ms-transition: color 0.5s ease; -ms-transition: text-shadow 0.5s ease; } #main_content a:hover { color: #0069ba; text-shadow: #0090ff 0px 0px 2px; } footer a:hover { color: #43adff; text-shadow: #0090ff 0px 0px 2px; } em { font-style: italic; } strong { font-weight: bold; } img { position: relative; margin: 0 auto; max-width: 739px; padding: 5px; margin: 10px 0 10px 0; border: 1px solid #ebebeb; box-shadow: 0 0 5px #ebebeb; -webkit-box-shadow: 0 0 5px #ebebeb; -moz-box-shadow: 0 0 5px #ebebeb; -o-box-shadow: 0 0 5px #ebebeb; -ms-box-shadow: 0 0 5px #ebebeb; } pre, code { width: 100%; color: #222; background-color: #fff; font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; font-size: 14px; border-radius: 2px; -moz-border-radius: 2px; -webkit-border-radius: 2px; } pre { width: 100%; padding: 10px; box-shadow: 0 0 10px rgba(0,0,0,.1); overflow: auto; } code { padding: 3px; margin: 0 3px; box-shadow: 0 0 10px rgba(0,0,0,.1); } pre code { display: block; box-shadow: none; } blockquote { color: #666; margin-bottom: 20px; padding: 0 0 0 20px; border-left: 3px solid #bbb; } ul, ol, dl { margin-bottom: 15px } ul li { list-style: inside; padding-left: 20px; } ol li { list-style: decimal inside; padding-left: 20px; } dl dt { font-weight: bold; } dl dd { padding-left: 20px; font-style: italic; } dl p { padding-left: 20px; font-style: italic; } hr { height: 1px; margin-bottom: 5px; border: none; background: url('../images/bg_hr.png') repeat-x center; } table { border: 1px solid #373737; margin-bottom: 20px; text-align: left; } th { font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif; padding: 10px; background: #373737; color: #fff; } td { padding: 10px; border: 1px solid #373737; } form { background: #f2f2f2; padding: 20px; } /******************************************************************************* Full-Width Styles *******************************************************************************/ .outer { width: 100%; } .inner { position: relative; max-width: 640px; padding: 20px 10px; margin: 0 auto; } #forkme_banner { display: block; position: absolute; top:0; right: 10px; z-index: 10; padding: 10px 50px 10px 10px; color: #fff; background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%; font-weight: 700; box-shadow: 0 0 10px rgba(0,0,0,.5); border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; } #header_wrap { background: #212121; background: -moz-linear-gradient(top, #373737, #212121); background: -webkit-linear-gradient(top, #373737, #212121); background: -ms-linear-gradient(top, #373737, #212121); background: -o-linear-gradient(top, #373737, #212121); background: linear-gradient(top, #373737, #212121); } #header_wrap .inner { padding: 50px 10px 30px 10px; } #project_title { margin: 0; color: #fff; font-size: 42px; font-weight: 700; text-shadow: #111 0px 0px 10px; } #project_tagline { color: #fff; font-size: 24px; font-weight: 300; background: none; text-shadow: #111 0px 0px 10px; } #downloads { position: absolute; width: 210px; z-index: 10; bottom: -40px; right: 0; height: 70px; background: url('../images/icon_download.png') no-repeat 0% 90%; } .zip_download_link { display: block; float: right; width: 90px; height:70px; text-indent: -5000px; overflow: hidden; background: url(../images/sprite_download.png) no-repeat bottom left; } .tar_download_link { display: block; float: right; width: 90px; height:70px; text-indent: -5000px; overflow: hidden; background: url(../images/sprite_download.png) no-repeat bottom right; margin-left: 10px; } .zip_download_link:hover { background: url(../images/sprite_download.png) no-repeat top left; } .tar_download_link:hover { background: url(../images/sprite_download.png) no-repeat top right; } #main_content_wrap { background: #f2f2f2; border-top: 1px solid #111; border-bottom: 1px solid #111; } #main_content { padding-top: 40px; } #footer_wrap { background: #212121; } /******************************************************************************* Small Device Styles *******************************************************************************/ @media screen and (max-width: 480px) { body { font-size:14px; } #downloads { display: none; } .inner { min-width: 320px; max-width: 480px; } #project_title { font-size: 32px; } h1 { font-size: 28px; } h2 { font-size: 24px; } h3 { font-size: 21px; } h4 { font-size: 18px; } h5 { font-size: 14px; } h6 { font-size: 12px; } code, pre { min-width: 320px; max-width: 480px; font-size: 11px; } } ghp-import-2.1.0/docs/test-ϋnicodé,fîleñämӛ.html000066400000000000000000000001321423377632400256310ustar00rootroot00000000000000 ghp-import-2.1.0/ghp_import.py000077500000000000000000000220221423377632400163360ustar00rootroot00000000000000#! /usr/bin/env python import errno import os import subprocess as sp import sys import time from dateutil import tz from datetime import datetime try: from shlex import quote except ImportError: from pipes import quote __all__ = ['ghp_import'] __version__ = "2.1.0" class GhpError(Exception): def __init__(self, message): self.message = message if sys.version_info[0] == 3: def enc(text): if isinstance(text, bytes): return text return text.encode() def dec(text): if isinstance(text, bytes): return text.decode('utf-8') return text def write(pipe, data): try: pipe.stdin.write(data) except IOError as e: if e.errno != errno.EPIPE: raise else: def enc(text): if isinstance(text, unicode): # noqa F821 return text.encode('utf-8') return text def dec(text): if isinstance(text, unicode): # noqa F821 return text return text.decode('utf-8') def write(pipe, data): pipe.stdin.write(data) class Git(object): def __init__(self, use_shell=False): self.use_shell = use_shell self.cmd = None self.pipe = None self.stderr = None self.stdout = None def check_repo(self): if self.call('rev-parse') != 0: error = self.stderr if not error: error = "Unknown Git error" error = dec(error) if error.startswith("fatal: "): error = error[len("fatal: "):] raise GhpError(error) def try_rebase(self, remote, branch, no_history=False): rc = self.call('rev-list', '--max-count=1', '%s/%s' % (remote, branch)) if rc != 0: return True rev = dec(self.stdout.strip()) if no_history: rc = self.call('update-ref', '-d', 'refs/heads/%s' % branch) else: rc = self.call('update-ref', 'refs/heads/%s' % branch, rev) if rc != 0: return False return True def get_config(self, key): self.call('config', key) return self.stdout.strip() def get_prev_commit(self, branch): rc = self.call('rev-list', '--max-count=1', branch, '--') if rc != 0: return None return dec(self.stdout).strip() def open(self, *args, **kwargs): if self.use_shell: self.cmd = 'git ' + ' '.join(map(quote, args)) else: self.cmd = ['git'] + list(args) if sys.version_info >= (3, 2, 0): kwargs['universal_newlines'] = False for k in 'stdin stdout stderr'.split(): kwargs.setdefault(k, sp.PIPE) kwargs['shell'] = self.use_shell self.pipe = sp.Popen(self.cmd, **kwargs) return self.pipe def call(self, *args, **kwargs): self.open(*args, **kwargs) (self.stdout, self.stderr) = self.pipe.communicate() return self.pipe.wait() def check_call(self, *args, **kwargs): kwargs["shell"] = self.use_shell sp.check_call(['git'] + list(args), **kwargs) def mk_when(timestamp=None): if timestamp is None: timestamp = int(time.time()) currtz = datetime.now(tz.tzlocal()).strftime('%z') return "%s %s" % (timestamp, currtz) def start_commit(pipe, git, branch, message, prefix=None): uname = os.getenv('GIT_COMMITTER_NAME', dec(git.get_config('user.name'))) email = os.getenv('GIT_COMMITTER_EMAIL', dec(git.get_config('user.email'))) when = os.getenv('GIT_COMMITTER_DATE', mk_when()) write(pipe, enc('commit refs/heads/%s\n' % branch)) write(pipe, enc('committer %s <%s> %s\n' % (uname, email, when))) write(pipe, enc('data %d\n%s\n' % (len(enc(message)), message))) head = git.get_prev_commit(branch) if head: write(pipe, enc('from %s\n' % head)) if prefix: write(pipe, enc('D %s\n' % prefix)) else: write(pipe, enc('deleteall\n')) def add_file(pipe, srcpath, tgtpath): with open(srcpath, "rb") as handle: if os.access(srcpath, os.X_OK): write(pipe, enc('M 100755 inline %s\n' % tgtpath)) else: write(pipe, enc('M 100644 inline %s\n' % tgtpath)) data = handle.read() write(pipe, enc('data %d\n' % len(data))) write(pipe, enc(data)) write(pipe, enc('\n')) def add_nojekyll(pipe, prefix=None): if prefix: fpath = os.path.join(prefix, '.nojekyll') else: fpath = '.nojekyll' write(pipe, enc('M 100644 inline %s\n' % fpath)) write(pipe, enc('data 0\n')) write(pipe, enc('\n')) def add_cname(pipe, cname): write(pipe, enc('M 100644 inline CNAME\n')) write(pipe, enc('data %d\n%s\n' % (len(enc(cname)), cname))) def gitpath(fname): norm = os.path.normpath(fname) return "/".join(norm.split(os.path.sep)) def run_import(git, srcdir, **opts): srcdir = dec(srcdir) pipe = git.open('fast-import', '--date-format=rfc2822', '--quiet', stdin=sp.PIPE, stdout=None, stderr=None) start_commit(pipe, git, opts['branch'], opts['mesg'], opts['prefix']) for path, _, fnames in os.walk(srcdir, followlinks=opts['followlinks']): for fn in fnames: fpath = os.path.join(path, fn) gpath = gitpath(os.path.relpath(fpath, start=srcdir)) if opts['prefix']: gpath = os.path.join(opts['prefix'], gpath) add_file(pipe, fpath, gpath) if opts['nojekyll']: add_nojekyll(pipe, opts['prefix']) if opts['cname'] is not None: add_cname(pipe, opts['cname']) write(pipe, enc('\n')) pipe.stdin.close() if pipe.wait() != 0: sys.stdout.write(enc("Failed to process commit.\n")) def options(): return [ (('-n', '--no-jekyll'), dict( dest='nojekyll', default=False, action="store_true", help='Include a .nojekyll file in the branch.', )), (('-c', '--cname'), dict( dest='cname', default=None, help='Write a CNAME file with the given CNAME.', )), (('-m', '--message'), dict( dest='mesg', default='Update documentation', help='The commit message to use on the target branch.', )), (('-p', '--push'), dict( dest='push', default=False, action='store_true', help='Push the branch to origin/{branch} after committing.', )), (('-x', '--prefix'), dict( dest='prefix', default=None, help='The prefix to add to each file that gets pushed to the ' 'remote. Only files below this prefix will be cleared ' 'out. [%(default)s]', )), (('-f', '--force'), dict( dest='force', default=False, action='store_true', help='Force the push to the repository.', )), (('-o', '--no-history'), dict( dest='no_history', default=False, action='store_true', help='Force new commit without parent history.', )), (('-r', '--remote'), dict( dest='remote', default='origin', help='The name of the remote to push to. [%(default)s]', )), (('-b', '--branch'), dict( dest='branch', default='gh-pages', help='Name of the branch to write to. [%(default)s]', )), (('-s', '--shell'), dict( dest='use_shell', default=False, action='store_true', help='Use the shell when invoking Git. [%(default)s]', )), (('-l', '--follow-links'), dict( dest='followlinks', default=False, action='store_true', help='Follow symlinks when adding files. [%(default)s]', )) ] def ghp_import(srcdir, **kwargs): if not os.path.isdir(srcdir): raise GhpError("Not a directory: %s" % srcdir) opts = {kwargs["dest"]: kwargs["default"] for _, kwargs in options()} opts.update(kwargs) git = Git(use_shell=opts['use_shell']) git.check_repo() if not git.try_rebase(opts['remote'], opts['branch'], opts['no_history']): raise GhpError("Failed to rebase %s branch." % opts['branch']) run_import(git, srcdir, **opts) if opts['push']: if opts['force'] or opts['no_history']: git.check_call('push', opts['remote'], opts['branch'], '--force') else: git.check_call('push', opts['remote'], opts['branch']) def main(): from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument("--version", action="version", version=__version__) parser.add_argument("directory") for args, kwargs in options(): parser.add_argument(*args, **kwargs) args = parser.parse_args().__dict__ try: ghp_import(args.pop("directory"), **args) except GhpError as e: parser.error(e.message) if __name__ == '__main__': main() ghp-import-2.1.0/setup.py000066400000000000000000000032751423377632400153340ustar00rootroot00000000000000import io import os import re try: from setuptools import setup except ImportError: from distutils.core import setup HERE = os.path.dirname(__file__) LONG_DESC_PATH = os.path.join(HERE, "README.md") LONG_DESC = io.open(LONG_DESC_PATH, encoding="utf-8").read() with io.open(os.path.join(HERE, "ghp_import.py"), encoding="utf-8") as fobj: for line in fobj: match = re.match( r"^__version__\s*=\s*['\"](?P[\d.]+)['\"]$", line.strip() ) if match: VERSION = match.group("version") break setup( name="ghp-import", version=VERSION, description="Copy your docs directly to the gh-pages branch.", long_description=LONG_DESC, long_description_content_type="text/markdown", author="Paul Joseph Davis", author_email="paul.joseph.davis@gmail.com", license="Apache Software License", url="https://github.com/c-w/ghp-import", zip_safe=False, install_requires=[ "python-dateutil>=2.8.1", ], extras_require={ "dev": [ "twine", "markdown", "flake8", "wheel", ], }, classifiers=[ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: Apache Software License", "Intended Audience :: Developers", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", ], py_modules=["ghp_import"], entry_points={ "console_scripts": [ "ghp-import = ghp_import:main", ], } )