{"id":16661042,"url":"https://github.com/mrkkrp/plan-b","last_synced_at":"2025-10-30T05:45:21.078Z","repository":{"id":56874915,"uuid":"48605879","full_name":"mrkkrp/plan-b","owner":"mrkkrp","description":"*DEPRECATED* Failure-tolerant file and directory editing for Haskell","archived":false,"fork":false,"pushed_at":"2018-02-27T17:17:05.000Z","size":42,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-05-08T20:24:48.245Z","etag":null,"topics":["file-system","haskell"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrkkrp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-26T09:29:24.000Z","updated_at":"2019-12-05T06:34:28.000Z","dependencies_parsed_at":"2022-08-20T10:11:05.812Z","dependency_job_id":null,"html_url":"https://github.com/mrkkrp/plan-b","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkkrp%2Fplan-b","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkkrp%2Fplan-b/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkkrp%2Fplan-b/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrkkrp%2Fplan-b/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrkkrp","download_url":"https://codeload.github.com/mrkkrp/plan-b/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248092820,"owners_count":21046558,"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":["file-system","haskell"],"created_at":"2024-10-12T10:33:12.114Z","updated_at":"2025-10-30T05:45:16.042Z","avatar_url":"https://github.com/mrkkrp.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Plan B\n\n[![License BSD3](https://img.shields.io/badge/license-BSD3-brightgreen.svg)](http://opensource.org/licenses/BSD-3-Clause)\n[![Hackage](https://img.shields.io/hackage/v/plan-b.svg?style=flat)](https://hackage.haskell.org/package/plan-b)\n[![Stackage Nightly](http://stackage.org/package/plan-b/badge/nightly)](http://stackage.org/nightly/package/plan-b)\n[![Stackage LTS](http://stackage.org/package/plan-b/badge/lts)](http://stackage.org/lts/package/plan-b)\n[![Build Status](https://travis-ci.org/mrkkrp/plan-b.svg?branch=master)](https://travis-ci.org/mrkkrp/plan-b)\n[![Coverage Status](https://coveralls.io/repos/mrkkrp/plan-b/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/mrkkrp/plan-b?branch=master)\n\nThis is a Haskell library helping perform failure-tolerant operations on\nfiles and directories.\n\n## Quick start\n\nThe library allows to create and/or edit files, directories, and containers.\nBy “container” we mean archive-like object that can contain representation\nof a directory inside it. Consequently, we have six functions available:\n\n* `withNewFile`\n* `withExstingFile`\n* `withNewDir`\n* `withExistingDir`\n* `withNewContainer`\n* `withExistingContainer`\n\nYou specify name of an object to edit or create, options (more on them\nbelow), and an action that gets a `Path` argument with the same type as\nobject you intend to edit (we use type-safe file paths\nfrom [`path`](https://hackage.haskell.org/package/path) package here to\nprevent a certain class of potential bugs). Then, having that path, you can\nperform all actions you want to and if at some point during this editing an\nexception is thrown, state of file system is rolled back—you get no\ncorrupted files, half-way edited directories, everything is intact as if\nnothing happened at all. If, however, the action is executed successfully\n(i.e. no exceptions thrown), all your manipulations are reflected in the\nfile system.\n\nThis is a lightweight solution that makes it harder to corrupt sensitive\ninformation. And since file system exists in the real world, all sorts of\nbad things *can* (and *will*) happen. *You should always have plan B.*\n\nTemporary files and back-ups are handled and deleted automatically, however\nyou can pass options to change default behaviors. Not all options can be\nused with every function, but wrong combinations won't type-check, so it's\nOK.\n\nCollection of options is a monoid. `mempty` corresponds to the default\nbehavior, while non-standard behavioral deviations can be `mappend`ed to it.\n\nBy default, when we want to create a new object and it already exists, we\nget an exception, two alternative options exist (only work when you create a\nnew object):\n\n* `overrideIfExist`\n* `useIfExist`\n\nThere is no way to prevent exception when you want to *edit* object that\ndoes not exist, though.\n\nAll functions make use of temporary directories. You can control certain\naspects of this business:\n\n* `tempDir dir`—tells the library to create temporary directories and files\n  inside `dir`. By default system's standard temporary directory (e.g.\n  `/tmp/` on Unix-like systems) is used.\n\n* `nameTemplate template`—specifies template to use for generation of unique\n  file and directory names. By default `\"plan-b\"` is used.\n\n* `preserveCorpse`—if you add this to options, in case of failure\n  (exception), temporary directory is not automatically deleted and can be\n  inspected. However, if operation succeeds, temporary directory is *always*\n  deleted.\n\n* `moveByRenaming`—by default files and directories are moved by copying,\n  this option enables moving by renaming. If you also specify `tempDir` that\n  is on the same disk/partition as the final file you're generating, this\n  may speed up things considerably.\n\nThat should be enough for a quick intro, for more information regarding\nconcrete functions, consult Haddocks.\n\n## License\n\nCopyright © 2016–2018 Mark Karpov\n\nDistributed under BSD 3 clause license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrkkrp%2Fplan-b","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrkkrp%2Fplan-b","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrkkrp%2Fplan-b/lists"}