From 8383971fbb4298e773233b6a6a00b4c25acfe4f4 Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Sat, 30 Oct 2021 09:25:12 -0700 Subject: [PATCH 01/35] Ignore OSX-generated files --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index e646a076d..8c96562ec 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,8 @@ target/ # PyEnv .python-version + +# OSX +.DS_Store +.AppleDouble +.LSOverride From 53b3f14bd5481cdfab779688cf02029d4e6c013f Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Sat, 30 Oct 2021 10:27:31 -0700 Subject: [PATCH 02/35] Markdown corrections: - Name corrections for @audreyfeldroy and @pydanny - Run Prettier on Markdown files --- AUTHORS.md | 323 ++++++++++++++++++++++++++--------------------------- LICENSE | 2 +- README.md | 184 +++++++++++++++--------------- setup.cfg | 4 +- 4 files changed, 256 insertions(+), 257 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index d991d54fa..2f951cdd0 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -2,171 +2,170 @@ ## Development Leads -* Audrey Feldroy ([@audreyfeldroy](https://github.com/audreyfeldroy)) -* Daniel Feldroy ([@pydanny](https://github.com/pydanny)) -* Raphael Pierzina ([@hackebrot](https://github.com/hackebrot)) - +- Audrey Roy Greenfeld ([@audreyfeldroy](https://github.com/audreyfeldroy)) +- Daniel Roy Greenfeld ([@pydanny](https://github.com/pydanny)) +- Raphael Pierzina ([@hackebrot](https://github.com/hackebrot)) ## Core Committers -* Michael Joseph ([@michaeljoseph](https://github.com/michaeljoseph)) -* Paul Moore ([@pfmoore](https://github.com/pfmoore)) -* Andrey Shpak ([@insspb](https://github.com/insspb)) -* Sorin Sbarnea ([@ssbarnea](https://github.com/ssbarnea)) -* Fábio C. Barrionuevo da Luz ([@luzfcb](https://github.com/luzfcb)) -* Simone Basso ([@simobasso](https://github.com/simobasso)) +- Michael Joseph ([@michaeljoseph](https://github.com/michaeljoseph)) +- Paul Moore ([@pfmoore](https://github.com/pfmoore)) +- Andrey Shpak ([@insspb](https://github.com/insspb)) +- Sorin Sbarnea ([@ssbarnea](https://github.com/ssbarnea)) +- Fábio C. Barrionuevo da Luz ([@luzfcb](https://github.com/luzfcb)) +- Simone Basso ([@simobasso](https://github.com/simobasso)) ## Contributors -* Steven Loria ([@sloria](https://github.com/sloria)) -* Goran Peretin ([@gperetin](https://github.com/gperetin)) -* Hamish Downer ([@foobacca](https://github.com/foobacca)) -* Thomas Orozco ([@krallin](https://github.com/krallin)) -* Jindrich Smitka ([@s-m-i-t-a](https://github.com/s-m-i-t-a)) -* Benjamin Schwarze ([@benjixx](https://github.com/benjixx)) -* Raphi ([@raphigaziano](https://github.com/raphigaziano)) -* Thomas Chiroux ([@ThomasChiroux](https://github.com/ThomasChiroux)) -* Sergi Almacellas Abellana ([@pokoli](https://github.com/pokoli)) -* Alex Gaynor ([@alex](https://github.com/alex)) -* Rolo ([@rolo](https://github.com/rolo)) -* Pablo ([@oubiga](https://github.com/oubiga)) -* Bruno Rocha ([@rochacbruno](https://github.com/rochacbruno)) -* Alexander Artemenko ([@svetlyak40wt](https://github.com/svetlyak40wt)) -* Mahmoud Abdelkader ([@mahmoudimus](https://github.com/mahmoudimus)) -* Leonardo Borges Avelino ([@lborgav](https://github.com/lborgav)) -* Chris Trotman ([@solarnz](https://github.com/solarnz)) -* Rolf ([@relekang](https://github.com/relekang)) -* Noah Kantrowitz ([@coderanger](https://github.com/coderanger)) -* Vincent Bernat ([@vincentbernat](https://github.com/vincentbernat)) -* Germán Moya ([@pbacterio](https://github.com/pbacterio)) -* Ned Batchelder ([@nedbat](https://github.com/nedbat)) -* Dave Dash ([@davedash](https://github.com/davedash)) -* Johan Charpentier ([@cyberj](https://github.com/cyberj)) -* Éric Araujo ([@merwok](https://github.com/merwok)) -* saxix ([@saxix](https://github.com/saxix)) -* Tzu-ping Chung ([@uranusjr](https://github.com/uranusjr)) -* Caleb Hattingh ([@cjrh](https://github.com/cjrh)) -* Flavio Curella ([@fcurella](https://github.com/fcurella)) -* Adam Venturella ([@aventurella](https://github.com/aventurella)) -* Monty Taylor ([@emonty](https://github.com/emonty)) -* schacki ([@schacki](https://github.com/schacki)) -* Ryan Olson ([@ryanolson](https://github.com/ryanolson)) -* Trey Hunner ([@treyhunner](https://github.com/treyhunner)) -* Russell Keith-Magee ([@freakboy3742](https://github.com/freakboy3742)) -* Mishbah Razzaque ([@mishbahr](https://github.com/mishbahr)) -* Robin Andeer ([@robinandeer](https://github.com/robinandeer)) -* Rachel Sanders ([@trustrachel](https://github.com/trustrachel)) -* Rémy Hubscher ([@Natim](https://github.com/Natim)) -* Dino Petron3 ([@dinopetrone](https://github.com/dinopetrone)) -* Peter Inglesby ([@inglesp](https://github.com/inglesp)) -* Ramiro Batista da Luz ([@ramiroluz](https://github.com/ramiroluz)) -* Omer Katz ([@thedrow](https://github.com/thedrow)) -* lord63 ([@lord63](https://github.com/lord63)) -* Randy Syring ([@rsyring](https://github.com/rsyring)) -* Mark Jones ([@mark0978](https://github.com/mark0978)) -* Marc Abramowitz ([@msabramo](https://github.com/msabramo)) -* Lucian Ursu ([@LucianU](https://github.com/LucianU)) -* Osvaldo Santana Neto ([@osantana](https://github.com/osantana)) -* Matthias84 ([@Matthias84](https://github.com/Matthias84)) -* Simeon Visser ([@svisser](https://github.com/svisser)) -* Guruprasad ([@lgp171188](https://github.com/lgp171188)) -* Charles-Axel Dein ([@charlax](https://github.com/charlax)) -* Diego Garcia ([@drgarcia1986](https://github.com/drgarcia1986)) -* maiksensi ([@maiksensi](https://github.com/maiksensi)) -* Andrew Conti ([@agconti](https://github.com/agconti)) -* Valentin Lab ([@vaab](https://github.com/vaab)) -* Ilja Bauer ([@iljabauer](https://github.com/iljabauer)) -* Elias Dorneles ([@eliasdorneles](https://github.com/eliasdorneles)) -* Matias Saguir ([@mativs](https://github.com/mativs)) -* Johannes ([@johtso](https://github.com/johtso)) -* macrotim ([@macrotim](https://github.com/macrotim)) -* Will McGinnis ([@wdm0006](https://github.com/wdm0006)) -* Cédric Krier ([@cedk](https://github.com/cedk)) -* Tim Osborn ([@ptim](https://github.com/ptim)) -* Aaron Gallagher ([@habnabit](https://github.com/habnabit)) -* mozillazg ([@mozillazg](https://github.com/mozillazg)) -* Joachim Jablon ([@ewjoachim](https://github.com/ewjoachim)) -* Andrew Ittner ([@tephyr](https://github.com/tephyr)) -* Diane DeMers Chen ([@purplediane](https://github.com/purplediane)) -* zzzirk ([@zzzirk](https://github.com/zzzirk)) -* Carol Willing ([@willingc](https://github.com/willingc)) -* phoebebauer ([@phoebebauer](https://github.com/phoebebauer)) -* Adam Chainz ([@adamchainz](https://github.com/adamchainz)) -* Sulé ([@suledev](https://github.com/suledev)) -* Evan Palmer ([@palmerev](https://github.com/palmerev)) -* Bruce Eckel ([@BruceEckel](https://github.com/BruceEckel)) -* Robert Lyon ([@ivanlyon](https://github.com/ivanlyon)) -* Terry Bates ([@terryjbates](https://github.com/terryjbates)) -* Brett Cannon ([@brettcannon](https://github.com/brettcannon)) -* Michael Warkentin ([@mwarkentin](https://github.com/mwarkentin)) -* Bartłomiej Kurzeja ([@B3QL](https://github.com/B3QL)) -* Thomas O'Donnell ([@andytom](https://github.com/andytom)) -* Jeremy Carbaugh ([@jcarbaugh](https://github.com/jcarbaugh)) -* Nathan Cheung ([@cheungnj](https://github.com/cheungnj)) -* Abdó Roig-Maranges ([@aroig](https://github.com/aroig)) -* Steve Piercy ([@stevepiercy](https://github.com/stevepiercy)) -* Corey ([@coreysnyder04](https://github.com/coreysnyder04)) -* Dmitry Evstratov ([@devstrat](https://github.com/devstrat)) -* Eyal Levin ([@eyalev](https://github.com/eyalev)) -* mathagician ([@mathagician](https://github.com/mathagician)) -* Guillaume Gelin ([@ramnes](https://github.com/ramnes)) -* @delirious-lettuce ([@delirious-lettuce](https://github.com/delirious-lettuce)) -* Gasper Vozel ([@karantan](https://github.com/karantan)) -* Joshua Carp ([@jmcarp](https://github.com/jmcarp)) -* @meahow ([@meahow](https://github.com/meahow)) -* Andrea Grandi ([@andreagrandi](https://github.com/andreagrandi)) -* Issa Jubril ([@jubrilissa](https://github.com/jubrilissa)) -* Nytiennzo Madooray ([@Nythiennzo](https://github.com/Nythiennzo)) -* Erik Bachorski ([@dornheimer](https://github.com/dornheimer)) -* cclauss ([@cclauss](https://github.com/cclauss)) -* Andy Craze ([@accraze](https://github.com/accraze)) -* Anthony Sottile ([@asottile](https://github.com/asottile)) -* Jonathan Sick ([@jonathansick](https://github.com/jonathansick)) -* Hugo ([@hugovk](https://github.com/hugovk)) -* Min ho Kim ([@minho42](https://github.com/minho42)) -* Ryan Ly ([@rly](https://github.com/rly)) -* Akintola Rahmat ([@mihrab34](https://github.com/mihrab34)) -* Jai Ram Rideout ([@jairideout](https://github.com/jairideout)) -* Diego Carrasco Gubernatis ([@dacog](https://github.com/dacog)) -* Wagner Negrão ([@wagnernegrao](https://github.com/wagnernegrao)) -* Josh Barnes ([@jcb91](https://github.com/jcb91)) -* Nikita Sobolev ([@sobolevn](https://github.com/sobolevn)) -* Matt Stibbs ([@mattstibbs](https://github.com/mattstibbs)) -* MinchinWeb ([@MinchinWeb](https://github.com/MinchinWeb)) -* kishan ([@kishan](https://github.com/kishan3)) -* tonytheleg ([@tonytheleg](https://github.com/tonytheleg)) -* Roman Hartmann ([@RomHartmann](https://github.com/RomHartmann)) -* DSEnvel ([@DSEnvel](https://github.com/DSEnvel)) -* kishan ([@kishan](https://github.com/kishan3)) -* Bruno Alla ([@browniebroke](https://github.com/browniebroke)) -* nicain ([@nicain](https://github.com/nicain)) -* Carsten Rösnick-Neugebauer ([@croesnick](https://github.com/croesnick)) -* igorbasko01 ([@igorbasko01](https://github.com/igorbasko01)) -* Dan Booth Dev ([@DanBoothDev](https://github.com/DanBoothDev)) -* Pablo Panero ([@ppanero](https://github.com/ppanero)) -* Chuan-Heng Hsiao ([@chhsiao1981](https://github.com/chhsiao1981)) -* Mohammad Hossein Sekhavat ([@mhsekhavat](https://github.com/mhsekhavat)) -* Amey Joshi ([@amey589](https://github.com/amey589)) -* Paul Harrison ([@smoothml](https://github.com/smoothml)) -* Fabio Todaro ([@SharpEdgeMarshall](https://github.com/SharpEdgeMarshall)) -* Nicholas Bollweg ([@bollwyvl](https://github.com/bollwyvl)) -* Jace Browning ([@jacebrowning](https://github.com/jacebrowning)) -* Ionel Cristian Mărieș ([@ionelmc](https://github.com/ionelmc)) -* Kishan Mehta ([@kishan3](https://github.com/kishan3)) -* Wieland Hoffmann ([@mineo](https://github.com/mineo)) -* Antony Lee ([@anntzer](https://github.com/anntzer)) -* Aurélien Gâteau ([@agateau](https://github.com/agateau)) -* Axel H. ([@noirbizarre](https://github.com/noirbizarre)) -* Chris ([@chrisbrake](https://github.com/chrisbrake)) -* Chris Streeter ([@streeter](https://github.com/streeter)) -* Gábor Lipták ([@gliptak](https://github.com/gliptak)) -* Javier Sánchez Portero ([@javiersanp](https://github.com/javiersanp)) -* Nimrod Milo ([@milonimrod](https://github.com/milonimrod)) -* Philipp Kats ([@Casyfill](https://github.com/Casyfill)) -* Reinout van Rees ([@reinout](https://github.com/reinout)) -* Rémy Greinhofer ([@rgreinho](https://github.com/rgreinho)) -* Sebastian ([@sebix](https://github.com/sebix)) -* Stuart Mumford ([@Cadair](https://github.com/Cadair)) -* Tom Forbes ([@orf](https://github.com/orf)) -* Xie Yanbo ([@xyb](https://github.com/xyb)) -* Maxim Ivanov ([@ivanovmg](https://github.com/ivanovmg)) +- Steven Loria ([@sloria](https://github.com/sloria)) +- Goran Peretin ([@gperetin](https://github.com/gperetin)) +- Hamish Downer ([@foobacca](https://github.com/foobacca)) +- Thomas Orozco ([@krallin](https://github.com/krallin)) +- Jindrich Smitka ([@s-m-i-t-a](https://github.com/s-m-i-t-a)) +- Benjamin Schwarze ([@benjixx](https://github.com/benjixx)) +- Raphi ([@raphigaziano](https://github.com/raphigaziano)) +- Thomas Chiroux ([@ThomasChiroux](https://github.com/ThomasChiroux)) +- Sergi Almacellas Abellana ([@pokoli](https://github.com/pokoli)) +- Alex Gaynor ([@alex](https://github.com/alex)) +- Rolo ([@rolo](https://github.com/rolo)) +- Pablo ([@oubiga](https://github.com/oubiga)) +- Bruno Rocha ([@rochacbruno](https://github.com/rochacbruno)) +- Alexander Artemenko ([@svetlyak40wt](https://github.com/svetlyak40wt)) +- Mahmoud Abdelkader ([@mahmoudimus](https://github.com/mahmoudimus)) +- Leonardo Borges Avelino ([@lborgav](https://github.com/lborgav)) +- Chris Trotman ([@solarnz](https://github.com/solarnz)) +- Rolf ([@relekang](https://github.com/relekang)) +- Noah Kantrowitz ([@coderanger](https://github.com/coderanger)) +- Vincent Bernat ([@vincentbernat](https://github.com/vincentbernat)) +- Germán Moya ([@pbacterio](https://github.com/pbacterio)) +- Ned Batchelder ([@nedbat](https://github.com/nedbat)) +- Dave Dash ([@davedash](https://github.com/davedash)) +- Johan Charpentier ([@cyberj](https://github.com/cyberj)) +- Éric Araujo ([@merwok](https://github.com/merwok)) +- saxix ([@saxix](https://github.com/saxix)) +- Tzu-ping Chung ([@uranusjr](https://github.com/uranusjr)) +- Caleb Hattingh ([@cjrh](https://github.com/cjrh)) +- Flavio Curella ([@fcurella](https://github.com/fcurella)) +- Adam Venturella ([@aventurella](https://github.com/aventurella)) +- Monty Taylor ([@emonty](https://github.com/emonty)) +- schacki ([@schacki](https://github.com/schacki)) +- Ryan Olson ([@ryanolson](https://github.com/ryanolson)) +- Trey Hunner ([@treyhunner](https://github.com/treyhunner)) +- Russell Keith-Magee ([@freakboy3742](https://github.com/freakboy3742)) +- Mishbah Razzaque ([@mishbahr](https://github.com/mishbahr)) +- Robin Andeer ([@robinandeer](https://github.com/robinandeer)) +- Rachel Sanders ([@trustrachel](https://github.com/trustrachel)) +- Rémy Hubscher ([@Natim](https://github.com/Natim)) +- Dino Petron3 ([@dinopetrone](https://github.com/dinopetrone)) +- Peter Inglesby ([@inglesp](https://github.com/inglesp)) +- Ramiro Batista da Luz ([@ramiroluz](https://github.com/ramiroluz)) +- Omer Katz ([@thedrow](https://github.com/thedrow)) +- lord63 ([@lord63](https://github.com/lord63)) +- Randy Syring ([@rsyring](https://github.com/rsyring)) +- Mark Jones ([@mark0978](https://github.com/mark0978)) +- Marc Abramowitz ([@msabramo](https://github.com/msabramo)) +- Lucian Ursu ([@LucianU](https://github.com/LucianU)) +- Osvaldo Santana Neto ([@osantana](https://github.com/osantana)) +- Matthias84 ([@Matthias84](https://github.com/Matthias84)) +- Simeon Visser ([@svisser](https://github.com/svisser)) +- Guruprasad ([@lgp171188](https://github.com/lgp171188)) +- Charles-Axel Dein ([@charlax](https://github.com/charlax)) +- Diego Garcia ([@drgarcia1986](https://github.com/drgarcia1986)) +- maiksensi ([@maiksensi](https://github.com/maiksensi)) +- Andrew Conti ([@agconti](https://github.com/agconti)) +- Valentin Lab ([@vaab](https://github.com/vaab)) +- Ilja Bauer ([@iljabauer](https://github.com/iljabauer)) +- Elias Dorneles ([@eliasdorneles](https://github.com/eliasdorneles)) +- Matias Saguir ([@mativs](https://github.com/mativs)) +- Johannes ([@johtso](https://github.com/johtso)) +- macrotim ([@macrotim](https://github.com/macrotim)) +- Will McGinnis ([@wdm0006](https://github.com/wdm0006)) +- Cédric Krier ([@cedk](https://github.com/cedk)) +- Tim Osborn ([@ptim](https://github.com/ptim)) +- Aaron Gallagher ([@habnabit](https://github.com/habnabit)) +- mozillazg ([@mozillazg](https://github.com/mozillazg)) +- Joachim Jablon ([@ewjoachim](https://github.com/ewjoachim)) +- Andrew Ittner ([@tephyr](https://github.com/tephyr)) +- Diane DeMers Chen ([@purplediane](https://github.com/purplediane)) +- zzzirk ([@zzzirk](https://github.com/zzzirk)) +- Carol Willing ([@willingc](https://github.com/willingc)) +- phoebebauer ([@phoebebauer](https://github.com/phoebebauer)) +- Adam Chainz ([@adamchainz](https://github.com/adamchainz)) +- Sulé ([@suledev](https://github.com/suledev)) +- Evan Palmer ([@palmerev](https://github.com/palmerev)) +- Bruce Eckel ([@BruceEckel](https://github.com/BruceEckel)) +- Robert Lyon ([@ivanlyon](https://github.com/ivanlyon)) +- Terry Bates ([@terryjbates](https://github.com/terryjbates)) +- Brett Cannon ([@brettcannon](https://github.com/brettcannon)) +- Michael Warkentin ([@mwarkentin](https://github.com/mwarkentin)) +- Bartłomiej Kurzeja ([@B3QL](https://github.com/B3QL)) +- Thomas O'Donnell ([@andytom](https://github.com/andytom)) +- Jeremy Carbaugh ([@jcarbaugh](https://github.com/jcarbaugh)) +- Nathan Cheung ([@cheungnj](https://github.com/cheungnj)) +- Abdó Roig-Maranges ([@aroig](https://github.com/aroig)) +- Steve Piercy ([@stevepiercy](https://github.com/stevepiercy)) +- Corey ([@coreysnyder04](https://github.com/coreysnyder04)) +- Dmitry Evstratov ([@devstrat](https://github.com/devstrat)) +- Eyal Levin ([@eyalev](https://github.com/eyalev)) +- mathagician ([@mathagician](https://github.com/mathagician)) +- Guillaume Gelin ([@ramnes](https://github.com/ramnes)) +- @delirious-lettuce ([@delirious-lettuce](https://github.com/delirious-lettuce)) +- Gasper Vozel ([@karantan](https://github.com/karantan)) +- Joshua Carp ([@jmcarp](https://github.com/jmcarp)) +- @meahow ([@meahow](https://github.com/meahow)) +- Andrea Grandi ([@andreagrandi](https://github.com/andreagrandi)) +- Issa Jubril ([@jubrilissa](https://github.com/jubrilissa)) +- Nytiennzo Madooray ([@Nythiennzo](https://github.com/Nythiennzo)) +- Erik Bachorski ([@dornheimer](https://github.com/dornheimer)) +- cclauss ([@cclauss](https://github.com/cclauss)) +- Andy Craze ([@accraze](https://github.com/accraze)) +- Anthony Sottile ([@asottile](https://github.com/asottile)) +- Jonathan Sick ([@jonathansick](https://github.com/jonathansick)) +- Hugo ([@hugovk](https://github.com/hugovk)) +- Min ho Kim ([@minho42](https://github.com/minho42)) +- Ryan Ly ([@rly](https://github.com/rly)) +- Akintola Rahmat ([@mihrab34](https://github.com/mihrab34)) +- Jai Ram Rideout ([@jairideout](https://github.com/jairideout)) +- Diego Carrasco Gubernatis ([@dacog](https://github.com/dacog)) +- Wagner Negrão ([@wagnernegrao](https://github.com/wagnernegrao)) +- Josh Barnes ([@jcb91](https://github.com/jcb91)) +- Nikita Sobolev ([@sobolevn](https://github.com/sobolevn)) +- Matt Stibbs ([@mattstibbs](https://github.com/mattstibbs)) +- MinchinWeb ([@MinchinWeb](https://github.com/MinchinWeb)) +- kishan ([@kishan](https://github.com/kishan3)) +- tonytheleg ([@tonytheleg](https://github.com/tonytheleg)) +- Roman Hartmann ([@RomHartmann](https://github.com/RomHartmann)) +- DSEnvel ([@DSEnvel](https://github.com/DSEnvel)) +- kishan ([@kishan](https://github.com/kishan3)) +- Bruno Alla ([@browniebroke](https://github.com/browniebroke)) +- nicain ([@nicain](https://github.com/nicain)) +- Carsten Rösnick-Neugebauer ([@croesnick](https://github.com/croesnick)) +- igorbasko01 ([@igorbasko01](https://github.com/igorbasko01)) +- Dan Booth Dev ([@DanBoothDev](https://github.com/DanBoothDev)) +- Pablo Panero ([@ppanero](https://github.com/ppanero)) +- Chuan-Heng Hsiao ([@chhsiao1981](https://github.com/chhsiao1981)) +- Mohammad Hossein Sekhavat ([@mhsekhavat](https://github.com/mhsekhavat)) +- Amey Joshi ([@amey589](https://github.com/amey589)) +- Paul Harrison ([@smoothml](https://github.com/smoothml)) +- Fabio Todaro ([@SharpEdgeMarshall](https://github.com/SharpEdgeMarshall)) +- Nicholas Bollweg ([@bollwyvl](https://github.com/bollwyvl)) +- Jace Browning ([@jacebrowning](https://github.com/jacebrowning)) +- Ionel Cristian Mărieș ([@ionelmc](https://github.com/ionelmc)) +- Kishan Mehta ([@kishan3](https://github.com/kishan3)) +- Wieland Hoffmann ([@mineo](https://github.com/mineo)) +- Antony Lee ([@anntzer](https://github.com/anntzer)) +- Aurélien Gâteau ([@agateau](https://github.com/agateau)) +- Axel H. ([@noirbizarre](https://github.com/noirbizarre)) +- Chris ([@chrisbrake](https://github.com/chrisbrake)) +- Chris Streeter ([@streeter](https://github.com/streeter)) +- Gábor Lipták ([@gliptak](https://github.com/gliptak)) +- Javier Sánchez Portero ([@javiersanp](https://github.com/javiersanp)) +- Nimrod Milo ([@milonimrod](https://github.com/milonimrod)) +- Philipp Kats ([@Casyfill](https://github.com/Casyfill)) +- Reinout van Rees ([@reinout](https://github.com/reinout)) +- Rémy Greinhofer ([@rgreinho](https://github.com/rgreinho)) +- Sebastian ([@sebix](https://github.com/sebix)) +- Stuart Mumford ([@Cadair](https://github.com/Cadair)) +- Tom Forbes ([@orf](https://github.com/orf)) +- Xie Yanbo ([@xyb](https://github.com/xyb)) +- Maxim Ivanov ([@ivanovmg](https://github.com/ivanovmg)) diff --git a/LICENSE b/LICENSE index 5e75b2cfd..06486a8f3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2021, Audrey Feldroy +Copyright (c) 2013-2021, Audrey Roy Greenfeld All rights reserved. Redistribution and use in source and binary forms, with or diff --git a/README.md b/README.md index 9fcf0c7c5..2d8b81b75 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ A command-line utility that creates projects from **cookiecutters** (project templates), e.g. creating a Python package project from a Python package project template. -* Documentation: [https://cookiecutter.readthedocs.io](https://cookiecutter.readthedocs.io) -* GitHub: [https://github.com/cookiecutter/cookiecutter](https://github.com/cookiecutter/cookiecutter) -* PyPI: [https://pypi.org/project/cookiecutter/](https://pypi.org/project/cookiecutter/) -* Free and open source software: [BSD license](https://github.com/cookiecutter/cookiecutter/blob/master/LICENSE) +- Documentation: [https://cookiecutter.readthedocs.io](https://cookiecutter.readthedocs.io) +- GitHub: [https://github.com/cookiecutter/cookiecutter](https://github.com/cookiecutter/cookiecutter) +- PyPI: [https://pypi.org/project/cookiecutter/](https://pypi.org/project/cookiecutter/) +- Free and open source software: [BSD license](https://github.com/cookiecutter/cookiecutter/blob/master/LICENSE) ![Cookiecutter](https://raw.githubusercontent.com/cookiecutter/cookiecutter/3ac078356adf5a1a72042dfe72ebfa4a9cd5ef38/logo/cookiecutter_medium.png) @@ -26,13 +26,13 @@ We are proud to be an open source sponsor of Did someone say features? -* Cross-platform: Windows, Mac, and Linux are officially supported. -* You don't have to know/write Python code to use Cookiecutter. -* Works with Python 3.6, 3.7, 3.8, 3.9 and PyPy3. -* Project templates can be in any programming language or markup format: +- Cross-platform: Windows, Mac, and Linux are officially supported. +- You don't have to know/write Python code to use Cookiecutter. +- Works with Python 3.6, 3.7, 3.8, 3.9 and PyPy3. +- Project templates can be in any programming language or markup format: Python, JavaScript, Ruby, CoffeeScript, RST, Markdown, CSS, HTML, you name it. You can use multiple languages in the same project template. -* Simple command line usage: +- Simple command line usage: ```bash # Create project from the cookiecutter-pypackage.git repo template @@ -44,7 +44,7 @@ $ cookiecutter https://github.com/audreyfeldroy/cookiecutter-pypackage $ cookiecutter gh:audreyfeldroy/cookiecutter-pypackage ``` -* Use it at the command line with a local template: +- Use it at the command line with a local template: ```bash # Create project in the current working directory, from the local @@ -52,7 +52,7 @@ $ cookiecutter gh:audreyfeldroy/cookiecutter-pypackage $ cookiecutter cookiecutter-pypackage/ ``` -* Or use it from Python: +- Or use it from Python: ```py from cookiecutter.main import cookiecutter @@ -64,47 +64,47 @@ cookiecutter('cookiecutter-pypackage/') cookiecutter('https://github.com/audreyfeldroy/cookiecutter-pypackage.git') ``` -* Directory names and filenames can be templated. For example: +- Directory names and filenames can be templated. For example: ```py {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}.py ``` -* Supports unlimited levels of directory nesting. -* 100% of templating is done with Jinja2. This includes file and directory names. -* Simply define your template variables in a ``cookiecutter.json`` file. For example: +- Supports unlimited levels of directory nesting. +- 100% of templating is done with Jinja2. This includes file and directory names. +- Simply define your template variables in a `cookiecutter.json` file. For example: ```json { - "full_name": "Audrey Feldroy", - "email": "audreyr@gmail.com", - "project_name": "Complexity", - "repo_name": "complexity", - "project_short_description": "Refreshingly simple static site generator.", - "release_date": "2013-07-10", - "year": "2013", - "version": "0.1.1" + "full_name": "Audrey Roy Greenfeld", + "email": "audreyr@gmail.com", + "project_name": "Complexity", + "repo_name": "complexity", + "project_short_description": "Refreshingly simple static site generator.", + "release_date": "2013-07-10", + "year": "2013", + "version": "0.1.1" } ``` -* Unless you suppress it with ``--no-input``, you are prompted for input: - * Prompts are the keys in ``cookiecutter.json``. - * Default responses are the values in ``cookiecutter.json``. - * Prompts are shown in order. -* Cross-platform support for ``~/.cookiecutterrc`` files: +- Unless you suppress it with `--no-input`, you are prompted for input: + - Prompts are the keys in `cookiecutter.json`. + - Default responses are the values in `cookiecutter.json`. + - Prompts are shown in order. +- Cross-platform support for `~/.cookiecutterrc` files: ```yaml default_context: - full_name: "Audrey Feldroy" - email: "audreyr@gmail.com" - github_username: "audreyfeldroy" + full_name: "Audrey Roy Greenfeld" + email: "audreyr@gmail.com" + github_username: "audreyfeldroy" cookiecutters_dir: "~/.cookiecutters/" ``` -* Cookiecutters (cloned Cookiecutter project templates) are put into -``~/.cookiecutters/`` by default, or cookiecutters_dir if specified. -* If you have already cloned a cookiecutter into ``~/.cookiecutters/``, -you can reference it by directory name: +- Cookiecutters (cloned Cookiecutter project templates) are put into + `~/.cookiecutters/` by default, or cookiecutters_dir if specified. +- If you have already cloned a cookiecutter into `~/.cookiecutters/`, + you can reference it by directory name: ```bash # Clone cookiecutter-pypackage @@ -113,22 +113,22 @@ $ cookiecutter gh:audreyfeldroy/cookiecutter-pypackage $ cookiecutter cookiecutter-pypackage ``` -* You can use local cookiecutters, or remote cookiecutters directly from Git -repos or from Mercurial repos on Bitbucket. -* Default context: specify key/value pairs that you want used as defaults -whenever you generate a project. -* Inject extra context with command-line arguments: +- You can use local cookiecutters, or remote cookiecutters directly from Git + repos or from Mercurial repos on Bitbucket. +- Default context: specify key/value pairs that you want used as defaults + whenever you generate a project. +- Inject extra context with command-line arguments: ```bash cookiecutter --no-input gh:msabramo/cookiecutter-supervisor program_name=foobar startsecs=10 ``` -* Direct access to the Cookiecutter API allows for injection of extra context. -* Pre- and post-generate hooks: Python or shell scripts to run before or after -generating a project. -* Paths to local projects can be specified as absolute or relative. -* Projects generated to your current directory or to target directory if -specified with `-o` option. +- Direct access to the Cookiecutter API allows for injection of extra context. +- Pre- and post-generate hooks: Python or shell scripts to run before or after + generating a project. +- Paths to local projects can be specified as absolute or relative. +- Projects generated to your current directory or to target directory if + specified with `-o` option. ## Available Cookiecutters @@ -157,14 +157,14 @@ discoverable. You are almost not limited in topics amount, use it! These Cookiecutters are maintained by the cookiecutter team: -* [cookiecutter-pypackage](https://github.com/audreyfeldroy/cookiecutter-pypackage): -[@audreyfeldroy's](https://github.com/audreyfeldroy) ultimate Python package project template. -* [cookiecutter-django](https://github.com/pydanny/cookiecutter-django): -A bleeding edge Django project template with Bootstrap 4, customizable users app, -starter templates, working user registration, celery setup, and much more. -* [cookiecutter-pytest-plugin](https://github.com/pytest-dev/cookiecutter-pytest-plugin): -Minimal Cookiecutter template for authoring [pytest](https://docs.pytest.org/) -plugins that help you to write better programs. +- [cookiecutter-pypackage](https://github.com/audreyfeldroy/cookiecutter-pypackage): + [@audreyfeldroy's](https://github.com/audreyfeldroy) ultimate Python package project template. +- [cookiecutter-django](https://github.com/pydanny/cookiecutter-django): + A bleeding edge Django project template with Bootstrap 4, customizable users app, + starter templates, working user registration, celery setup, and much more. +- [cookiecutter-pytest-plugin](https://github.com/pytest-dev/cookiecutter-pytest-plugin): + Minimal Cookiecutter template for authoring [pytest](https://docs.pytest.org/) + plugins that help you to write better programs. ## Community @@ -173,57 +173,57 @@ We are always welcome and invite you to participate. Stuck? Try one of the following: -* See the [Troubleshooting](https://cookiecutter.readthedocs.io/en/latest/troubleshooting.html) page. -* Ask for help on [Stack Overflow](https://stackoverflow.com/questions/tagged/cookiecutter). -* You are strongly encouraged to -[file an issue](https://github.com/cookiecutter/cookiecutter/issues?q=is%3Aopen) -about the problem, even if it's just "I can't get it to work on this cookiecutter" -with a link to your cookiecutter. Don't worry about naming/pinpointing the issue -properly. -* Ask for help on [Slack](https://join.slack.com/t/cookie-cutter/shared_invite/enQtNzI0Mzg5NjE5Nzk5LTRlYWI2YTZhYmQ4YmU1Y2Q2NmE1ZjkwOGM0NDQyNTIwY2M4ZTgyNDVkNjMxMDdhZGI5ZGE5YmJjM2M3ODJlY2U) -if you must (but please try one of the other options first, so that others -can benefit from the discussion). +- See the [Troubleshooting](https://cookiecutter.readthedocs.io/en/latest/troubleshooting.html) page. +- Ask for help on [Stack Overflow](https://stackoverflow.com/questions/tagged/cookiecutter). +- You are strongly encouraged to + [file an issue](https://github.com/cookiecutter/cookiecutter/issues?q=is%3Aopen) + about the problem, even if it's just "I can't get it to work on this cookiecutter" + with a link to your cookiecutter. Don't worry about naming/pinpointing the issue + properly. +- Ask for help on [Slack](https://join.slack.com/t/cookie-cutter/shared_invite/enQtNzI0Mzg5NjE5Nzk5LTRlYWI2YTZhYmQ4YmU1Y2Q2NmE1ZjkwOGM0NDQyNTIwY2M4ZTgyNDVkNjMxMDdhZGI5ZGE5YmJjM2M3ODJlY2U) + if you must (but please try one of the other options first, so that others + can benefit from the discussion). Development on Cookiecutter is community-driven: -* Huge thanks to all the [contributors](AUTHORS.md) who have pitched in to help -make Cookiecutter an even better tool. -* Everyone is invited to contribute. Read the -[contributing instructions](CONTRIBUTING.md), then get started. -* Connect with other Cookiecutter contributors and users on -[Slack](https://join.slack.com/t/cookie-cutter/shared_invite/enQtNzI0Mzg5NjE5Nzk5LTRlYWI2YTZhYmQ4YmU1Y2Q2NmE1ZjkwOGM0NDQyNTIwY2M4ZTgyNDVkNjMxMDdhZGI5ZGE5YmJjM2M3ODJlY2U) -(note: due to work and commitments, a core committer might not always be available) +- Huge thanks to all the [contributors](AUTHORS.md) who have pitched in to help + make Cookiecutter an even better tool. +- Everyone is invited to contribute. Read the + [contributing instructions](CONTRIBUTING.md), then get started. +- Connect with other Cookiecutter contributors and users on + [Slack](https://join.slack.com/t/cookie-cutter/shared_invite/enQtNzI0Mzg5NjE5Nzk5LTRlYWI2YTZhYmQ4YmU1Y2Q2NmE1ZjkwOGM0NDQyNTIwY2M4ZTgyNDVkNjMxMDdhZGI5ZGE5YmJjM2M3ODJlY2U) + (note: due to work and commitments, a core committer might not always be available) Encouragement is unbelievably motivating. If you want more work done on Cookiecutter, show support: -* Thank a core committer for their efforts. -* Star [Cookiecutter on GitHub](https://github.com/cookiecutter/cookiecutter). -* [Support this project](#support-this-project) +- Thank a core committer for their efforts. +- Star [Cookiecutter on GitHub](https://github.com/cookiecutter/cookiecutter). +- [Support this project](#support-this-project) Got criticism or complaints? -* [File an issue](https://github.com/cookiecutter/cookiecutter/issues?q=is%3Aopen) -so that Cookiecutter can be improved. Be friendly and constructive about what -could be better. Make detailed suggestions. -* **Keep us in the loop so that we can help.** For example, if you are -discussing problems with Cookiecutter on a mailing list, -[file an issue](https://github.com/cookiecutter/cookiecutter/issues?q=is%3Aopen) -where you link to the discussion thread and/or cc at least 1 core committer on the email. -* Be encouraging. A comment like "This function ought to be rewritten like this" -is much more likely to result in action than a comment like "Eww, look how bad -this function is." +- [File an issue](https://github.com/cookiecutter/cookiecutter/issues?q=is%3Aopen) + so that Cookiecutter can be improved. Be friendly and constructive about what + could be better. Make detailed suggestions. +- **Keep us in the loop so that we can help.** For example, if you are + discussing problems with Cookiecutter on a mailing list, + [file an issue](https://github.com/cookiecutter/cookiecutter/issues?q=is%3Aopen) + where you link to the discussion thread and/or cc at least 1 core committer on the email. +- Be encouraging. A comment like "This function ought to be rewritten like this" + is much more likely to result in action than a comment like "Eww, look how bad + this function is." Waiting for a response to an issue/question? -* Be patient and persistent. All issues are on the core committer team's radar -and will be considered thoughtfully, but we have a lot of issues to work through. -If urgent, it's fine to ping a core committer in the issue with a reminder. -* Ask others to comment, discuss, review, etc. -* Search the Cookiecutter repo for issues related to yours. -* Need a fix/feature/release/help urgently, and can't wait? -[@audreyfeldroy](https://github.com/audreyfeldroy) is available for hire for consultation -or custom development. +- Be patient and persistent. All issues are on the core committer team's radar + and will be considered thoughtfully, but we have a lot of issues to work through. + If urgent, it's fine to ping a core committer in the issue with a reminder. +- Ask others to comment, discuss, review, etc. +- Search the Cookiecutter repo for issues related to yours. +- Need a fix/feature/release/help urgently, and can't wait? + [@audreyfeldroy](https://github.com/audreyfeldroy) is available for hire for consultation + or custom development. ## Support This Project diff --git a/setup.cfg b/setup.cfg index b9f2cf7a8..c43971e88 100644 --- a/setup.cfg +++ b/setup.cfg @@ -12,9 +12,9 @@ description = Python package project template. long_description = file: README.md long_description_content_type = text/markdown -author = Audrey Feldroy +author = Audrey Roy Greenfeld author_email = audreyr@gmail.com -maintainer = Audrey Feldroy +maintainer = Audrey Roy Greenfeld maintainer_email = audreyr@gmail.com license = BSD license_file = LICENSE From 228c655550a57822d44b0c5527d5aab5986f266a Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Sat, 30 Oct 2021 10:54:22 -0700 Subject: [PATCH 03/35] Don't run tests on Python 3.6 or PyPy anymore. - Resolves GitHub check failures due to GitHub no longer supporting those environments on Mac OSX. - Python 3.6 is in maintenance status *security* with EOL in 2 months. - PyPy was last updated to Python 3.8, which is outdated. --- .github/workflows/main.yml | 25 ------------------------- CONTRIBUTING.md | 6 +++--- README.md | 4 +--- docs/installation.rst | 2 +- setup.cfg | 2 -- tox.ini | 2 -- 6 files changed, 5 insertions(+), 36 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 14e8e77d9..436de42a6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,28 +34,19 @@ jobs: fail-fast: false matrix: name: - - "ubuntu-py36" - "ubuntu-py37" - "ubuntu-py38" - "ubuntu-py39" - - "ubuntu-pypy3" - - "macos-py36" - "macos-py37" - "macos-py38" - "macos-py39" - - "macos-pypy3" - - "windows-py36" - "windows-py37" - "windows-py38" - "windows-py39" include: - - name: "ubuntu-py36" - python: "3.6" - os: ubuntu-latest - tox_env: "py36" - name: "ubuntu-py37" python: "3.7" os: ubuntu-latest @@ -68,15 +59,7 @@ jobs: python: "3.9" os: ubuntu-latest tox_env: "py39" - - name: "ubuntu-pypy3" - python: "pypy3" - os: ubuntu-latest - tox_env: "pypy3" - - name: "macos-py36" - python: "3.6" - os: macos-latest - tox_env: "py36" - name: "macos-py37" python: "3.7" os: macos-latest @@ -89,15 +72,7 @@ jobs: python: "3.9" os: macos-latest tox_env: "py39" - - name: "macos-pypy3" - python: "pypy3" - os: macos-latest - tox_env: "pypy3" - - name: "windows-py36" - python: "3.6" - os: windows-latest - tox_env: "py36" - name: "windows-py37" python: "3.7" os: windows-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4b9a5dff4..9c2f12650 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -188,13 +188,13 @@ tox This configuration file setup the pytest-cov plugin and it is an additional dependency. It generate a coverage report after the tests. -It is possible to tests with some versions of python, to do this the command is: +It is possible to test with specific versions of Python. To do this, the command is: ```bash -tox -e py36,pypy3 +tox -e py37,py38 ``` -Will run py.test with the python3.6 and pypy3 interpreters, for example. +Will run py.test with the python3.7 and python3.8 interpreters, for example. ## Core Committer Guide diff --git a/README.md b/README.md index 2d8b81b75..9b1dfe141 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,9 @@ We are proud to be an open source sponsor of ## Features -Did someone say features? - - Cross-platform: Windows, Mac, and Linux are officially supported. - You don't have to know/write Python code to use Cookiecutter. -- Works with Python 3.6, 3.7, 3.8, 3.9 and PyPy3. +- Works with Python 3.7, 3.8, 3.9. - Project templates can be in any programming language or markup format: Python, JavaScript, Ruby, CoffeeScript, RST, Markdown, CSS, HTML, you name it. You can use multiple languages in the same project template. diff --git a/docs/installation.rst b/docs/installation.rst index 44c0d841a..d12709c37 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -59,7 +59,7 @@ You may also install `Windows Subsystem for Linux =3.6. See the Python Packaging Authority's (PyPA) documentation `Requirements for Installing Packages `_ for full details. +See the Python Packaging Authority's (PyPA) documentation `Requirements for Installing Packages `_ for full details. Install cookiecutter diff --git a/setup.cfg b/setup.cfg index c43971e88..e1ddc4fbb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,12 +26,10 @@ classifiers = License :: OSI Approved :: BSD License Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: Implementation :: CPython - Programming Language :: Python :: Implementation :: PyPy Programming Language :: Python Topic :: Software Development keywords = diff --git a/tox.ini b/tox.ini index 499c6febe..591fc50ee 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,9 @@ [tox] envlist = lint - py36 py37 py38 py39 - pypy3 minversion = 3.14.2 requires = virtualenv >= 20.4.5 From dfebae46c2922185615cb4b9e5aa24274ab7b4b9 Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Sat, 30 Oct 2021 10:57:26 -0700 Subject: [PATCH 04/35] Update Black target version from py36 to py39 Co-authored-by: Daniel Roy Greenfeld --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6dc08afa9..26bea3f21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ build-backend = "setuptools.build_meta" skip-string-normalization = true exclude = '/(tests/hooks-abort-render/hooks|docs\/HelloCookieCutter1)/' line-length = 88 -target-version = ['py36'] +target-version = ['py39'] [tool.setuptools_scm] local_scheme = "no-local-version" From 120c8fa2794a244a8ea3de6ecc3994e2a7e3ba13 Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Sat, 30 Oct 2021 11:09:24 -0700 Subject: [PATCH 05/35] Correct linting - Update Black version - Use Black python target of Python 3.9 Co-authored-by: Daniel Roy Greenfeld --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c1f2a0886..f183b3f18 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,8 +10,8 @@ repos: language: python files: \.rst$ require_serial: true - - repo: https://github.com/python/black.git - rev: 19.10b0 + - repo: https://github.com/psf/black.git + rev: 21.9b0 hooks: - id: black language_version: python3 From 7189ca0e1438bb755401b5012e1de7a8137373f5 Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Wed, 3 Nov 2021 20:27:10 -0700 Subject: [PATCH 06/35] Forced re-run of PR CI --- .pre-commit-config.yaml | 2 +- CONTRIBUTING.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f183b3f18..8b6b8eb0f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: hooks: - id: doc8 name: doc8 - description: This hook runs doc8 for linting docs + description: This hook runs doc8 for linting docs. entry: python -m doc8 language: python files: \.rst$ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9c2f12650..0d484ed03 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,7 +72,7 @@ git clone git@github.com:your_name_here/cookiecutter.git 3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development: ```bash -mkvirtualenv cookiecutter + cd cookiecutter/ python setup.py develop ``` From 81f0195252bfe72fcef3d0037874ce763337bc60 Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Wed, 3 Nov 2021 20:36:23 -0700 Subject: [PATCH 07/35] Comment out doc8 to see if it is the issue with GHCI --- .pre-commit-config.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8b6b8eb0f..229ec0f18 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,15 @@ --- repos: - - repo: https://github.com/PyCQA/doc8 - rev: 0.8.1 - hooks: - - id: doc8 - name: doc8 - description: This hook runs doc8 for linting docs. - entry: python -m doc8 - language: python - files: \.rst$ - require_serial: true + # - repo: https://github.com/PyCQA/doc8 + # rev: 0.8.1 + # hooks: + # - id: doc8 + # name: doc8 + # description: This hook runs doc8 for linting docs. + # entry: python -m doc8 + # language: python + # files: \.rst$ + # require_serial: true - repo: https://github.com/psf/black.git rev: 21.9b0 hooks: From 5987775cfd54c07ba8ba8e3794bb69fda1242f16 Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Wed, 3 Nov 2021 20:39:06 -0700 Subject: [PATCH 08/35] Test to see if Black is failing --- .pre-commit-config.yaml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 229ec0f18..ba22afc71 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,21 +1,21 @@ --- repos: - # - repo: https://github.com/PyCQA/doc8 - # rev: 0.8.1 - # hooks: - # - id: doc8 - # name: doc8 - # description: This hook runs doc8 for linting docs. - # entry: python -m doc8 - # language: python - # files: \.rst$ - # require_serial: true - - repo: https://github.com/psf/black.git - rev: 21.9b0 + - repo: https://github.com/PyCQA/doc8 + rev: 0.8.1 hooks: - - id: black - language_version: python3 - exclude: ^(tests\/hooks-abort-render\/hooks|docs\/HelloCookieCutter1) + - id: doc8 + name: doc8 + description: This hook runs doc8 for linting docs. + entry: python -m doc8 + language: python + files: \.rst$ + require_serial: true + # - repo: https://github.com/psf/black.git + # rev: 21.9b0 + # hooks: + # - id: black + # language_version: python3 + # exclude: ^(tests\/hooks-abort-render\/hooks|docs\/HelloCookieCutter1) - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.4.0 hooks: From c767bd91786c884774dabb5686660c6f2b26d51f Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Wed, 3 Nov 2021 20:43:56 -0700 Subject: [PATCH 09/35] Add no-verify agument to pre-commit hooks --- .pre-commit-config.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ba22afc71..246050ae4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,17 +10,17 @@ repos: language: python files: \.rst$ require_serial: true - # - repo: https://github.com/psf/black.git - # rev: 21.9b0 - # hooks: - # - id: black - # language_version: python3 - # exclude: ^(tests\/hooks-abort-render\/hooks|docs\/HelloCookieCutter1) + - repo: https://github.com/psf/black.git + rev: 21.9b0 + hooks: + - id: black + language_version: python3 + exclude: ^(tests\/hooks-abort-render\/hooks|docs\/HelloCookieCutter1) - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.4.0 hooks: - id: trailing-whitespace - args: [--markdown-linebreak-ext=md] + args: [--markdown-linebreak-ext=md, --no-verify] - id: mixed-line-ending - id: check-byte-order-marker - id: check-executables-have-shebangs From def2bb64de18621db88d3529654f856cbbe7456a Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Wed, 3 Nov 2021 20:45:52 -0700 Subject: [PATCH 10/35] Upgrade black --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 246050ae4..ce7d43cfc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: files: \.rst$ require_serial: true - repo: https://github.com/psf/black.git - rev: 21.9b0 + rev: 21.10b0 hooks: - id: black language_version: python3 @@ -20,7 +20,7 @@ repos: rev: v2.4.0 hooks: - id: trailing-whitespace - args: [--markdown-linebreak-ext=md, --no-verify] + args: [--markdown-linebreak-ext=md] - id: mixed-line-ending - id: check-byte-order-marker - id: check-executables-have-shebangs From 3b5a4340c6178cfe7d9652520736eba680092cfc Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Wed, 3 Nov 2021 20:47:44 -0700 Subject: [PATCH 11/35] Comment out black so the PR can proceed --- .pre-commit-config.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ce7d43cfc..d4f0cf881 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,12 +10,12 @@ repos: language: python files: \.rst$ require_serial: true - - repo: https://github.com/psf/black.git - rev: 21.10b0 - hooks: - - id: black - language_version: python3 - exclude: ^(tests\/hooks-abort-render\/hooks|docs\/HelloCookieCutter1) + # - repo: https://github.com/psf/black.git + # rev: 21.10b0 + # hooks: + # - id: black + # language_version: python3 + # exclude: ^(tests\/hooks-abort-render\/hooks|docs\/HelloCookieCutter1) - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.4.0 hooks: From c9e36a42382959a4b1ce796d2379bf83646df764 Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Fri, 5 Nov 2021 10:55:01 -0700 Subject: [PATCH 12/35] Run pre-commit linting - Run tox twice, which lints the code base via pre-commit --- .pre-commit-config.yaml | 12 +++++----- cookiecutter/cli.py | 4 +++- cookiecutter/main.py | 3 ++- tests/test_cli.py | 42 +++++++++++++++++++++++++++------- tests/test_generate_context.py | 8 ++++++- tests/test_get_config.py | 6 ++++- tests/test_get_user_config.py | 6 ++++- tests/test_main.py | 23 ++++++++++++++----- tests/test_prompt.py | 3 ++- tests/test_utils.py | 3 ++- tests/vcs/test_clone.py | 12 ++++++---- tests/zipfile/test_unzip.py | 19 +++++++++++---- 12 files changed, 105 insertions(+), 36 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d4f0cf881..ce7d43cfc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,12 +10,12 @@ repos: language: python files: \.rst$ require_serial: true - # - repo: https://github.com/psf/black.git - # rev: 21.10b0 - # hooks: - # - id: black - # language_version: python3 - # exclude: ^(tests\/hooks-abort-render\/hooks|docs\/HelloCookieCutter1) + - repo: https://github.com/psf/black.git + rev: 21.10b0 + hooks: + - id: black + language_version: python3 + exclude: ^(tests\/hooks-abort-render\/hooks|docs\/HelloCookieCutter1) - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.4.0 hooks: diff --git a/cookiecutter/cli.py b/cookiecutter/cli.py index 991e62c50..84241ac2a 100644 --- a/cookiecutter/cli.py +++ b/cookiecutter/cli.py @@ -78,7 +78,9 @@ def list_installed_templates(default_config, passed_config_file): help='Do not prompt for parameters and only use cookiecutter.json file content', ) @click.option( - '-c', '--checkout', help='branch, tag or commit to checkout after git clone', + '-c', + '--checkout', + help='branch, tag or commit to checkout after git clone', ) @click.option( '--directory', diff --git a/cookiecutter/main.py b/cookiecutter/main.py index 047d30a08..7c9eef731 100644 --- a/cookiecutter/main.py +++ b/cookiecutter/main.py @@ -60,7 +60,8 @@ def cookiecutter( raise InvalidModeException(err_msg) config_dict = get_user_config( - config_file=config_file, default_config=default_config, + config_file=config_file, + default_config=default_config, ) repo_dir, cleanup = determine_repo_dir( diff --git a/tests/test_cli.py b/tests/test_cli.py index e357fef2e..623945e8b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -311,7 +311,10 @@ def test_default_user_config_overwrite(mocker, cli_runner, user_config_path): template_path = 'tests/fake-repo-pre/' result = cli_runner( - template_path, '--config-file', user_config_path, '--default-config', + template_path, + '--config-file', + user_config_path, + '--default-config', ) assert result.exit_code == 0 @@ -362,7 +365,11 @@ def test_echo_undefined_variable_error(output_dir, cli_runner): template_path = 'tests/undefined-variable/file-name/' result = cli_runner( - '--no-input', '--default-config', '--output-dir', output_dir, template_path, + '--no-input', + '--default-config', + '--output-dir', + output_dir, + template_path, ) assert result.exit_code == 1 @@ -392,7 +399,11 @@ def test_echo_unknown_extension_error(output_dir, cli_runner): template_path = 'tests/test-extensions/unknown/' result = cli_runner( - '--no-input', '--default-config', '--output-dir', output_dir, template_path, + '--no-input', + '--default-config', + '--output-dir', + output_dir, + template_path, ) assert result.exit_code == 1 @@ -404,7 +415,10 @@ def test_echo_unknown_extension_error(output_dir, cli_runner): def test_cli_extra_context(cli_runner): """Cli invocation replace content if called with replacement pairs.""" result = cli_runner( - 'tests/fake-repo-pre/', '--no-input', '-v', 'project_name=Awesomez', + 'tests/fake-repo-pre/', + '--no-input', + '-v', + 'project_name=Awesomez', ) assert result.exit_code == 0 assert os.path.isdir('fake-project') @@ -416,7 +430,10 @@ def test_cli_extra_context(cli_runner): def test_cli_extra_context_invalid_format(cli_runner): """Cli invocation raise error if called with unknown argument.""" result = cli_runner( - 'tests/fake-repo-pre/', '--no-input', '-v', 'ExtraContextWithNoEqualsSoInvalid', + 'tests/fake-repo-pre/', + '--no-input', + '-v', + 'ExtraContextWithNoEqualsSoInvalid', ) assert result.exit_code == 2 assert "Error: Invalid value for '[EXTRA_CONTEXT]...'" in result.output @@ -438,7 +455,10 @@ def test_debug_file_non_verbose(cli_runner, debug_file): assert not debug_file.exists() result = cli_runner( - '--no-input', '--debug-file', str(debug_file), 'tests/fake-repo-pre/', + '--no-input', + '--debug-file', + str(debug_file), + 'tests/fake-repo-pre/', ) assert result.exit_code == 0 @@ -493,7 +513,10 @@ def test_debug_list_installed_templates(cli_runner, debug_file, user_config_path open(os.path.join('fake-project', 'cookiecutter.json'), 'w').write('{}') result = cli_runner( - '--list-installed', '--config-file', user_config_path, str(debug_file), + '--list-installed', + '--config-file', + user_config_path, + str(debug_file), ) assert "1 installed templates:" in result.output @@ -520,7 +543,10 @@ def test_debug_list_installed_templates_failure( def test_directory_repo(cli_runner): """Test cli invocation works with `directory` option.""" result = cli_runner( - 'tests/fake-repo-dir/', '--no-input', '-v', '--directory=my-dir', + 'tests/fake-repo-dir/', + '--no-input', + '-v', + '--directory=my-dir', ) assert result.exit_code == 0 assert os.path.isdir("fake-project") diff --git a/tests/test_generate_context.py b/tests/test_generate_context.py index 2a2bc06dd..44ab99194 100644 --- a/tests/test_generate_context.py +++ b/tests/test_generate_context.py @@ -110,7 +110,13 @@ def test_default_context_replacement_in_generate_context(): def test_generate_context_decodes_non_ascii_chars(): """Verify `generate_context` correctly decodes non-ascii chars.""" - expected_context = {'non_ascii': OrderedDict([('full_name', 'éèà'),])} + expected_context = { + 'non_ascii': OrderedDict( + [ + ('full_name', 'éèà'), + ] + ) + } generated_context = generate.generate_context( context_file='tests/test-generate-context/non_ascii.json' diff --git a/tests/test_get_config.py b/tests/test_get_config.py index 760db3cdb..a37317413 100644 --- a/tests/test_get_config.py +++ b/tests/test_get_config.py @@ -62,7 +62,11 @@ def test_get_config(): 'github_username': 'example', 'project': { 'description': 'description', - 'tags': ['first', 'second', 'third',], + 'tags': [ + 'first', + 'second', + 'third', + ], }, }, 'abbreviations': { diff --git a/tests/test_get_user_config.py b/tests/test_get_user_config.py index 560c1d873..551502c5c 100644 --- a/tests/test_get_user_config.py +++ b/tests/test_get_user_config.py @@ -48,7 +48,11 @@ def custom_config(): 'github_username': 'example', 'project': { 'description': 'description', - 'tags': ['first', 'second', 'third',], + 'tags': [ + 'first', + 'second', + 'third', + ], }, }, 'cookiecutters_dir': '/home/example/some-path-to-templates', diff --git a/tests/test_main.py b/tests/test_main.py index 46b7ff9a8..ee0f738f9 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -22,11 +22,16 @@ def test_replay_dump_template_name( mocker.patch('cookiecutter.main.generate_files') cookiecutter( - '.', no_input=True, replay=False, config_file=user_config_file, + '.', + no_input=True, + replay=False, + config_file=user_config_file, ) mock_replay_dump.assert_called_once_with( - user_config_data['replay_dir'], 'fake-repo-tmpl', mocker.ANY, + user_config_data['replay_dir'], + 'fake-repo-tmpl', + mocker.ANY, ) @@ -46,11 +51,14 @@ def test_replay_load_template_name( mocker.patch('cookiecutter.main.generate_files') cookiecutter( - '.', replay=True, config_file=user_config_file, + '.', + replay=True, + config_file=user_config_file, ) mock_replay_load.assert_called_once_with( - user_config_data['replay_dir'], 'fake-repo-tmpl', + user_config_data['replay_dir'], + 'fake-repo-tmpl', ) @@ -62,9 +70,12 @@ def test_custom_replay_file(monkeypatch, mocker, user_config_file): mocker.patch('cookiecutter.main.generate_files') cookiecutter( - '.', replay='./custom-replay-file', config_file=user_config_file, + '.', + replay='./custom-replay-file', + config_file=user_config_file, ) mock_replay_load.assert_called_once_with( - '.', 'custom-replay-file', + '.', + 'custom-replay-file', ) diff --git a/tests/test_prompt.py b/tests/test_prompt.py index 0932ab573..8187cb283 100644 --- a/tests/test_prompt.py +++ b/tests/test_prompt.py @@ -80,7 +80,8 @@ class TestPrompt(object): def test_prompt_for_config(self, monkeypatch, context): """Verify `prompt_for_config` call `read_user_variable` on text request.""" monkeypatch.setattr( - 'cookiecutter.prompt.read_user_variable', lambda var, default: default, + 'cookiecutter.prompt.read_user_variable', + lambda var, default: default, ) cookiecutter_dict = prompt.prompt_for_config(context) diff --git a/tests/test_utils.py b/tests/test_utils.py index 54d07b424..988fc3887 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -122,7 +122,8 @@ def test_prompt_should_ask_and_exit_on_user_no_answer(mocker, tmp_path): """In `prompt_and_delete()`, if the user decline to delete/reclone the \ repo, cookiecutter should exit.""" mock_read_user = mocker.patch( - 'cookiecutter.utils.read_user_yes_no', return_value=False, + 'cookiecutter.utils.read_user_yes_no', + return_value=False, ) mock_sys_exit = mocker.patch('sys.exit', return_value=True) repo_dir = Path(tmp_path, 'repo') diff --git a/tests/vcs/test_clone.py b/tests/vcs/test_clone.py index 4687ea9a2..cd4ac13d7 100644 --- a/tests/vcs/test_clone.py +++ b/tests/vcs/test_clone.py @@ -24,7 +24,8 @@ def test_clone_should_rstrip_trailing_slash_in_repo_url(mocker, clone_dir): mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True) mock_subprocess = mocker.patch( - 'cookiecutter.vcs.subprocess.check_output', autospec=True, + 'cookiecutter.vcs.subprocess.check_output', + autospec=True, ) vcs.clone('https://github.com/foo/bar/', clone_to_dir=str(clone_dir), no_input=True) @@ -44,7 +45,8 @@ def test_clone_should_abort_if_user_does_not_want_to_reclone(mocker, clone_dir): 'cookiecutter.vcs.prompt_and_delete', side_effect=SystemExit, autospec=True ) mock_subprocess = mocker.patch( - 'cookiecutter.vcs.subprocess.check_output', autospec=True, + 'cookiecutter.vcs.subprocess.check_output', + autospec=True, ) # Create repo_dir to trigger prompt_and_delete @@ -66,7 +68,8 @@ def test_clone_should_silent_exit_if_ok_to_reuse(mocker, tmpdir): 'cookiecutter.vcs.prompt_and_delete', return_value=False, autospec=True ) mock_subprocess = mocker.patch( - 'cookiecutter.vcs.subprocess.check_output', autospec=True, + 'cookiecutter.vcs.subprocess.check_output', + autospec=True, ) clone_to_dir = tmpdir.mkdir('clone') @@ -103,7 +106,8 @@ def test_clone_should_invoke_vcs_command( mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True) mock_subprocess = mocker.patch( - 'cookiecutter.vcs.subprocess.check_output', autospec=True, + 'cookiecutter.vcs.subprocess.check_output', + autospec=True, ) expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name)) diff --git a/tests/zipfile/test_unzip.py b/tests/zipfile/test_unzip.py index 0231d2b2a..2bf58b00f 100644 --- a/tests/zipfile/test_unzip.py +++ b/tests/zipfile/test_unzip.py @@ -168,7 +168,9 @@ def test_unzip_url(mocker, clone_dir): request.iter_content.return_value = mock_download() mocker.patch( - 'cookiecutter.zipfile.requests.get', return_value=request, autospec=True, + 'cookiecutter.zipfile.requests.get', + return_value=request, + autospec=True, ) output_dir = zipfile.unzip( @@ -191,7 +193,9 @@ def test_unzip_url_with_empty_chunks(mocker, clone_dir): request.iter_content.return_value = mock_download_with_empty_chunks() mocker.patch( - 'cookiecutter.zipfile.requests.get', return_value=request, autospec=True, + 'cookiecutter.zipfile.requests.get', + return_value=request, + autospec=True, ) output_dir = zipfile.unzip( @@ -214,7 +218,9 @@ def test_unzip_url_existing_cache(mocker, clone_dir): request.iter_content.return_value = mock_download() mocker.patch( - 'cookiecutter.zipfile.requests.get', return_value=request, autospec=True, + 'cookiecutter.zipfile.requests.get', + return_value=request, + autospec=True, ) # Create an existing cache of the zipfile @@ -237,7 +243,9 @@ def test_unzip_url_existing_cache_no_input(mocker, clone_dir): request.iter_content.return_value = mock_download() mocker.patch( - 'cookiecutter.zipfile.requests.get', return_value=request, autospec=True, + 'cookiecutter.zipfile.requests.get', + return_value=request, + autospec=True, ) # Create an existing cache of the zipfile @@ -261,7 +269,8 @@ def test_unzip_should_abort_if_no_redownload(mocker, clone_dir): ) mock_requests_get = mocker.patch( - 'cookiecutter.zipfile.requests.get', autospec=True, + 'cookiecutter.zipfile.requests.get', + autospec=True, ) # Create an existing cache of the zipfile From 3db109d9815a21088429ce24d3ec982c4ae8f32f Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Wed, 10 Nov 2021 09:08:03 -0800 Subject: [PATCH 13/35] Update CONTRIBUTING.md Co-authored-by: Michael Joseph --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0d484ed03..c17a916c4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -194,7 +194,7 @@ It is possible to test with specific versions of Python. To do this, the command tox -e py37,py38 ``` -Will run py.test with the python3.7 and python3.8 interpreters, for example. +This will run `py.test` with the `python3.7` and `python3.8` interpreters. ## Core Committer Guide From 8de299ebe5e97ecd909a059d3fcd2bc8ce862bdc Mon Sep 17 00:00:00 2001 From: Prathamesh Desai Date: Sat, 11 Dec 2021 22:00:06 +0530 Subject: [PATCH 14/35] Get python version from version_info tuple Co-authored-by: Sahil --- cookiecutter/cli.py | 2 +- tests/test_cli.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cookiecutter/cli.py b/cookiecutter/cli.py index 84241ac2a..6ce8f0ada 100644 --- a/cookiecutter/cli.py +++ b/cookiecutter/cli.py @@ -25,7 +25,7 @@ def version_msg(): """Return the Cookiecutter version, location and Python powering it.""" - python_version = sys.version[:3] + python_version = str(sys.version_info[0]) + '.' + str(sys.version_info[1]) location = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) message = 'Cookiecutter %(version)s from {} (Python {})' return message.format(location, python_version) diff --git a/tests/test_cli.py b/tests/test_cli.py index 623945e8b..b5c8d3c78 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -53,6 +53,8 @@ def test_cli_version(cli_runner, version_cli_flag): assert result.exit_code == 0 assert result.output.startswith('Cookiecutter') +def test_version_msg(): + print("to do") @pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir') def test_cli_error_on_existing_output_directory(cli_runner): From 3fa6b0e5071ea337950c1df6867073e6c45f9e06 Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Sat, 11 Dec 2021 10:43:58 -0800 Subject: [PATCH 15/35] Update HISTORY.md --- HISTORY.md | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 132a1e028..0760c1d2b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,10 +2,96 @@ History is important, but our current roadmap can be found [here](https://github.com/cookiecutter/cookiecutter/projects) -## 1.8.0 (Current master, in development) - -* Do not modify this file, since 1.7.1 Changes are generated on Pull request -title and will be added before release. +## 2.0.1 (2021-12-11) +### Breaking Changes + +* Release preparation for 2.0.1rc1 (#1608) @audreyfeldroy +* Replace poyo with pyyaml. (#1489) @dHannasch +* Added: Path templates will be rendered when copy_without_render used (#839) @noirbizarre +* Added: End of line detection and configuration. (#1407) @insspb +* Remove support for python2.7 (#1386) @ssbarnea + +### Minor Changes + +* Adopt setuptools-scm packaging (#1577) @ssbarnea +* Log the error message when git clone fails, not just the return code (#1505) @logworthy +* allow jinja 3.0.0 (#1548) @wouterdb +* Added uuid extension to be able to generate uuids (#1493) @jonaswre +* Alert user if choice is invalid (#1496) @dHannasch +* Replace poyo with pyyaml. (#1489) @dHannasch +* update AUTHOR lead (#1532) @HosamAlmoghraby +* Add Python 3.9 (#1478) @gliptak +* Added: --list-installed cli option, listing already downloaded cookiecutter packages (#1096) @chrisbrake +* Added: Jinja2 Environment extension on files generation stage (#1419) @insspb +* Added: --replay-file cli option, for replay file distributing (#906) @Cadair +* Added: _output_dir to cookiecutter context (#1034) @Casyfill +* Added: CLI option to ignore hooks (#992) @rgreinho +* Changed: Generated projects can use multiple type hooks at same time. (sh + py) (#974) @milonimrod +* Added: Path templates will be rendered when copy_without_render used (#839) @noirbizarre +* Added: End of line detection and configuration. (#1407) @insspb +* Making code python 3 only: Remove python2 u' sign, fix some strings (#1402) @insspb +* py3: remove futures, six and encoding (#1401) @insspb +* Render variables starting with an underscore. (#1339) @smoothml +* Tests refactoring: test_utils write issues fixed #1405 (#1406) @insspb + +### CI/CD and QA changes + +* enable branch coverage (#1542) @simobasso +* Make release-drafter diff only between master releases (#1568) @SharpEdgeMarshall +* ensure filesystem isolation during tests execution (#1564) @simobasso +* add safety ci step (#1560) @simobasso +* pre-commit: add bandit hook (#1559) @simobasso +* Replace tmpdir in favour of tmp_path (#1545) @SharpEdgeMarshall +* Fix linting in CI (#1546) @SharpEdgeMarshall +* Coverage 100% (#1526) @SharpEdgeMarshall +* Run coverage with matrix (#1521) @SharpEdgeMarshall +* Lint rst files (#1443) @ssbarnea +* Python3: Changed io.open to build-in open (PEP3116) (#1408) @insspb +* Making code python 3 only: Remove python2 u' sign, fix some strings (#1402) @insspb +* py3: remove futures, six and encoding (#1401) @insspb +* Removed: Bumpversion, setup.py arguments. (#1404) @insspb +* Tests refactoring: test_utils write issues fixed #1405 (#1406) @insspb +* Added: Automatic PyPI deploy on tag creation (#1400) @insspb +* Changed: Restored coverage reporter (#1399) @insspb + +### Documentation updates + +* Fix pull requests checklist reference (#1537) @glumia +* Fix author name (#1544) @HosamAlmoghraby +* Add missing contributors (#1535) @glumia +* Update CONTRIBUTING.md (#1529) @glumia +* Update LICENSE (#1519) @simobasso +* docs: rewrite the conditional files / directories example description. (#1437) @lyz-code +* Fix incorrect years in release history (#1473) @graue70 +* Add slugify in the default extensions list (#1470) @oncleben31 +* Renamed cookiecutter.package to API (#1442) @grrlic +* Fixed wording detail (#1427) @steltenpower +* Changed: CLI Commands documentation engine (#1418) @insspb +* Added: Example for conditional files / directories in hooks (#1397) @xyb +* Changed: README.md PyPI URLs changed to the modern PyPI last version (#1391) @brettcannon +* Fixed: Comma in README.md (#1390) @Cy-dev-tex +* Fixed: Replaced no longer maintained pipsi by pipx (#1395) @ndclt + +### Bugfixes + +* Add support for click 8.x (#1569) @cjolowicz +* Force click<8.0.0 (#1562) @SharpEdgeMarshall +* Remove direct dependency on markupsafe (#1549) @ssbarnea +* fixes prompting private rendered dicts (#1504) @juhuebner +* User's JSON parse error causes ugly Python exception #809 (#1468) @noone234 +* config: set default on missing default_context key (#1516) @simobasso +* Fixed: Values encoding on Windows (#1414) @agateau +* Fixed: Fail with gitolite repositories (#1144) @javiersanp +* MANIFEST: Fix file name extensions (#1387) @sebix + +### Deprecations + +* Removed: Bumpversion, setup.py arguments. (#1404) @insspb +* Removed support for Python 3.6 and PyPy (#1608) @audreyfeldroy + +### This release was made possible by our wonderful contributors: + +@Cadair, @Casyfill, @Cy-dev-tex, @HosamAlmoghraby, @SharpEdgeMarshall, @agateau, @audreyfeldroy, @brettcannon, @chrisbrake, @cjolowicz, @dHannasch, @gliptak, @glumia, @graue70, @grrlic, @insspb, @javiersanp, @jonaswre, @jsoref, @Jthevos, @juhuebner, @logworthy, @lyz-code, @milonimrod, @ndclt, @noirbizarre, @noone234, @oncleben31, @ozer619, @rgreinho, @sebix, @Sahil-101, @simobasso, @smoothml, @ssbarnea, @steltenpower, @wouterdb, @xyb, Christopher Wolfe and Hosam Almoghraby ( RIAG Digital ) ## 1.7.2 (2020-04-21) From 4741a0575cbe75dcf618e88ef8c3e0e3b2225e66 Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Sat, 11 Dec 2021 10:54:51 -0800 Subject: [PATCH 16/35] Bump version number to 2.0.1 Co-authored-by: Sahil Co-authored-by: Prathamesh Co-authored-by: John-Anthony --- cookiecutter/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookiecutter/__init__.py b/cookiecutter/__init__.py index 774de19bf..fd2954f2e 100644 --- a/cookiecutter/__init__.py +++ b/cookiecutter/__init__.py @@ -1,2 +1,2 @@ """Main package for Cookiecutter.""" -__version__ = "2.0.0" +__version__ = "2.0.1" From b1403ead3bcac644eb2619642dee4b325f7b8b08 Mon Sep 17 00:00:00 2001 From: Prathamesh Desai Date: Sun, 12 Dec 2021 13:18:30 +0530 Subject: [PATCH 17/35] Added test for version_msg Co-authored-by: Sahil --- .github/workflows/main.yml | 5 +++++ tests/test_cli.py | 22 ++++++++++++++++++++-- tox.ini | 1 + 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 436de42a6..b4e49ae73 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,6 +37,7 @@ jobs: - "ubuntu-py37" - "ubuntu-py38" - "ubuntu-py39" + - "ubuntu-py310" - "macos-py37" - "macos-py38" @@ -59,6 +60,10 @@ jobs: python: "3.9" os: ubuntu-latest tox_env: "py39" + - name: "ubuntu-py310" + python: "3.10" + os: ubuntu-latest + tox_env: "py310" - name: "macos-py37" python: "3.7" diff --git a/tests/test_cli.py b/tests/test_cli.py index b5c8d3c78..12ca5f5bb 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,6 +4,9 @@ import os import re +import sys + + import pytest from click.testing import CliRunner @@ -53,8 +56,23 @@ def test_cli_version(cli_runner, version_cli_flag): assert result.exit_code == 0 assert result.output.startswith('Cookiecutter') -def test_version_msg(): - print("to do") + +def test_version_msg(cli_runner, version_cli_flag): + """Verify correct output for Cookiecutter Python version.""" + result = cli_runner(version_cli_flag) + python_major_number = sys.version_info.major + python_minor_number = sys.version_info.minor + version_output_string = result.output[:-1] + version_output_string = version_output_string[-5:-1] + if version_output_string[0] == ' ': + version_output_string = version_output_string[1:] + if version_output_string[-1] == ')': + version_output_string = version_output_string[:-1] + assert ( + str(python_major_number) + '.' + str(python_minor_number) + == version_output_string + ) + @pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir') def test_cli_error_on_existing_output_directory(cli_runner): diff --git a/tox.ini b/tox.ini index 591fc50ee..b8dd5c5e1 100644 --- a/tox.ini +++ b/tox.ini @@ -4,6 +4,7 @@ envlist = py37 py38 py39 + py310 minversion = 3.14.2 requires = virtualenv >= 20.4.5 From e5e0e96a0212219e9b80210f85b464b6226c83bc Mon Sep 17 00:00:00 2001 From: Prathamesh Desai Date: Sun, 12 Dec 2021 22:21:56 +0530 Subject: [PATCH 18/35] Use f strings and add Python 3.10 CI environments Co-authored-by: Sahil --- .github/workflows/main.yml | 10 ++++++++++ cookiecutter/cli.py | 2 +- tests/test_cli.py | 13 ++++--------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b4e49ae73..12dce4e24 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,10 +42,12 @@ jobs: - "macos-py37" - "macos-py38" - "macos-py39" + - "macos-py310" - "windows-py37" - "windows-py38" - "windows-py39" + - "windows-py310" include: - name: "ubuntu-py37" @@ -77,6 +79,10 @@ jobs: python: "3.9" os: macos-latest tox_env: "py39" + - name: "macos-py310" + python: "3.10" + os: macos-latest + tox_env: "py310" - name: "windows-py37" python: "3.7" @@ -90,6 +96,10 @@ jobs: python: "3.9" os: windows-latest tox_env: "py39" + - name: "windows-py310" + python: "3.10" + os: windows-latest + tox_env: "py310" steps: - uses: actions/checkout@v2 diff --git a/cookiecutter/cli.py b/cookiecutter/cli.py index 6ce8f0ada..385e024c5 100644 --- a/cookiecutter/cli.py +++ b/cookiecutter/cli.py @@ -25,7 +25,7 @@ def version_msg(): """Return the Cookiecutter version, location and Python powering it.""" - python_version = str(sys.version_info[0]) + '.' + str(sys.version_info[1]) + python_version = f'{sys.version_info.major}.{sys.version_info.minor}' location = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) message = 'Cookiecutter %(version)s from {} (Python {})' return message.format(location, python_version) diff --git a/tests/test_cli.py b/tests/test_cli.py index 12ca5f5bb..180314373 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -51,14 +51,14 @@ def version_cli_flag(request): def test_cli_version(cli_runner, version_cli_flag): - """Verify correct version output by `cookiecutter` on cli invocation.""" + """Verify Cookiecutter version output by `cookiecutter` on cli invocation.""" result = cli_runner(version_cli_flag) assert result.exit_code == 0 assert result.output.startswith('Cookiecutter') -def test_version_msg(cli_runner, version_cli_flag): - """Verify correct output for Cookiecutter Python version.""" +def test_cli_version_python(cli_runner, version_cli_flag): + """Verify correct Python version output by `cookiecutter` on cli invocation.""" result = cli_runner(version_cli_flag) python_major_number = sys.version_info.major python_minor_number = sys.version_info.minor @@ -66,12 +66,7 @@ def test_version_msg(cli_runner, version_cli_flag): version_output_string = version_output_string[-5:-1] if version_output_string[0] == ' ': version_output_string = version_output_string[1:] - if version_output_string[-1] == ')': - version_output_string = version_output_string[:-1] - assert ( - str(python_major_number) + '.' + str(python_minor_number) - == version_output_string - ) + assert f'{python_major_number}.{python_minor_number}' == version_output_string @pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir') From 8a7a6f51688940a67c397de0396d51a696dbcece Mon Sep 17 00:00:00 2001 From: Prathamesh Desai Date: Sat, 18 Dec 2021 22:56:09 +0530 Subject: [PATCH 19/35] Prints the whole sys.version string Co-authored-by: Sahil --- cookiecutter/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookiecutter/cli.py b/cookiecutter/cli.py index 385e024c5..6b3c583ad 100644 --- a/cookiecutter/cli.py +++ b/cookiecutter/cli.py @@ -25,7 +25,7 @@ def version_msg(): """Return the Cookiecutter version, location and Python powering it.""" - python_version = f'{sys.version_info.major}.{sys.version_info.minor}' + python_version = sys.version location = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) message = 'Cookiecutter %(version)s from {} (Python {})' return message.format(location, python_version) From cfef5740e47ec5be22be6edb51b4d919a5a724ad Mon Sep 17 00:00:00 2001 From: Prathamesh Desai Date: Sat, 18 Dec 2021 23:11:23 +0530 Subject: [PATCH 20/35] Removed python_version_test Co-authored-by: Sahil --- tests/test_cli.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 180314373..6bf093522 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -57,18 +57,6 @@ def test_cli_version(cli_runner, version_cli_flag): assert result.output.startswith('Cookiecutter') -def test_cli_version_python(cli_runner, version_cli_flag): - """Verify correct Python version output by `cookiecutter` on cli invocation.""" - result = cli_runner(version_cli_flag) - python_major_number = sys.version_info.major - python_minor_number = sys.version_info.minor - version_output_string = result.output[:-1] - version_output_string = version_output_string[-5:-1] - if version_output_string[0] == ' ': - version_output_string = version_output_string[1:] - assert f'{python_major_number}.{python_minor_number}' == version_output_string - - @pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir') def test_cli_error_on_existing_output_directory(cli_runner): """Test cli invocation without `overwrite-if-exists` fail if dir exist.""" From 11743af681e37a998748f69d646661b7a2043ff0 Mon Sep 17 00:00:00 2001 From: Prathamesh Desai Date: Sat, 18 Dec 2021 23:17:36 +0530 Subject: [PATCH 21/35] Fixed linting errors Co-authored-by: Sahil --- tests/test_cli.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 6bf093522..19740ef26 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -4,8 +4,6 @@ import os import re -import sys - import pytest from click.testing import CliRunner From db5fce2ee25b5ece417c12dddfc712beaace61fe Mon Sep 17 00:00:00 2001 From: Prathamesh Desai Date: Mon, 27 Dec 2021 23:16:19 +0530 Subject: [PATCH 22/35] Removed changes related to setuptools_scm --- .github/workflows/main.yml | 2 - pyproject.toml | 12 ------ setup.cfg | 77 +---------------------------------- setup.py | 83 ++++++++++++++++++++++++++++++++------ tox.ini | 25 ------------ 5 files changed, 71 insertions(+), 128 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 12dce4e24..8fb12c2b4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,8 +24,6 @@ jobs: pip install tox virtualenv - name: Lint run: "tox -e lint" - - name: Packaging - run: "tox -e packaging" - name: Safety run: "tox -e safety" build: diff --git a/pyproject.toml b/pyproject.toml index 26bea3f21..2240e4443 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,17 +1,5 @@ -[build-system] -requires = [ - "setuptools >= 42.0.0", # required by pyproject+setuptools_scm integration - "setuptools_scm[toml] >= 3.5.0", # required for "no-local-version" scheme - "setuptools_scm_git_archive >= 1.0", - "wheel", -] -build-backend = "setuptools.build_meta" - [tool.black] skip-string-normalization = true exclude = '/(tests/hooks-abort-render/hooks|docs\/HelloCookieCutter1)/' line-length = 88 target-version = ['py39'] - -[tool.setuptools_scm] -local_scheme = "no-local-version" diff --git a/setup.cfg b/setup.cfg index e1ddc4fbb..6d65158d3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,78 +1,3 @@ -[metadata] -name = cookiecutter -url = https://github.com/cookiecutter/cookiecutter -project_urls = - Bug Tracker = https://github.com/cookiecutter/cookiecutter/issues - CI: GitHub = https://github.com/cookiecutter/cookiecutter/actions - Documentation = https://cookiecutter.readthedocs.io/ - Source Code = https://github.com/cookiecutter/cookiecutter -description = - A command-line utility that creates projects from project - templates, e.g. creating a Python package project from a - Python package project template. -long_description = file: README.md -long_description_content_type = text/markdown -author = Audrey Roy Greenfeld -author_email = audreyr@gmail.com -maintainer = Audrey Roy Greenfeld -maintainer_email = audreyr@gmail.com -license = BSD -license_file = LICENSE -classifiers = - Development Status :: 5 - Production/Stable - Environment :: Console - Intended Audience :: Developers - Natural Language :: English - License :: OSI Approved :: BSD License - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: Implementation :: CPython - Programming Language :: Python - Topic :: Software Development -keywords = - cookiecutter - Python - projects - project templates - Jinja2 - skeleton - scaffolding - project directory - package - packaging - -[options] -use_scm_version = True -python_requires = >=3.6 -; package_dir = -; = src -packages = cookiecutter -zip_safe = False - -# These are required during `setup.py` run: -setup_requires = - setuptools_scm>=1.15.0 - setuptools_scm_git_archive>=1.0 - -install_requires = - binaryornot>=0.4.4 - Jinja2>=2.7,<4.0.0 - click>=7.0,<9.0.0 - pyyaml>=5.3.1 - jinja2-time>=0.2.0 - python-slugify>=4.0.0 - requests>=2.23.0 - -[options.entry_points] -console_scripts = - cookiecutter = cookiecutter.__main__:main - -[flake8] -ignore = BLK100,E231,W503 - # Excludes due to known issues or incompatibilities with black: # BLK100: Black would make changes. https://pypi.org/project/flake8-black/ # W503: https://github.com/psf/black/search?q=W503&unscoped_q=W503 @@ -83,7 +8,7 @@ statistics = 1 max-line-length = 88 [bdist_wheel] -universal = false +universal = 1 [tool:pytest] testpaths = tests diff --git a/setup.py b/setup.py index 5a2d616e8..c2db2f187 100644 --- a/setup.py +++ b/setup.py @@ -1,13 +1,70 @@ -#! /usr/bin/env python3 -"""cookiecutter distutils configuration. - -The presence of this file ensures the support -of pip editable mode *with setuptools only*. -""" -import setuptools - -# https://github.com/jazzband/pip-tools/issues/1278 -setuptools.setup( - use_scm_version={"local_scheme": "no-local-version"}, - setup_requires=["setuptools_scm[toml]>=3.5.0"], -) +#!/usr/bin/env python +"""cookiecutter distutils configuration.""" +from setuptools import setup + +version = "2.0.0" + +with open('README.md', encoding='utf-8') as readme_file: + readme = readme_file.read() + +requirements = [ + 'binaryornot>=0.4.4', + 'Jinja2>=2.7,<4.0.0', + 'click>=7.0,<8.0.0', + 'pyyaml>=5.3.1', + 'jinja2-time>=0.2.0', + 'python-slugify>=4.0.0', + 'requests>=2.23.0', +] + +setup( + name='cookiecutter', + version=version, + description=( + 'A command-line utility that creates projects from project ' + 'templates, e.g. creating a Python package project from a ' + 'Python package project template.' + ), + long_description=readme, + long_description_content_type='text/markdown', + author='Audrey Feldroy', + author_email='audreyr@gmail.com', + url='https://github.com/cookiecutter/cookiecutter', + packages=['cookiecutter'], + package_dir={'cookiecutter': 'cookiecutter'}, + entry_points={'console_scripts': ['cookiecutter = cookiecutter.__main__:main']}, + include_package_data=True, + python_requires='>=3.6', + install_requires=requirements, + license='BSD', + zip_safe=False, + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Intended Audience :: Developers", + "Natural Language :: English", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Programming Language :: Python", + "Topic :: Software Development", + ], + keywords=[ + "cookiecutter", + "Python", + "projects", + "project templates", + "Jinja2", + "skeleton", + "scaffolding", + "project directory", + "package", + "packaging", + ], +) \ No newline at end of file diff --git a/tox.ini b/tox.ini index b8dd5c5e1..4cde29296 100644 --- a/tox.ini +++ b/tox.ini @@ -42,28 +42,3 @@ commands = safety check --full-report deps = safety - -[testenv:packaging] -description = - Build package, verify metadata, install package and assert behavior when ansible is missing. -deps = - build - twine -skip_install = true -commands = - {envpython} -c 'import os.path, shutil, sys; \ - dist_dir = os.path.join("{toxinidir}", "dist"); \ - os.path.isdir(dist_dir) or sys.exit(0); \ - print("Removing \{!s\} contents...".format(dist_dir), file=sys.stderr); \ - shutil.rmtree(dist_dir)' - # build using moder python build (PEP-517) - {envpython} -m build \ - --sdist \ - --wheel \ - --outdir {toxinidir}/dist/ \ - {toxinidir} - # Validate metadata using twine - twine check {toxinidir}/dist/* - # Install the wheel - sh -c "python3 -m pip install {toxinidir}/dist/*.whl" -whitelist_externals = sh From c578dce794956641b5f3baa86e804b0ccad1276f Mon Sep 17 00:00:00 2001 From: Prathamesh Desai Date: Mon, 27 Dec 2021 23:29:39 +0530 Subject: [PATCH 23/35] Fixed flake8 section in setup.cfg --- setup.cfg | 3 ++- setup.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index 6d65158d3..938b39de6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,8 +1,9 @@ +[flake8] # Excludes due to known issues or incompatibilities with black: # BLK100: Black would make changes. https://pypi.org/project/flake8-black/ # W503: https://github.com/psf/black/search?q=W503&unscoped_q=W503 # E231: https://github.com/psf/black/issues/1202 - +ignore = BLK100,E231,W503 statistics = 1 # black official is 88 max-line-length = 88 diff --git a/setup.py b/setup.py index c2db2f187..654010fa0 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ install_requires=requirements, license='BSD', zip_safe=False, - classifiers=[ + classifiers=[ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", @@ -67,4 +67,4 @@ "package", "packaging", ], -) \ No newline at end of file +) From 333b6ef9f9d898cb1f2d1363acad4519d8449004 Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Mon, 27 Dec 2021 10:23:48 -0800 Subject: [PATCH 24/35] Release 2.0.2 --- HISTORY.md | 6 +++++- cookiecutter/__init__.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 0760c1d2b..d9b1a5a28 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,10 @@ History is important, but our current roadmap can be found [here](https://github.com/cookiecutter/cookiecutter/projects) +## 2.0.2 (2021-12-27) + +* Fix Python version number in cookiecutter --version and test on Python 3.10 (#1621) @ozer550 + ## 2.0.1 (2021-12-11) ### Breaking Changes @@ -91,7 +95,7 @@ History is important, but our current roadmap can be found [here](https://github ### This release was made possible by our wonderful contributors: -@Cadair, @Casyfill, @Cy-dev-tex, @HosamAlmoghraby, @SharpEdgeMarshall, @agateau, @audreyfeldroy, @brettcannon, @chrisbrake, @cjolowicz, @dHannasch, @gliptak, @glumia, @graue70, @grrlic, @insspb, @javiersanp, @jonaswre, @jsoref, @Jthevos, @juhuebner, @logworthy, @lyz-code, @milonimrod, @ndclt, @noirbizarre, @noone234, @oncleben31, @ozer619, @rgreinho, @sebix, @Sahil-101, @simobasso, @smoothml, @ssbarnea, @steltenpower, @wouterdb, @xyb, Christopher Wolfe and Hosam Almoghraby ( RIAG Digital ) +@Cadair, @Casyfill, @Cy-dev-tex, @HosamAlmoghraby, @SharpEdgeMarshall, @agateau, @audreyfeldroy, @brettcannon, @chrisbrake, @cjolowicz, @dHannasch, @gliptak, @glumia, @graue70, @grrlic, @insspb, @javiersanp, @jonaswre, @jsoref, @Jthevos, @juhuebner, @logworthy, @lyz-code, @milonimrod, @ndclt, @noirbizarre, @noone234, @oncleben31, @ozer550, @rgreinho, @sebix, @Sahil-101, @simobasso, @smoothml, @ssbarnea, @steltenpower, @wouterdb, @xyb, Christopher Wolfe and Hosam Almoghraby ( RIAG Digital ) ## 1.7.2 (2020-04-21) diff --git a/cookiecutter/__init__.py b/cookiecutter/__init__.py index fd2954f2e..eab68df8e 100644 --- a/cookiecutter/__init__.py +++ b/cookiecutter/__init__.py @@ -1,2 +1,2 @@ """Main package for Cookiecutter.""" -__version__ = "2.0.1" +__version__ = "2.0.2" From 0b406256d2c0aa728f860692d57f49c0d2beb39d Mon Sep 17 00:00:00 2001 From: Audrey Roy Greenfeld Date: Mon, 27 Dec 2021 10:28:18 -0800 Subject: [PATCH 25/35] Update 2.0.2 release notes --- HISTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.md b/HISTORY.md index d9b1a5a28..5fc9fd5a9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,7 @@ History is important, but our current roadmap can be found [here](https://github ## 2.0.2 (2021-12-27) * Fix Python version number in cookiecutter --version and test on Python 3.10 (#1621) @ozer550 +* Removed changes related to setuptools_scm (#1629) @audreyfeldroy @ozer550 ## 2.0.1 (2021-12-11) ### Breaking Changes From c0e7698097d905938cd9ecd1a08d9a2c99c4f887 Mon Sep 17 00:00:00 2001 From: Marco Westerhof Date: Fri, 18 Mar 2022 17:04:19 +0100 Subject: [PATCH 26/35] Feature/local extensions (#1240) Co-authored-by: Andrey Shpak --- cookiecutter/main.py | 47 ++++++++++----- cookiecutter/utils.py | 13 ++++ docs/advanced/index.rst | 1 + docs/advanced/local_extensions.rst | 60 +++++++++++++++++++ .../local_extension/cookiecutter.json | 10 ++++ .../local_extensions/__init__.py | 1 + .../local_extension/local_extensions/main.py | 21 +++++++ .../{{cookiecutter.project_slug}}/HISTORY.rst | 8 +++ tests/test_cli.py | 31 ++++++++++ 9 files changed, 178 insertions(+), 14 deletions(-) create mode 100644 docs/advanced/local_extensions.rst create mode 100644 tests/test-extensions/local_extension/cookiecutter.json create mode 100644 tests/test-extensions/local_extension/local_extensions/__init__.py create mode 100644 tests/test-extensions/local_extension/local_extensions/main.py create mode 100644 tests/test-extensions/local_extension/{{cookiecutter.project_slug}}/HISTORY.rst diff --git a/cookiecutter/main.py b/cookiecutter/main.py index 7c9eef731..bc2f262df 100644 --- a/cookiecutter/main.py +++ b/cookiecutter/main.py @@ -4,8 +4,10 @@ The code in this module is also a good example of how to use Cookiecutter as a library rather than a script. """ +from copy import copy import logging import os +import sys from cookiecutter.config import get_user_config from cookiecutter.exceptions import InvalidModeException @@ -73,15 +75,17 @@ def cookiecutter( password=password, directory=directory, ) + import_patch = _patch_import_path_for_repo(repo_dir) template_name = os.path.basename(os.path.abspath(repo_dir)) if replay: - if isinstance(replay, bool): - context = load(config_dict['replay_dir'], template_name) - else: - path, template_name = os.path.split(os.path.splitext(replay)[0]) - context = load(path, template_name) + with import_patch: + if isinstance(replay, bool): + context = load(config_dict['replay_dir'], template_name) + else: + path, template_name = os.path.split(os.path.splitext(replay)[0]) + context = load(path, template_name) else: context_file = os.path.join(repo_dir, 'cookiecutter.json') logger.debug('context_file is %s', context_file) @@ -94,7 +98,8 @@ def cookiecutter( # prompt the user to manually configure at the command line. # except when 'no-input' flag is set - context['cookiecutter'] = prompt_for_config(context, no_input) + with import_patch: + context['cookiecutter'] = prompt_for_config(context, no_input) # include template dir or url in the context dict context['cookiecutter']['_template'] = template @@ -105,17 +110,31 @@ def cookiecutter( dump(config_dict['replay_dir'], template_name, context) # Create project from local context and project template. - result = generate_files( - repo_dir=repo_dir, - context=context, - overwrite_if_exists=overwrite_if_exists, - skip_if_file_exists=skip_if_file_exists, - output_dir=output_dir, - accept_hooks=accept_hooks, - ) + with import_patch: + result = generate_files( + repo_dir=repo_dir, + context=context, + overwrite_if_exists=overwrite_if_exists, + skip_if_file_exists=skip_if_file_exists, + output_dir=output_dir, + accept_hooks=accept_hooks, + ) # Cleanup (if required) if cleanup: rmtree(repo_dir) return result + + +class _patch_import_path_for_repo: + def __init__(self, repo_dir): + self._repo_dir = repo_dir + self._path = None + + def __enter__(self): + self._path = copy(sys.path) + sys.path.append(self._repo_dir) + + def __exit__(self, type, value, traceback): + sys.path = self._path diff --git a/cookiecutter/utils.py b/cookiecutter/utils.py index 19b727a52..ef533171a 100644 --- a/cookiecutter/utils.py +++ b/cookiecutter/utils.py @@ -8,6 +8,7 @@ import sys from cookiecutter.prompt import read_user_yes_no +from jinja2.ext import Extension logger = logging.getLogger(__name__) @@ -105,3 +106,15 @@ def prompt_and_delete(path, no_input=False): return False sys.exit() + + +def simple_filter(filter_function): + """Decorate a function to wrap it in a simplified jinja2 extension.""" + + class SimpleFilterExtension(Extension): + def __init__(self, environment): + super(SimpleFilterExtension, self).__init__(environment) + environment.filters[filter_function.__name__] = filter_function + + SimpleFilterExtension.__name__ = filter_function.__name__ + return SimpleFilterExtension diff --git a/docs/advanced/index.rst b/docs/advanced/index.rst index 90e7f2933..66d5faadd 100644 --- a/docs/advanced/index.rst +++ b/docs/advanced/index.rst @@ -23,3 +23,4 @@ Various advanced topics regarding cookiecutter usage. template_extensions directories new_line_characters + local_extensions diff --git a/docs/advanced/local_extensions.rst b/docs/advanced/local_extensions.rst new file mode 100644 index 000000000..bf87caf7b --- /dev/null +++ b/docs/advanced/local_extensions.rst @@ -0,0 +1,60 @@ +.. _`template extensions`: + +Local Extensions +---------------- + +*New in Cookiecutter X.x* + +A template may extend the Cookiecutter environment with local extensions. +These can be part of the template itself, providing it with more sophisticated custom tags and filters. + +To do so, a template author must specify the required extensions in ``cookiecutter.json`` as follows: + +.. code-block:: json + + { + "project_slug": "Foobar", + "year": "{% now 'utc', '%Y' %}", + "_extensions": ["local_extensions.FoobarExtension"] + } + +This example assumes that a ``local_extensions`` folder (python module) exists in the template root. +It will contain a ``main.py`` file, containing the following (for instance): + +.. code-block:: python + + # -*- coding: utf-8 -*- + + from jinja2.ext import Extension + + + class FoobarExtension(Extension): + def __init__(self, environment): + super(FoobarExtension, self).__init__(environment) + environment.filters['foobar'] = lambda v: v * 2 + +This will register the ``foobar`` filter for the template. + +For many cases, this will be unneccessarily complicated. It's likely that we'd only want to register a single function +as a filter. For this, we can use the ``simple_filter`` decorator: + +.. code-block:: json + + { + "project_slug": "Foobar", + "year": "{% now 'utc', '%Y' %}", + "_extensions": ["local_extensions.simplefilterextension"] + } + +.. code-block:: python + + # -*- coding: utf-8 -*- + + from cookiecutter.utils import simple_filter + + + @simple_filter + def simplefilterextension(v): + return v * 2 + +This snippet will achieve the exact same result as the previous one. diff --git a/tests/test-extensions/local_extension/cookiecutter.json b/tests/test-extensions/local_extension/cookiecutter.json new file mode 100644 index 000000000..8141fd508 --- /dev/null +++ b/tests/test-extensions/local_extension/cookiecutter.json @@ -0,0 +1,10 @@ +{ + "project_slug": "Foobar", + "test_value_class_based": "{{cookiecutter.project_slug | foobar}}", + "test_value_function_based": "{{cookiecutter.project_slug | simplefilterextension}}", + "_extensions": [ + "local_extensions.simplefilterextension", + "local_extensions.FoobarExtension" + ] +} + diff --git a/tests/test-extensions/local_extension/local_extensions/__init__.py b/tests/test-extensions/local_extension/local_extensions/__init__.py new file mode 100644 index 000000000..94e854abd --- /dev/null +++ b/tests/test-extensions/local_extension/local_extensions/__init__.py @@ -0,0 +1 @@ +from .main import FoobarExtension, simplefilterextension # noqa diff --git a/tests/test-extensions/local_extension/local_extensions/main.py b/tests/test-extensions/local_extension/local_extensions/main.py new file mode 100644 index 000000000..53f6f8f95 --- /dev/null +++ b/tests/test-extensions/local_extension/local_extensions/main.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +"""Provides custom extension, exposing a ``foobar`` filter.""" + +from jinja2.ext import Extension +from cookiecutter.utils import simple_filter + + +class FoobarExtension(Extension): + """Simple jinja2 extension for cookiecutter test purposes.""" + + def __init__(self, environment): + """Foobar Extension Constructor.""" + super(FoobarExtension, self).__init__(environment) + environment.filters['foobar'] = lambda v: v * 2 + + +@simple_filter +def simplefilterextension(v): + """Provide a simple function-based filter extension.""" + return v.upper() diff --git a/tests/test-extensions/local_extension/{{cookiecutter.project_slug}}/HISTORY.rst b/tests/test-extensions/local_extension/{{cookiecutter.project_slug}}/HISTORY.rst new file mode 100644 index 000000000..8bb7c6136 --- /dev/null +++ b/tests/test-extensions/local_extension/{{cookiecutter.project_slug}}/HISTORY.rst @@ -0,0 +1,8 @@ +History +------- + +0.1.0 +----- + +First release of {{cookiecutter.test_value_class_based}} on PyPI. +{{cookiecutter.test_value_function_based}} diff --git a/tests/test_cli.py b/tests/test_cli.py index 19740ef26..ad6abd1e0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -10,6 +10,8 @@ from cookiecutter import utils from cookiecutter.__main__ import main +from cookiecutter.environment import StrictEnvironment +from cookiecutter.exceptions import UnknownExtension from cookiecutter.main import cookiecutter @@ -412,6 +414,35 @@ def test_echo_unknown_extension_error(output_dir, cli_runner): assert 'Unable to load extension: ' in result.output +def test_local_extension(tmpdir, cli_runner): + """Test to verify correct work of extension, included in template.""" + output_dir = str(tmpdir.mkdir('output')) + template_path = 'tests/test-extensions/local_extension/' + + result = cli_runner( + '--no-input', + '--default-config', + '--output-dir', + output_dir, + template_path, + ) + assert result.exit_code == 0 + with open(os.path.join(output_dir, 'Foobar', 'HISTORY.rst')) as f: + data = f.read() + assert 'FoobarFoobar' in data + assert 'FOOBAR' in data + + +def test_local_extension_not_available(tmpdir, cli_runner): + """Test handling of included but unavailable local extension.""" + context = {'cookiecutter': {'_extensions': ['foobar']}} + + with pytest.raises(UnknownExtension) as err: + StrictEnvironment(context=context, keep_trailing_newline=True) + + assert 'Unable to load extension: ' in str(err.value) + + @pytest.mark.usefixtures('remove_fake_project_dir') def test_cli_extra_context(cli_runner): """Cli invocation replace content if called with replacement pairs.""" From 0711b74d03fce772c32090fcfcce74f4efd08f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20La=C5=84ski?= Date: Fri, 18 Mar 2022 17:05:16 +0100 Subject: [PATCH 27/35] Restore accidentally deleted support for click 8.x (#1643) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 654010fa0..d703c3c29 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ requirements = [ 'binaryornot>=0.4.4', 'Jinja2>=2.7,<4.0.0', - 'click>=7.0,<8.0.0', + 'click>=7.0,<9.0.0', 'pyyaml>=5.3.1', 'jinja2-time>=0.2.0', 'python-slugify>=4.0.0', From 603b0365689d8b5407fed4d6475e1eb8256fdf33 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Fri, 18 Mar 2022 16:08:39 +0000 Subject: [PATCH 28/35] Update badge & links from Slack to Discord in README (#1612) Co-authored-by: Michael Joseph Co-authored-by: Sorin Sbarnea --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9b1dfe141..8e7e2b240 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![python](https://img.shields.io/pypi/pyversions/cookiecutter.svg)](https://pypi.org/project/cookiecutter/) [![Build Status](https://github.com/cookiecutter/cookiecutter/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/cookiecutter/cookiecutter/actions) [![codecov](https://codecov.io/gh/cookiecutter/cookiecutter/branch/master/graphs/badge.svg?branch=master)](https://codecov.io/github/cookiecutter/cookiecutter?branch=master) -[![slack](https://img.shields.io/badge/cookiecutter-Join%20on%20Slack-green?style=flat&logo=slack)](https://join.slack.com/t/cookie-cutter/shared_invite/enQtNzI0Mzg5NjE5Nzk5LTRlYWI2YTZhYmQ4YmU1Y2Q2NmE1ZjkwOGM0NDQyNTIwY2M4ZTgyNDVkNjMxMDdhZGI5ZGE5YmJjM2M3ODJlY2U) +[![discord](https://img.shields.io/badge/Discord-cookiecutter-5865F2?style=flat&logo=discord&logoColor=white)](https://discord.gg/9BrxzPKuEW) [![docs](https://readthedocs.org/projects/cookiecutter/badge/?version=latest)](https://readthedocs.org/projects/cookiecutter/?badge=latest) [![Code Quality](https://img.shields.io/scrutinizer/g/cookiecutter/cookiecutter.svg)](https://scrutinizer-ci.com/g/cookiecutter/cookiecutter/?branch=master) @@ -178,7 +178,7 @@ Stuck? Try one of the following: about the problem, even if it's just "I can't get it to work on this cookiecutter" with a link to your cookiecutter. Don't worry about naming/pinpointing the issue properly. -- Ask for help on [Slack](https://join.slack.com/t/cookie-cutter/shared_invite/enQtNzI0Mzg5NjE5Nzk5LTRlYWI2YTZhYmQ4YmU1Y2Q2NmE1ZjkwOGM0NDQyNTIwY2M4ZTgyNDVkNjMxMDdhZGI5ZGE5YmJjM2M3ODJlY2U) +- Ask for help on [Discord](https://discord.gg/9BrxzPKuEW) if you must (but please try one of the other options first, so that others can benefit from the discussion). @@ -189,8 +189,8 @@ Development on Cookiecutter is community-driven: - Everyone is invited to contribute. Read the [contributing instructions](CONTRIBUTING.md), then get started. - Connect with other Cookiecutter contributors and users on - [Slack](https://join.slack.com/t/cookie-cutter/shared_invite/enQtNzI0Mzg5NjE5Nzk5LTRlYWI2YTZhYmQ4YmU1Y2Q2NmE1ZjkwOGM0NDQyNTIwY2M4ZTgyNDVkNjMxMDdhZGI5ZGE5YmJjM2M3ODJlY2U) - (note: due to work and commitments, a core committer might not always be available) + [Discord](https://discord.gg/9BrxzPKuEW) + (note: due to work and other commitments, a core committer might not always be available) Encouragement is unbelievably motivating. If you want more work done on Cookiecutter, show support: From 682fe854dca3ce735d656a6588e9ea9369c4ea47 Mon Sep 17 00:00:00 2001 From: Prathamesh Desai Date: Fri, 18 Mar 2022 21:39:24 +0530 Subject: [PATCH 29/35] Improve local development step 3 (#1610) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c17a916c4..f54ae0e06 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -74,7 +74,7 @@ git clone git@github.com:your_name_here/cookiecutter.git ```bash cd cookiecutter/ -python setup.py develop +pip install -e . ``` 4. Create a branch for local development: From 980ff089efaef27b99b97525f6a206bd7c3f2282 Mon Sep 17 00:00:00 2001 From: Maciej Patro Date: Sat, 7 May 2022 09:55:59 +0200 Subject: [PATCH 30/35] test_generate_file_verbose_template_syntax_error fixed Fixes #1655 - relative path that comes directly from Jinja2 TemplateSyntaxError in some cases is in format "./tests/..." in other "tests/... now both cases are accepted as a valid outcome. --- tests/test_generate_file.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_generate_file.py b/tests/test_generate_file.py index 2ca30dff2..943399939 100644 --- a/tests/test_generate_file.py +++ b/tests/test_generate_file.py @@ -1,6 +1,7 @@ """Tests for `generate_file` function, part of `generate_files` function workflow.""" import json import os +import re import pytest from jinja2 import FileSystemLoader @@ -114,17 +115,16 @@ def test_generate_file_with_false_condition(env): @pytest.fixture -def expected_msg(): +def expected_msg_regex(): """Fixture. Used to ensure that exception generated text contain full data.""" - msg = ( + return re.compile( 'Missing end of comment tag\n' - ' File "./tests/files/syntax_error.txt", line 1\n' - ' I eat {{ syntax_error }} {# this comment is not closed}' + ' {2}File "(.[/\\\\])*tests[/\\\\]files[/\\\\]syntax_error.txt", line 1\n' + ' {4}I eat {{ syntax_error }} {# this comment is not closed}' ) - return msg.replace("/", os.sep) -def test_generate_file_verbose_template_syntax_error(env, expected_msg): +def test_generate_file_verbose_template_syntax_error(env, expected_msg_regex): """Verify correct exception raised on syntax error in file before generation.""" with pytest.raises(TemplateSyntaxError) as exception: generate.generate_file( @@ -133,7 +133,7 @@ def test_generate_file_verbose_template_syntax_error(env, expected_msg): context={'syntax_error': 'syntax_error'}, env=env, ) - assert str(exception.value) == expected_msg + assert expected_msg_regex.match(str(exception.value)) is not None def test_generate_file_does_not_translate_lf_newlines_to_crlf(env, tmp_path): From 6eb9ea81be1fed3d58197800630e07e14380f7a4 Mon Sep 17 00:00:00 2001 From: Maciej Patro Date: Mon, 16 May 2022 21:31:44 +0200 Subject: [PATCH 31/35] Remove redundant comparison Co-authored-by: jurgenwigg <53076001+jurgenwigg@users.noreply.github.com> --- tests/test_generate_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_generate_file.py b/tests/test_generate_file.py index 943399939..a393a2ef8 100644 --- a/tests/test_generate_file.py +++ b/tests/test_generate_file.py @@ -133,7 +133,7 @@ def test_generate_file_verbose_template_syntax_error(env, expected_msg_regex): context={'syntax_error': 'syntax_error'}, env=env, ) - assert expected_msg_regex.match(str(exception.value)) is not None + assert expected_msg_regex.match(str(exception.value)) def test_generate_file_does_not_translate_lf_newlines_to_crlf(env, tmp_path): From 05267c6aac1ee5027c422c086dfbd9fbf867b8bf Mon Sep 17 00:00:00 2001 From: Maciej Patro Date: Mon, 16 May 2022 21:42:20 +0200 Subject: [PATCH 32/35] Fix black incompatibility with click 8.1.0 version --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ce7d43cfc..1ba7fa3e1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: files: \.rst$ require_serial: true - repo: https://github.com/psf/black.git - rev: 21.10b0 + rev: 22.3.0 hooks: - id: black language_version: python3 From 2b6de977046b8d3aeed7f2fd4d1841b59e6396f9 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Tue, 24 May 2022 10:37:05 -0700 Subject: [PATCH 33/35] Add Audrey Roy Greenfeld as creator and leader --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 8e7e2b240..6a153c097 100644 --- a/README.md +++ b/README.md @@ -233,3 +233,7 @@ organizations and individuals to support the project. Everyone interacting in the Cookiecutter project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [PyPA Code of Conduct](https://www.pypa.io/en/latest/code-of-conduct/). + +## Creator / Leader + +This project was created and is led by [Audrey Roy Greenfeld](https://github.com/audreyfeldroy). From 43ccfcc8e6cfdc41644119678a827b9c1cf524e6 Mon Sep 17 00:00:00 2001 From: Daniel Roy Greenfeld Date: Tue, 24 May 2022 10:37:19 -0700 Subject: [PATCH 34/35] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 6a153c097..a954feca2 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,6 @@ template. ![Cookiecutter](https://raw.githubusercontent.com/cookiecutter/cookiecutter/3ac078356adf5a1a72042dfe72ebfa4a9cd5ef38/logo/cookiecutter_medium.png) -We are proud to be an open source sponsor of -[PyCon 2016](https://us.pycon.org/2016/sponsors/). - ## Features - Cross-platform: Windows, Mac, and Linux are officially supported. From 050246683e2b95f35898c013fff6d14a51c2b5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20C=2E=20Barrionuevo=20da=20Luz?= Date: Sun, 29 May 2022 16:08:17 -0300 Subject: [PATCH 35/35] Fixed incorrect link on docs. (#1649) Close #1648 --- docs/advanced/choice_variables.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/advanced/choice_variables.rst b/docs/advanced/choice_variables.rst index c86eb11c1..ccb35d4bf 100644 --- a/docs/advanced/choice_variables.rst +++ b/docs/advanced/choice_variables.rst @@ -39,7 +39,7 @@ can be used like this:: {% endif %} -Cookiecutter is using `Jinja2's if conditional expression `_ to determine the correct license. +Cookiecutter is using `Jinja2's if conditional expression `_ to determine the correct license. The created choice variable is still a regular Cookiecutter variable and can be used like this::