Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

나도 할 수 있다 오픈소스

476 views

Published on

PyCON KR 2018에서 발표한 슬라이드입니다.

Published in: Software
  • Be the first to comment

나도 할 수 있다 오픈소스

  1. 1. 나도 할 수 있다 오픈소스! setup.py에서 PyPI까지 강효준 Kang Hyojun
  2. 2. 오픈 소스 시작하기             .           , 뭔가 복잡하고 어려워보인다.  PR    리뷰하기 어렵다.
  3. 3. 오픈 소스 시작하기                 . setup.py     ,        .         ..  achimnol/pycon apac2018 packaging workshop           ,                .
  4. 4. pyleftpad를 PyPI에 배포해봅시다 https://github.com/admire93/pyleftpad $ pip install pyleftpad $ leftpad -l 5 -f 0 foo 00foo
  5. 5. pyleftpad를 PyPI에 배포해봅시다 예제 함수 def leftpad(    source: Union[str, int],    padded: int,    fill_value: Union[str, int]  )  > str: ... return result 디렉토리 구조 /pyleftpad /leftpad __init__.py func.py cli.py setup.py setup.cfg README.md CHANGES.md CONTRIBUTING.md LICENSE /docs /tests .travis.yml
  6. 6. setup.py 작성 from setuptools import setup setup( name='pyleftpad', version='0.1.0', ... )
  7. 7. 천리 길도 setup.py 부터 setuptools      /        distutils → setuptools Distribute Distutils2 scikit build
  8. 8. setuptools.setup                                      
  9. 9. setuptools.setup Metadata name ,  version ,  url ,  download_url ,  project_urls ,  author ,  author_email , maintainer ,  maintainer_email ,  classifiers ,  license ,  description , long_description ,  long_description_content_type ,  keywords ,  platforms ,  provides , requires ,  obsoletes Options zip_safe ,  setup_requires ,  install_requires ,  extras_require ,  python_requires , entry_points ,  use_2to3 ,  use_2to3_fixers ,  use2to3_exclude_fixers , convert_2to3_doctests ,  scripts ,  eager_resources ,  dependency_links , tests_require ,  include_package_data ,  packages ,  package_dir ,  package_data , exclude_package_data ,  namespace_packages ,  py_modules ,
  10. 10. setuptools.setup 인자   :  name     :  author , author_email setup( name='pyleftpad', author='Kang Hyojun', author_email='foo' '@' 'gmail.com' )
  11. 11. setuptools.setup 인자   :  name     :  author , author_email   :  description , long_description         . long_description_content_type setup( description='Python leftpad', long_description=readme(), long_description_content_type= 'text/markdown', )
  12. 12. setuptools.setup 인자   :  name     :  author , author_email   :  description , long_description         . long_description_content_type def readme()  > str: with open('./README.md') as f: return f.read()
  13. 13. setuptools.setup 인자   :  name     :  author , author_email   :  description , long_description         . long_description_content_type :  license : https://choosealicense.com/
  14. 14. 지금까지 채워넣은 setuptools.setup setup( name='pyleftpad', author='Kang Hyojun', author_email='iam.kanghyojun' '@' 'gmail.com', description='Python leftpad', long_description=readme(), license='GPL', )
  15. 15. setuptools.setup 인자     version             :  url setup( version='0.1.0', url='https://github.com/admire93/' 'pyleftpad', )
  16. 16. PEP 396 — Module Version Numbers           ,  __version__       . [N ]N(.N)*[{a|b|rc}N][.postN][.devN] — PEP 440   . VCS             . setup.py   version       __version__     ,      .
  17. 17. PEP 396 — Module Version Numbers from leftpad import __version__ setup( ... version=__version__, ... )
  18. 18. PEP 396 — Module Version Numbers __init__.py           ,          constant       setup.py     :mod:`leftpad`   Leftpad  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  from .constant import DEFAULT_PADDING __version__ = '0.1.0'
  19. 19. PEP 396 — Module Version Numbers ast     __init__.py     __version__         import ast def get_version(): filename = 'leftpad/__init__.py' with open(filename, 'r') as f: tree = ast.parse(f.read(), filename) for node in tree.body: if (isinstance(node, ast.Assign) and node.targets[0].id == '__version__'): return ast.literal_eval(node.value) else: raise ValueError('could not find __version__')
  20. 20. setuptools.setup 인자 (2)   :  packages  vs  py_modules py_modules :        ,            . packages :            . setuptools.find_packages()         . setup( ... # or use find_packages() py_modules='leftpad.py', classifiers=[ ... ], ... )
  21. 21. setuptools.setup 인자 (2)   :  classifiers                PyPI      https://pypi.org/pypi? %3Aaction=list_classifiers
  22. 22. setuptools.setup 인자 (2)   :  classifiers                PyPI      https://pypi.org/pypi? %3Aaction=list_classifiers  PyPI       
  23. 23. setuptools.setup 인자 (3)   :  entry_ponits Dynamic Discovery       CLI         setup( ..., entry_points={ 'console_scripts': [ 'leftpad=leftpad:cli' ], }, ... )
  24. 24. setuptools.setup 인자 (3)   :  entry_ponits Dynamic Discovery       CLI         $ pip install leftpad $ leftpad 'foo'   'foo' $ pip install httpie $ http get http://example.com ...
  25. 25. setuptools.setup 인자 (4) 패키지 의존성 관리 install_requires :      tests_require :        extras_require :      install_requires=[ 'flask >= 1.0.2, < 1.1', 'click == 6.7', ], tests_require=['pytest', 'flake'], extras_require={ 'crypto': ['crypto'], ... },
  26. 26. 패키지 의존성 관리 tests_require     extras_require               $ pip install pyleftpad[crypto]
  27. 27. setup.cfg 사용하기   setup.cfg           setuptools 30.3.0 (2016  12  8   )     
  28. 28. setup.cfg 사용하기 예제 [metadata] name = my_package version = attr: src.VERSION ... classifiers = Framework :: Django Programming Language :: Python :: 3 Programming Language :: Python :: 3.5 [options] packages = find: scripts = bin/first.py bin/second.py install_requires = requests importlib; python_version == 2.6
  29. 29. setup.cfg 사용하기 pyleftpad에 적용 [metadata] name = pyleftpad version = attr: leftpad.__version__ description = Python leftpad long_description = file: README.md long_description_content_type = text/markdown keywords = leftpad, pyleftpad license = GPLv3 classifiers = License :: OSI Approved :: GNU General Public License v3 (GPLv3) Topic :: Utilities Development Status :: 3 - Alpha Environment :: Console [options] packages = find: [options.entry_points] console_scripts = leftpad = leftpad.cli:main
  30. 30. PyPI Python Package Index https://pypi.org/
  31. 31. PyPI에 가입하기 https://pypi.org/account/register/ PyPI                               .
  32. 32. PyPI 설정 ~/.pypirc     repository   password       password    CLI       . [distutils] index-servers = pypi [pypi] repository:    https://upload.pypi.org/legacy/ username: <username> password: <password>
  33. 33. PyPI에 업로드하기 $ python setup.py sdist upload              
  34. 34. Wheel로 업로드하기 $ pip install wheel $ python setup.py sdist bdist_wheel upload
  35. 35. Wheel? Wheels are the new standard of Python distribution and are intended to replace eggs. Support is offered in pip >= 1.4 and setuptools >= 0.8. egg           C                    CI                   setup.py    
  36. 36. Wheel VS Egg https://packaging.python.org/discussions/wheel vs egg/ Wheel  PEP 0427  Egg   . Egg           , Wheel     Wheel  .pyc     
  37. 37. Wheel로 업로드 완료  .whl   PyPI        . { }-{ }-{ }.whl
  38. 38. twine                PyPI  HTTPS     keyring         
  39. 39. twine             twine       $ python setup.py sdist bdist_wheel $ twine upload dist/*
  40. 40. twine             twine           $ twine upload --repository-url https://test.pypi.org/legacy/ dist/*
  41. 41. 협업하기     ,    (   )                             ,         
  42. 42. 기여 가이드하기 GitHub             Setting guidelines for repository contributors CONTRIBUTING           : atom     CoC           .
  43. 43. 기여 가이드하기 GitHub             Setting guidelines for repository contributors CONTRIBUTING           : atom     CoC             .
  44. 44. 풀 리퀘스트 템플릿 이용하기 pull_request_template.md      PR      PR           ## PR을 올리기전에.. , .  [ ] diff [     ][google test review] .  [ ] / . ## tl;dr ... [google test review]: https://testing.googleblog.com/2017/06/code health too many comments on your.h
  45. 45. 풀 리퀘스트 템플릿 이용하기                            
  46. 46. 변경 기록 항상 적기                           (Changelog)  CI            
  47. 47. 변경 기록 항상 적기 if git show --format=%B --quiet $TRAVIS_PULL_REQUEST_SHA | grep '[changelog skip]' > /dev/null; then echo Skip changelog checker... elif [[ $TRAVIS_TAG != ]]; then ! grep -i to be released CHANGES.md else [[ $TRAVIS_COMMIT_RANGE = ]] || [[ $(git diff  name only  $TRAVIS_COMMIT_RANGE  | grep CHANGES.md) != ]] fi
  48. 48. 귀찮은 일 미루기 CI  (CircleCI   TravisCI)  git      GitHub  deploy:   provider: releases   api_key: GITHUB OAUTH TOKEN   file: FILE TO UPLOAD   skip_cleanup: true   on:     tags: true
  49. 49. 귀찮은 일 미루기 CI  (CircleCI   TravisCI)  git      PyPI       deploy:   provider: pypi   user: ...   password: ...   on:     tags: true
  50. 50. README에 배지 달기 CI, readthedocs, code coverage                          .    
  51. 51. README에 배지 달기
  52. 52. GitHub으로 코드 관리하기       close closes closed fix fixes fixed resolve resolves resolved
  53. 53. 매장과 고객을 세련되게 연결하다 recruit@spoqa.com
  54. 54. 감사합니다 질문있으신가요? iam.kanghyojun(at)gmail.com kanghyojun.org

×