{"id":18800878,"url":"https://github.com/bitovi/landscaper","last_synced_at":"2025-04-13T17:31:44.882Z","repository":{"id":136981537,"uuid":"89941101","full_name":"bitovi/landscaper","owner":"bitovi","description":"Apply code mods to projects, awesomely","archived":false,"fork":false,"pushed_at":"2018-02-07T16:32:13.000Z","size":233,"stargazers_count":14,"open_issues_count":15,"forks_count":2,"subscribers_count":49,"default_branch":"master","last_synced_at":"2024-04-14T00:53:50.364Z","etag":null,"topics":["code-modification","command-line-tool","localhost","pull-request"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/bitovi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-01T16:30:04.000Z","updated_at":"2023-07-20T16:50:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"bdbabed1-e7ba-4f13-85e0-6aa4589b53a4","html_url":"https://github.com/bitovi/landscaper","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitovi%2Flandscaper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitovi%2Flandscaper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitovi%2Flandscaper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitovi%2Flandscaper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitovi","download_url":"https://codeload.github.com/bitovi/landscaper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248752436,"owners_count":21156089,"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":["code-modification","command-line-tool","localhost","pull-request"],"created_at":"2024-11-07T22:20:33.788Z","updated_at":"2025-04-13T17:31:44.876Z","avatar_url":"https://github.com/bitovi.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align='center'\u003e\n\u003cbr/\u003e\n\u003cimg src='/assets/landscaper.png' alt='Landscaper' width='500'\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003c/h1\u003e\n\n\u003e Apply code mods to projects\n\n```sh\nnpm install --global landscaper\n```\n\n[![npm](https://img.shields.io/npm/v/landscaper.svg)](https://www.npmjs.com/package/landscaper)\n\nLandscaper is a command-line tool for making sweeping changes to any number of projects using code mods.\n\n## Features\n\n- Combine any number of code mods into a single transformation\n- Run code mods on any number of directories at once\n- Run code mods on any number of Github repositories at once\n- Use code mods published on NPM\n- Use code mods saved as Github gists\n- Apply [JSCodeShift](https://github.com/facebook/jscodeshift) code mods without any modification\n- Automatically submit pull requests to Github repositories\n\n## Use cases\n\n\u003e \"I need to upgrade my current codebase with code mods and want to run them all together.\"\n\nLandscaper can run code mods in a series back to back, no problem.\n\n\u003e \"I need to fix a typo in the README of every personal project I ever published on Github, ever.\"\n\nLandscaper can take your update script and run it against a new branch forked from the master branch of each of your repositories. Once finished, it will push the new branch with changes and create a pull request.\n\n\u003e \"I want to update pre-release version dependencies in the package.json of every project in my Github organization.\"\n\nSure, we have a [code mod](https://gist.githubusercontent.com/phillipskevin/75a3626b00dd32709b13132706cb7f30/raw/bbda2496be6a7f97032ef6f60266172fad7309a7/remove-pre-release-deps.js) for that already.\n\n\u003e \"It's {CURRENT-YEAR}, I want to update the copyright year in all my LICENSE files.\"\n\nSure, we have a [code mod](https://gist.github.com/andrejewski/8d0b4927f73978e78b0105f84ad8abd4) for that already.\n\n\u003e \"I want to switch from tabs|spaces to spaces|tabs in all my diary entries in my `Desktop` folder\"\n\nNotice how I did not take a side here.\n\n## Super Mod\n\nThe [JSCodeShift](https://github.com/facebook/jscodeshift) code mods take a file and transform it based on its contents. Landscaper supports those mods without any configuration, but in some cases you may want more power. This power lies in a **Super Mod**.\n\nA Super Mod:\n- Accepts any number of configuration options, allowing transformations to take user input and be dynamic to use cases.\n- Access the entire working directory, have access to the project, and create, delete, and rename files and folders.\n\nEssentially, a Super Mod can do anything. Below is a simple example of a Super Mod that creates a file with the content entered by the user when configuring the code mod.\n\n```js\nvar fs = require('fs')\nvar path = require('path')\n\nmodule.exports = {\n  getOptions: function () {\n    return [{\n      name: 'content',\n      type: 'input',\n      default: 'Some text I made',\n      message: 'Text to write'\n    }]\n  },\n\n  run: function (directory, options) {\n    var text = options.content\n    var filepath = path.join(directory, 'foo.txt')\n    return new Promise(function (resolve, reject) {\n      fs.writeFile(filepath, text, function (error) {\n        error ? reject(error) : resolve()\n      })\n    })\n  }\n}\n```\n\nNote: Configuration options go through [`inquirer.prompt()`](https://github.com/SBoudrias/Inquirer.js/#question).\n\n\n---\n\u003ch6 align='center'\u003e\n\u003cbr/\u003e\n\u003ca href='https://www.bitovi.com/'\u003e\u003cimg src='/assets/bitovi.png' alt='Bitovi' width='300'\u003e\u003c/a\u003e\n\u003cbr/\u003e\nBuilt and maintained by the open source team at \u003ca href='https://www.bitovi.com/'\u003eBitovi\u003c/a\u003e.\n\u003cbr/\u003e\n\u003c/h6\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitovi%2Flandscaper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitovi%2Flandscaper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitovi%2Flandscaper/lists"}