https://github.com/financial-times/nori
🍙 exploratory command-line tool to make changes across multiple repositories & track their progress
https://github.com/financial-times/nori
cli command-line-tool customer-products enquirer interactive migrations platforms-customer-products
Last synced: 11 months ago
JSON representation
🍙 exploratory command-line tool to make changes across multiple repositories & track their progress
- Host: GitHub
- URL: https://github.com/financial-times/nori
- Owner: Financial-Times
- License: mit
- Created: 2018-11-27T21:36:41.000Z (over 7 years ago)
- Default Branch: main
- Last Pushed: 2024-10-24T19:52:45.000Z (over 1 year ago)
- Last Synced: 2024-10-24T23:53:08.875Z (over 1 year ago)
- Topics: cli, command-line-tool, customer-products, enquirer, interactive, migrations, platforms-customer-products
- Language: JavaScript
- Homepage:
- Size: 12.2 MB
- Stars: 11
- Watchers: 48
- Forks: 0
- Open Issues: 19
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: CODEOWNERS
Awesome Lists containing this project
README

_exploratory command-line tool to make changes across multiple repositories & track their progress_
words defined by this readme are written in bold
Nori is a command-line application for managing changes across multiple (usually Github) repositories. It allows you to build up a sequence of [**Operations**](#operations) to go through the process of discovering repositories to change, cloning them & making the changes, creating Pull Requests for the changes, and tracking the progress of the Pull Requests in a Github Project. The main interface for Nori is an interactive command-line wizard, which prompts you for which operations to run, and the arguments needed for each operation.
## Usage
```sh
npx nori
```
This temporarily installs Nori and runs the interactive wizard. The first time you run it, it will prompt you for various configuration variables, which are required only for certain operations. It'll then ask you to `Create a session`. Give the session a memorable name. The wizard takes you through the operations you can run. At any point you can exit by pressing Ctrl+C or selecting `Done`. Your progress is saved under the name you gave when you started `nori`. Next time you run it, it will display a list of previous sessions that you can resume, most recent last.
If you'll be running `nori` frequently, install it globally:
```sh
npm install -g nori
```
`nori` can run operations via the interactive prompt, or directly on the command line. Operations **output** a particular type of data, and some operations have one or more **inputs**, which are types of data that must be gathered before you can run the operation. The interactive prompt will only enable the operations you have the data for so far. When running from the command line, you can pass this data around by [**Piping**](#piping) the operations, or by using a [**State File**](#state-file).
Run `nori` with the name of the operation, and any arguments it requires as double-dashed command line arguments (`nori` understands `--kebab-case` arguments and transforms them to `camelCase`). If you're running in an interactive shell, `nori` will prompt for any missing arguments.
For example, to consume repositories from `repos.txt` and output the formatted list:
```sh
⟩ nori file --file repos.txt
https://github.com/financial-times-sandbox/Abandoned-Toothbrush
https://github.com/financial-times-sandbox/Western-Storm
```
Every operation supports the `--json` flag, which outputs all data found formatted as JSON:
```sh
⟩ nori file --file repos.txt --json
[
{
"owner": "financial-times-sandbox",
"name": "Abandoned-Toothbrush"
},
{
"owner": "financial-times-sandbox",
"name": "Western-Storm"
}
]
```
## Operations
### File
##### `nori file --file `
Get a list of repositories from a text file, structured as line-separated `owner/name` strings (optionally with leading `https://github.com/`).
Arguments
file
path to the text file to read, relative to the current working directory
Inputs
none
Output
repos
### Get repositories through Bizops
Before executing any of the two commands below, either through `npx nori` interactive mode, or directly through the command line, make sure you set the env variable `BIZ_OPS_API_KEY`. To get the key, request a key with a Biz Ops API policy from https://apigateway.in.ft.com/key-form/developer.
##### `nori team-repos`
This operation gets all the repositories from the team you have selected.
It shows a list of teams in customer products (obtained from Bizops) which you can select.
Arguments
None
Teams to be selected when command is run
Inputs
none
Output
repos
##### `nori graphql-repos --file `
This operation gets repositories by executing the file that you pass in containing your own graphql query.
Arguments
file
path to a .graphql | .txt file containing graphql query for repositories
Inputs
none
Output
repos
### Filter repository name
##### `nori filter-repo-name --filter `
Filter the list of repositories by their names.
Arguments
filter
regular expression to filter the names of the repos by
Inputs
repos
Output
repos
### Clone
##### `nori clone`
Clone each of the list of repositories
Arguments
none
Inputs
repos
Output
clones
### Run Script
##### `nori run-script --script --branch `
Create a branch and run a script on it. If the provided branch name already exists, Nori will append a number to it (e.g. `branch` → `branch-1`).
Arguments
script
path to the script to run, relative to the current working directory. should have executable permissions
branch
name of the branch to create
Inputs
clones
Output
localBranches
The script has the responsibility to:
- Make changes to the files in a local clone of a git repository
- Add those changes to git
- Commit those changes to git
Nori will take care of creating branches. The main benefit
of this approach is that scripts do not _need_
`nori` for you to be able to run them. This makes development,
debugging and one-off runs of a script much simpler.
### Push Branches
##### `nori push-branches`
Push each repository's local branch to the remote. If a branch already exists on the remote with the same name as the local branch, Nori will append a number to it (e.g. `branch` → `branch-1`).
Arguments
none
Inputs
clones, localBranches
Output
remoteBranches
### Pull Requests
If you are planning to raise PRs, please add your github personal access token to the githubAccessToken object in `~/.config/nori-workspace/config.json`. Authenticating increases the [secondary rate limit](https://docs.github.com/en/rest/guides/best-practices-for-integrators#dealing-with-secondary-rate-limits) of GitHub API, which increases your chance to raise multiple PRs without being blocked by the limit.
##### `nori prs --templates.title --templates.body `
Create a Pull Request for each of the pushed branches.
Arguments
templates.title
the title of the pull requests. you can use Javascript ${} template string syntax. available variables are repo.owner, repo.name and branch.
templates.body
the body of the pull requests. supports templates like title
Configuration
githubAccessToken
Github personal access token with repo scope
Inputs
repos, branches
Output
prs
### Create Project
##### `nori create-project --project-data.name --project-data.org `
Create a Github Project.
Arguments
projectData.name
the name of the project to create
projectData.org
the org to create the project in. this must be the same org as every repo that you've created a PR on.
Configuration
githubAccessToken
Github personal access token with repo scope
Inputs
none
Output
project
**NB** _we're considering what to do about repos from multiple orgs, see [#62](https://github.com/Financial-Times/nori/issue/62)_
**NB** _the project will have `To Do`, `In Progress` and `Done` columns, but there's currently no way to set up automatic transitions using the Github API. you'll have to set that up manually if you want the project board to reflect the state of the PRs_
### Get Project
##### `nori get-project --project-url `
Get a project from Github.
Arguments
projectUrl
URL of the Github project page
Configuration
githubAccessToken
Github personal access token with repo scope
Inputs
none
Output
project
### Add to Project
##### `nori add-to-project`
Add the [PRs](#pull-requests) to the project.
Arguments
noned
Configuration
githubAccessToken
Github personal access token with repo scope
Inputs
prs, project
Output
cards
## State Files
When running the interactive prompt, your progress is automatically saved to a state file. It contains the list of operations you've run & the arguments given to them, and a cache of the data returned by the operations.
State files are kept in the folder `~/.config/nori-workspace` (this is also where repositories are cloned to). When you start the interactive prompt, it will list any state files already in the workspace folder, allowing you to resume previous sessions.
Individual operations can also read and save to state files with the `--state-file path/to/file.json` option. When you run an operation with a path to a state file that doesn't exist, it will ask if you want to create it. When the operation completes, it'll have added itself and the data it returned to the state file.
The `--state-file` option can also be used with the interactive prompt, which will skip the step asking you to create a state file or use one from the `nori` workspace folder, and allow you to use a state file from any location. State files are compatible between individual operations and the interactive prompt, which lets you shuffle between the two modes.
## Piping
State can also be passed between operations using shell pipes. This is equivalent to running them in sequence and reusing the same state file.
```sh
nori file --file repos.txt | nori run-script --script script.sh --branch change
```
Note that interactive features, such as prompting for missing arguments, won't be available when piping. If any arguments are missing, the operation will error instead. The same goes for providing a state file via the command line argument; it's an error to use `--state-file` and pipe as well. To load or save a state file in a piped operation, use [shell redirection](https://www.tldp.org/LDP/abs/html/io-redirection.html):
```sh
nori file --file repos.txt < input-state.json | nori run-script --script script.sh --branch change > output-state.json
# └─────────┬────────┘ └─────────┬─────────┘
# read input from input-state.json write output to output-state.json
```
## Licence
MIT. © 2019 Financial Times. Made with :green_heart: by FT.com Enabling Technologies Group