پرونده محیط encoding/envfile
خواندن و نوشتن پروندههای .env با جایگذاری متغیرها.
واردسازی کدگذاری.پرونده محیط
پروندهی .env تنظیمها و رازهای یک برنامه را به شکل یک KEY=value در هر خط نگه میدارد؛ همان قالبی که داکر کامپوز، بیشتر برنامههای دوازدهعاملی و ابزارهایی مثل dotenv به کار میبرند. این بسته چنین پروندهای را در یک سند میخواند، یعنی فهرستی مرتب از کلیدها و مقدارهای رشتهای، ارجاعهای ${NAME} را جایگذاری میکند و سند را دوباره به متن مینویسد.
این بسته روی متن کار میکند و به محیط فرایند دست نمیزند. اگر فقط میخواهید متغیرهای یک پروندهی .env در دسترس برنامه باشند، محیط.بارگذاری(مسیر) در بستهی محیط با یک فراخوانی آنها را در محیط میگذارد (و محیط.بارگذاری اجباری پرونده را بر متغیرهایی که از قبل تنظیم شدهاند مقدم میکند). پیکربندی.بارگذاری محیط در بستهی پیکربندی پرونده را در یک پیکربندی با خوانندههای نوعدار مثل دریافت صحیح و دریافت منطقی میخواند. این بسته را وقتی به کار ببرید که خود پرونده را لازم دارید: ترتیبش، ارجاعهایش، بررسی سختگیرانه یا نوشتن دوبارهاش. برای تنظیمهای تودرتو با عدد و فهرست، تامل یا یامل مناسبترند.
در هر خط چه میتواند بیاید
- خطهای خالی و خطهایی که با
#آغاز میشوند نادیده گرفته میشوند و نشانهی ترتیب بایت UTF-8 در آغاز پرونده هم کنار گذاشته میشود.exportپیش از کلید مجاز است، پس پروندهای که پوستهsourceمیکند هم تجزیه میشود. - کلیدها از حرف، رقم،
_،.و-ساخته میشوند. فاصله در دو طرف=مجاز است. - مقدار بینقلقول تا پایان خط ادامه دارد و فاصلههای انتهاییاش برداشته میشود.
#فقط پس از یک فاصله توضیح را آغاز میکند، پسhttps://x/#topنشانهی#خود را نگه میدارد. - مقدار درون نقلقول دوتایی
\n،\t،\"و\\را میفهمد، میتواند چند خط باشد و جایگذاری${NAME}را میپذیرد. مقدار درون نقلقول تکی همانطور که هست خوانده میشود، بدون گریز و بدون جایگذاری. - کلیدی که دو بار بیاید جای نخستینش را نگه میدارد و مقدار آخرش را میگیرد.
اشتباههای رایج
- همهی مقدارها رشتهاند.
PORT=8080رشتهی"8080"میدهد؛ خودتان تبدیلش کنید و یادتان باشد که"abc".به صحیح()صفر است، نه خطا. - ارجاعها فقط به بالا نگاه میکنند.
${NAME}از خطهای بالاتر حل میشود (و بعد از سندbase، اگر داده باشید). نامی که پایینتر تعریف شده یا اصلاً تعریف نشده، بیصدا رشتهی خالی میشود. بانامهای ارجاعروی خروجیتجزیه خامببینید پرونده چه نامهایی را انتظار دارد. تجزیهخطهای خراب را بیصدا رد میکند. خطی مثلSECRET KEY 8f2cبهسادگی ناپدید میشود. هنگام راهاندازی پروندهها را باتجزیه سخت گیرانهبخوانید.قالبتوضیحها را نگه نمیدارد و خطهای خالی را هم نمینویسد؛ فقط کلیدها و مقدارها میمانند.
راهنما: پیشفرضهای مشترک و رونویسی محلی
بیشتر پروژهها یک .env با پیشفرضهای بیخطر در مخزن میگذارند و هر برنامهنویس یک .env.local با درگاهها و گذرواژههای خودش نگه میدارد. هر دو را تجزیه کنید و پروندهی محلی را با ادغام در روی دیگری بریزید: کلیدهای آن جای کلیدهای مشترک را میگیرند و کلیدهایی که فقط در پروندهی مشترکاند میمانند. دریافت با پیش فرض تنظیمهایی را پوشش میدهد که در هیچکدام نیست.
واردسازی کدگذاری.پرونده محیط
تابع ریشه:
مشترک := `# committed to the repository
APP_NAME=shop
PORT=8080
LOG_LEVEL=info
DB_URL=postgres://localhost/shop
`
محلی := `# .env.local, kept out of git
PORT=9000
DB_URL=postgres://sara:secret@localhost/shop_dev
`
ناپایا پیکر := پرونده محیط.تجزیه(مشترک)
ناپایا رونویس := پرونده محیط.تجزیه(محلی)
پرونده محیط.ادغام در(پیکر، رونویس)
درگاه := پرونده محیط.دریافت(پیکر، "PORT").به صحیح()
سرچاپ پرونده محیط.دریافت(پیکر، "APP_NAME")، "روی درگاه"، درگاه
سرچاپ "سطح گزارش:"، پرونده محیط.دریافت با پیش فرض(پیکر، "LOG_LEVEL"، "warn")
سرچاپ "کارگرها:"، پرونده محیط.دریافت با پیش فرض(پیکر، "WORKERS"، "2").به صحیح()
سرچاپ "کلیدها به ترتیب:"، پرونده محیط.کلیدها(پیکر)
پرونده محیط.آزادسازی(رونویس)
پرونده محیط.آزادسازی(پیکر)
پایانهمهی مقدارها رشتهاند؛ عددها را با به صحیح() تبدیل کنید. کلید ادغامشده جای اصلیاش را نگه میدارد، پس کلیدها باز هم به ترتیب پروندهی مشترک فهرست میکند. در برنامهی واقعی دو متن از پرونده.خواندن همه در بستهی پرونده میآیند.
راهنما: توضیح، نقلقول و مقدار چندخطی
پروندههای واقعی .env توضیح، نشانیهایی با #، کلیدهای PEM چندخطی و قیمتهایی با $ را کنار هم دارند. برنامهی زیر از هر کدام یکی میخواند تا ببینید هر قاعدهی فهرست بالا کجا اثر میکند.
واردسازی کدگذاری.پرونده محیط
تابع ریشه:
متن := `export APP_NAME=shop # trailing comment
HOME_URL=https://shop.example/#top
MOTD="Welcome!\nOrders ship daily."
TLS_KEY="-----BEGIN KEY-----
MIIEvQIBADANBg
-----END KEY-----"
PRICE_NOTE='$5 off, literally'
EARLY=${LATER}
LATER=set below
PORT=8080
PORT=9090
`
ناپایا تنظیمها := پرونده محیط.تجزیه(متن)
سرچاپ "APP_NAME:"، پرونده محیط.دریافت(تنظیمها، "APP_NAME")
سرچاپ "HOME_URL:"، پرونده محیط.دریافت(تنظیمها، "HOME_URL")
سرچاپ "MOTD:"، پرونده محیط.دریافت(تنظیمها، "MOTD")
کلید := پرونده محیط.دریافت(تنظیمها، "TLS_KEY")
سرچاپ "سطرهای TLS_KEY:"، کلید.بشکاف("\n").طول()
سرچاپ "PRICE_NOTE:"، پرونده محیط.دریافت(تنظیمها، "PRICE_NOTE")
سرچاپ "EARLY: [" + پرونده محیط.دریافت(تنظیمها، "EARLY") + "]"
سرچاپ "PORT:"، پرونده محیط.دریافت(تنظیمها، "PORT")، "کلیدها:"، پرونده محیط.طول(تنظیمها)
پرونده محیط.آزادسازی(تنظیمها)
پایانتوضیح بعد از shop حذف میشود چون پیش از # فاصله آمده؛ # درون HOME_URL میماند. MOTD که در نقلقول دوتایی است \n را به شکستن واقعی خط تبدیل میکند و TLS_KEY سه خطش را نگه میدارد. EARLY خالی است چون LATER بعد از آن تعریف شده، و PORT مقدار دوم را دارد ولی یک بار شمرده میشود.
راهنما: ارجاع میان متغیرها
مقدارها میتوانند با ${NAME} یا $NAME به کلیدهای دیگر ارجاع دهند و ${NAME:-default} وقتی کلید تنظیم نشده به مقدار جایگزین برمیگردد. تجزیه ارجاعهای درون پرونده را حل میکند. برای پر کردن برخی از آنها از جای دیگر، مثلاً رازهایی که فقط کارساز میداند، پرونده را با تجزیه خام بخوانید و با گسترش سند و یک سند دوم از مقدارهای پایه حل کنید.
واردسازی کدگذاری.پرونده محیط
تابع ریشه:
متن := `DB_HOST=localhost
DB_PORT=5432
DB_NAME=shop
DATABASE_URL=postgres://${DB_USER}@${DB_HOST}:${DB_PORT}/${DB_NAME}
CACHE_URL=redis://${REDIS_HOST:-127.0.0.1}:6379
GREETING='costs $5, not expanded'
`
ناپایا خام := پرونده محیط.تجزیه خام(متن)
سرچاپ "ارجاعها:"، پرونده محیط.نامهای ارجاع(خام)
ناپایا پایه := پرونده محیط.جدید()
پرونده محیط.تنظیم(پایه، "DB_USER"، "app")
ناپایا محیط := پرونده محیط.گسترش سند(خام، پایه)
سرچاپ پرونده محیط.دریافت(محیط، "DATABASE_URL")
سرچاپ پرونده محیط.دریافت(محیط، "CACHE_URL")
سرچاپ پرونده محیط.دریافت(محیط، "GREETING")
سرچاپ "الگو:"، پرونده محیط.گسترش("${DB_NAME}_test"، محیط، پایه)
پرونده محیط.آزادسازی(محیط)
پرونده محیط.آزادسازی(پایه)
پرونده محیط.آزادسازی(خام)
پایاننقلقول تکی مثل پوسته گسترش را خاموش میکند، پس $5 همانطور که نوشته شده میماند؛ در مقدار بینقلقول یا درون نقلقول دوتایی برای علامت دلار \$ بنویسید. ${NAME:-x} وقتی نام نباشد یا خالی باشد x را به کار میبرد و ${NAME-x} فقط وقتی نام نباشد. نامهای ارجاع همهی نامهایی را که پرونده به آنها ارجاع میدهد فهرست میکند؛ راهی سریع برای اینکه به گردانندهی کارساز بگویید یک استقرار به چه متغیرهایی نیاز دارد. برای اینکه محیط خود فرایند پایه باشد، متغیرهای لازم را با محیط.دریافت از بستهی محیط در آن بریزید.
راهنما: زود شکست بخورید
تجزیه آسانگیر است و خطهایی را که نمیفهمد رد میکند. هنگام راهاندازی بهتر است با پیامی روشن بایستید: تجزیه سخت گیرانه یک خطای کدگذاری را با دلیل و جایگاه بایتی آغاز خط خراب پر میکند. پس از آن کلیدهایی را بررسی کنید که برنامه بی آنها اجرا نمیشود.
واردسازی کدگذاری.پرونده محیط
واردسازی کدگذاری.خطای کدگذاری
تابع بارگذاری(نام: رشته، متن: رشته):
ناپایا خطا := خطای کدگذاری.بدون خطا()
ناپایا سند := پرونده محیط.تجزیه سخت گیرانه(متن، خطا)
اگر خطای کدگذاری.خطا است(خطا):
سرچاپ نام، "خطا در بایت"، خطا.موقعیت، "->"، خطا.پیام
پرونده محیط.آزادسازی(سند)
برگشت
پایان
لازم := ["DB_URL"، "SECRET_KEY"]
ناپایا کمبود := ۰
هر ک در لازم:
اگر وارونه پرونده محیط.دارد(سند، ک) یا پرونده محیط.دریافت(سند، ک) == "":
سرچاپ نام، "کم دارد:"، ک
کمبود += ۱
پایان
پایان
اگر کمبود == ۰:
سرچاپ نام، "درست است با"، پرونده محیط.طول(سند)، "کلید"
پایان
پرونده محیط.آزادسازی(سند)
پایان
تابع ریشه:
بارگذاری("تولید:"، "DB_URL=postgres://db/shop\nSECRET_KEY=8f2c\n")
بارگذاری("توسعه:"، "DB_URL=postgres://localhost/shop\nSECRET_KEY=\n")
بارگذاری("غلط: "، "DB_URL=postgres://db/shop\nSECRET KEY 8f2c\n")
بارگذاری("باز: "، "DB_URL=\"postgres://db/shop\n")
پایانبرای کلیدهای لازم، مقدار خالی را مثل نبودن کلید حساب کنید، چون SECRET_KEY= باقیماندهی رایجی از پروندهی نمونه است.
راهنما: تغییر پرونده و نوشتن دوبارهی آن
ابزارهایی که تنظیمها را ویرایش میکنند، مثل یک نصبکننده، یک سند را با تنظیم و حذف تغییر میدهند و با قالب مینویسند. مقدارها فقط وقتی لازم باشد در نقلقول میآیند و نقلقولهای درونی گریزانده میشوند، پس تجزیه متن را به همان مقدارها برمیگرداند. قالب صادراتی پیش از هر خط export میگذارد، برای پروندهای که پوسته بتواند source کند.
واردسازی کدگذاری.پرونده محیط
تابع ریشه:
ناپایا سند := پرونده محیط.تجزیه("APP_NAME=shop\nPORT=8080\n")
پرونده محیط.تنظیم(سند، "PORT"، "9090")
پرونده محیط.تنظیم(سند، "WELCOME"، "Hello, \"friend\"")
پرونده محیط.تنظیم(سند، "SEARCH_URL"، "http://127.0.0.1:7700")
سرچاپ "APP_NAME حذف شد:"، پرونده محیط.حذف(سند، "APP_NAME")
چاپ پرونده محیط.قالب(سند)
سرچاپ "---"
چاپ پرونده محیط.قالب صادراتی(سند)
سرچاپ "---"
سرچاپ پرونده محیط.نقل قول("no-spaces")، پرونده محیط.نقل قول("two words")
ناپایا دوباره := پرونده محیط.تجزیه(پرونده محیط.قالب(سند))
سرچاپ "رفت و برگشت:"، پرونده محیط.دریافت(دوباره، "WELCOME")
پرونده محیط.آزادسازی(دوباره)
پرونده محیط.آزادسازی(سند)
پایانقالب کلیدها را به ترتیب مینویسد و توضیحها را کنار میگذارد، پس آن را برای پروندههایی به کار ببرید که مال برنامهی خودتان است. برای پروندهای که آدمها با دست نگه میدارند، بهتر است به آنها بگویید کدام خط را عوض کنند.
گونهها
سند Doc
ساختار سند| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نگاشت | m | collections.OrderedMap | کلیدها و مقدارها به ترتیب. |
| پرچمهای جایگذاری | flags | وکتور<صحیح> | برای هر کلید، آیا مقدارش جایگذاریپذیر است (نقلقول تکی جایگذاری را غیرفعال میکند). |
واردسازی کدگذاری.پرونده محیط
واردسازی کدگذاری.خطای کدگذاری
تابع ریشه:
متن := "# تنظیمات\nHOST=localhost\nPORT=8080\nexport NAME=\"سلام دنیا\"\nURL=http://${HOST}:${PORT}/\n"
ناپایا س := پرونده محیط.تجزیه(متن)
سرچاپ پرونده محیط.طول(س)، پرونده محیط.کلیدها(س)
سرچاپ پرونده محیط.دریافت(س، "NAME")، پرونده محیط.دارد(س، "DEBUG")، پرونده محیط.دریافت با پیش فرض(س، "DEBUG"، "false")
سرچاپ پرونده محیط.کلید در(س، ۰)، پرونده محیط.مقدار در(س، ۱)
سرچاپ پرونده محیط.دریافت(س، "URL")
خام := پرونده محیط.تجزیه خام(متن)
سرچاپ پرونده محیط.دریافت(خام، "URL")، پرونده محیط.نامهای ارجاع(خام)
ناپایا پایه := پرونده محیط.جدید()
گسترده := پرونده محیط.گسترش سند(خام، پایه)
سرچاپ پرونده محیط.دریافت(گسترده، "URL")
سرچاپ پرونده محیط.گسترش("${HOST}/api"، س، پایه)، پرونده محیط.نامهای ارجاع در("$A و ${B}")
پرونده محیط.تنظیم(س، "DEBUG"، "true")
سرچاپ پرونده محیط.حذف(س، "URL")
سرچاپ پرونده محیط.قالب(س)
سرچاپ پرونده محیط.قالب صادراتی(پایه) == ""، پرونده محیط.نقل قول("a b")
ناپایا دیگر := پرونده محیط.تجزیه("PORT=9090\nMODE=prod\n")
پرونده محیط.ادغام در(س، دیگر)
سرچاپ پرونده محیط.دریافت(س، "PORT")، پرونده محیط.دریافت(س، "MODE")
ناپایا خ := خطای کدگذاری.بدون خطا()
_ := پرونده محیط.تجزیه سخت گیرانه("=بیکلید\n"، خ)
سرچاپ خطای کدگذاری.خطا است(خ)، پرونده محیط.معتبر("A=1\n")
سرچاپ پرونده محیط.تجزیه مقدار(`"a\tb"`)، پرونده محیط.تجزیه مقدار گسترده("x ; comment"، درست)
پرونده محیط.آزادسازی(س)
پرونده محیط.آزادسازی(خام)
پرونده محیط.آزادسازی(پایه)
پرونده محیط.آزادسازی(گسترده)
پرونده محیط.آزادسازی(دیگر)
پایانتابعها
گسترش سند ExpandDoc
تابع گسترش سند(d &: سند، base &: سند): سندbase جستجو میشود؛ نامی که در هیچکدام نباشد رشتهی خالی میشود. خروجی کاملاً گسترش یافته است، پس نامهای ارجاع در آن چیزی پیدا نمیکند.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
گسترش Expand
تابع گسترش(raw: رشته، d &: سند، base &: سند): رشتهbase جایگذاری میکند.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
نامهای ارجاع RefNames
تابع نامهای ارجاع(d &: سند): وکتور<رشته>تجزیه خام صدا بزنید؛ پس از تجزیه ارجاعها دیگر نیستند.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
نامهای ارجاع در RefNamesIn
تابع نامهای ارجاع در(raw: رشته): وکتور<رشته>$A و ${A}.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
نقل قول Quote
تابع نقل قول(v: رشته): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
قالب Format
تابع قالب(d &: سند): رشتهKEY=value در یک خط، و مقدارهایی را که لازم دارند در نقلقول میگذارد و میگریزاند. توضیحها نگه داشته نمیشوند.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
قالب صادراتی FormatExport
تابع قالب صادراتی(d &: سند): رشتهقالب، با export پیش از هر خط؛ برای پوسته.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
تجزیه خام ParseRaw
تابع تجزیه خام(text: رشته): سندنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
تجزیه Parse
تابع تجزیه(text: رشته): سندنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
تجزیه سخت گیرانه ParseStrict
تابع تجزیه سخت گیرانه(text: رشته، err &: encerr.EncodingError): سندتجزیه، ولی نخستین خط نادرست یا نقلقول بستهنشده خواندن را متوقف میکند و err را پر میکند، با position در آغاز همان خط. کلیدهایی که پیش از آن خوانده شدهاند برگردانده میشوند.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
معتبر Valid
تابع معتبر(text: رشته): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
تجزیه مقدار ParseScalar
تابع تجزیه مقدار(raw: رشته): رشته= میخواند: نقلقول و اسکیپ را برمیدارد.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
تجزیه مقدار گسترده ParseScalarEx
تابع تجزیه مقدار گسترده(raw: رشته، semi: منطقی): رشتهتجزیه مقدار؛ اگر semi درست باشد، ; هم مثل # آغاز توضیح است.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
جدید New
تابع جدید(): سندنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
طول Len
تابع طول(d &: سند): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
دارد Has
تابع دارد(d &: سند، key: رشته): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
دریافت Get
تابع دریافت(d &: سند، key: رشته): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
دریافت با پیش فرض GetOr
تابع دریافت با پیش فرض(d &: سند، key: رشته، def: رشته): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
تنظیم Set
تابع تنظیم(d &: سند، key: رشته، val: رشته)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
حذف Remove
تابع حذف(d &: سند، key: رشته): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
کلید در KeyAt
تابع کلید در(d &: سند، i: صحیح): رشتهi.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
مقدار در ValueAt
تابع مقدار در(d &: سند، i: صحیح): رشتهi.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
کلیدها Keys
تابع کلیدها(d &: سند): وکتور<رشته>نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
ادغام در MergeInto
تابع ادغام در(dst &: سند، src &: سند)src را در dst میریزد؛ کلیدهای تکراری جایگزین میشوند.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam
آزادسازی Free
تابع آزادسازی(d &: سند)نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-envfile-Parse.salam