{"id":13880092,"url":"https://github.com/thoughtbot/climate_control","last_synced_at":"2025-05-14T16:02:30.809Z","repository":{"id":5695346,"uuid":"6905846","full_name":"thoughtbot/climate_control","owner":"thoughtbot","description":"Modify your ENV","archived":false,"fork":false,"pushed_at":"2024-09-30T17:38:23.000Z","size":100,"stargazers_count":554,"open_issues_count":1,"forks_count":25,"subscribers_count":38,"default_branch":"main","last_synced_at":"2025-05-02T08:46:52.122Z","etag":null,"topics":["ruby","testing"],"latest_commit_sha":null,"homepage":"https://robots.thoughtbot.com","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thoughtbot.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-11-28T16:56:21.000Z","updated_at":"2025-04-27T20:46:22.000Z","dependencies_parsed_at":"2024-03-15T00:30:33.196Z","dependency_job_id":"4407d4ff-6b12-4453-afe7-a17665bf526a","html_url":"https://github.com/thoughtbot/climate_control","commit_stats":{"total_commits":96,"total_committers":25,"mean_commits":3.84,"dds":0.6458333333333333,"last_synced_commit":"8c38cc017a68e6de77c88f8aaee170a357529f41"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fclimate_control","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fclimate_control/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fclimate_control/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtbot%2Fclimate_control/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thoughtbot","download_url":"https://codeload.github.com/thoughtbot/climate_control/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252316695,"owners_count":21728521,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ruby","testing"],"created_at":"2024-08-06T08:02:46.934Z","updated_at":"2025-05-14T16:02:30.746Z","avatar_url":"https://github.com/thoughtbot.png","language":"Ruby","readme":"# Climate Control\n\n![GitHub Actions CI](https://github.com/thoughtbot/climate_control/actions/workflows/ci.yml/badge.svg)\n\nEasily manage your environment.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'climate_control'\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install climate_control\n\n## Usage\n\nClimate Control can be used to temporarily assign environment variables\nwithin a block:\n\n```ruby\nClimateControl.modify CONFIRMATION_INSTRUCTIONS_BCC: 'confirmation_bcc@example.com' do\n  sign_up_as 'john@example.com'\n\n  confirm_account_for_email 'john@example.com'\n\n  expect(current_email).to bcc_to('confirmation_bcc@example.com')\nend\n```\n\nTo modify multiple environment variables:\n\n```ruby\nClimateControl.modify CONFIRMATION_INSTRUCTIONS_BCC: 'confirmation_bcc@example.com',\n                      MAIL_FROM: 'us@example.com' do\n  sign_up_as 'john@example.com'\n\n  confirm_account_for_email 'john@example.com'\n\n  expect(current_email).to bcc_to('confirmation_bcc@example.com')\n  expect(current_email).to be_from('us@example.com')\nend\n```\n\nTo use with RSpec, you could define this in your spec:\n\n```ruby\ndef with_modified_env(options = {}, \u0026block)\n  ClimateControl.modify(options, \u0026block)\nend\n```\n\nThis would allow for more straightforward way to modify the environment:\n\n```ruby\nrequire 'spec_helper'\n\ndescribe Thing, 'name' do\n  it 'appends ADDITIONAL_NAME' do\n    with_modified_env ADDITIONAL_NAME: 'bar' do\n      expect(Thing.new.name).to eq('John Doe Bar')\n    end\n  end\n\n  def with_modified_env(options, \u0026block)\n    ClimateControl.modify(options, \u0026block)\n  end\nend\n```\n\nTo modify the environment for an entire set of tests in RSpec, use an `around`\nblock:\n\n```ruby\ndescribe Thing, 'name' do\n  # ... tests\n\n  around do |example|\n    ClimateControl.modify FOO: 'bar' do\n      example.run\n    end\n  end\nend\n```\n\nEnvironment variables assigned within the block will be preserved;\nessentially, the code should behave exactly the same with and without the\nblock, except for the overrides. Transparency is crucial because the code\nexecuted within the block is not for `ClimateControl` to manage or modify. See\nthe tests for more detail about the specific behaviors.\n\n## Why Use Climate Control?\n\nBy following guidelines regarding environment variables outlined by the\n[twelve-factor app](http://12factor.net/config), testing code in an isolated\nmanner becomes more difficult:\n\n* avoiding modifications and testing values, we introduce mystery guests\n* making modifications and testing values, we introduce risk as environment\n  variables represent global state\n\nClimate Control modifies environment variables only within the context of the\nblock, ensuring values are managed properly and consistently.\n\n## Thread-safety\n\nWhen using threads, for instance when running tests concurrently in the same\nprocess, you may need to wrap your code inside `ClimateControl.modify` blocks,\ne.g.:\n\n```ruby\nfirst_thread = Thread.new do\n  ClimateControl.modify(SECRET: \"1\") do\n    p ENV[\"SECRET\"] # =\u003e \"1\"\n    sleep 2\n    p ENV[\"SECRET\"] # =\u003e \"1\"\n  end\nend\n\nsecond_thread = Thread.new do\n  ClimateControl.modify({}) do\n    sleep 1\n    p ENV[\"SECRET\"] # =\u003e nil\n    sleep 1\n    p ENV[\"SECRET\"] # =\u003e nil\n  end\nend\n\nfirst_thread.join\nsecond_thread.join\n```\n\n\u003e The modification wraps ENV in a mutex. If there's contention (the env being used - including potentially mutating values), it blocks until the value is freed (we shift out of the Ruby block).\n\u003e\n\u003e \u003ccite\u003e\u003ca href=\"https://github.com/thoughtbot/climate_control/issues/32#issuecomment-800713686\"\u003eJosh Clayton\u003c/a\u003e\u003c/cite\u003e\n\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\nThis project uses [StandardRB](https://github.com/testdouble/standard) to ensure formatting.\n\n## License\n\nclimate_control is copyright © 2012 Joshua Clayton and thoughtbot, inc. It is free software and may be redistributed under the terms specified in the [LICENSE](https://github.com/thoughtbot/climate_control/blob/main/LICENSE) file.\n\n\n\u003c!-- START /templates/footer.md --\u003e\n## About thoughtbot\n\n![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg)\n\nThis repo is maintained and funded by thoughtbot, inc.\nThe names and logos for thoughtbot are trademarks of thoughtbot, inc.\n\nWe love open source software!\nSee [our other projects][community].\nWe are [available for hire][hire].\n\n[community]: https://thoughtbot.com/community?utm_source=github\n[hire]: https://thoughtbot.com/hire-us?utm_source=github\n\n\n\u003c!-- END /templates/footer.md --\u003e\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoughtbot%2Fclimate_control","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthoughtbot%2Fclimate_control","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoughtbot%2Fclimate_control/lists"}