monorepo-operator

command module
v0.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 24, 2020 License: MIT Imports: 1 Imported by: 0

README

monorepo-operator

A tool for managing monolithic repositories with subtree splits.

Table of contents

Quick start

This tool is for monolithic repository which need to synchronize directories into subtree repos. A common use case is maintaining plugins or themes in the same repository.

plugins/
├── repo01
└── repo02

The init command create the necessary mappings for your directories. You can find this example in the _examples directory.

The --operating-dir flag specifies the directory where the repositories related to the directories will be stored. These will be used for performing batch tasks on all subtrees with the exec command.

# Initialize the repos with the operating directory ".repos"
$ monorepo-operator init --operating-dir=.repos [email protected]:SimonBaeumer plugins/

# View written config file
$ cat .monorepo-operator.yml
projects:
- name: repo01
  path: plugins/repo01
  git-url: [email protected]:SimonBaeumer/repo01.git
- name: repo02
  path: plugins/repo02
  git-url: [email protected]:SimonBaeumer/repo02.git
operating-directory: .repos

# Clone the repository into the specified operating-directory .repos
$ monorepo-operator clone
> Cloning repo01
> Cloning repo02

$ ls -la .repos/
total 16
drwxrwxr-x 4 user user 4096 Okt 22 13:50 .
drwxrwxr-x 5 user user 4096 Okt 22 13:44 ..
drwxrwxr-x 3 user user 4096 Okt 22 13:50 repo01
drwxrwxr-x 3 user user 4096 Okt 22 13:50 repo02

# Execute a command on all subtree-repos directly
$ monorepo-operator exec "git remote -v"
> Execute on repo01
origin  [email protected]:SimonBaeumer/repo01.git (fetch)
origin  [email protected]:SimonBaeumer/repo01.git (push)
> Execute on repo02
origin  [email protected]:SimonBaeumer/repo02.git (fetch)
origin  [email protected]:SimonBaeumer/repo02.git (push)

They sync can only be performed from the root of your monorepo repo. This will not work with the example.

sync creates subtrees for each project in the .monorepo-operator.yml with the git subtree split command. After that it pushed the changes to the desired repository, in this case testing.

# Create subtrees from currently checked out ref and push it to the configured repos on branch testing.
$ monorepo-sync tesing
> split project repo01 in branch repo01-testing
> add remote repo01
> push project repo01
Counting objects: 6, done.
[...]
To github.com:SimonBaeumer/repo01
 * [new branch]      repo01-testing -> testing
> remove remote repo01
> remove branch repo01-testing
Deleted branch repo01-testing (was a8f688f).

> split project repo02 in branch repo02-testing
> add remote repo02
> push project repo02
Total 0 (delta 0), reused 0 (delta 0)
[...]
To github.com:SimonBaeumer/repo02
 * [new branch]      repo02-testing -> testing
> remove remote repo02
> remove branch repo02-testing
Deleted branch repo02-testing (was 8fbf026).
Requirements
  • git
  • windows, osx or linux
Usage
list

list displays an overview of all projects which are managed by the monorepo-operator.

$ ./monorepo-operator --config _examples/.monorepo-operator.yml list
+--------+----------------+------------------------------------+
|  NAME  |      PATH      |              GIT-URL               |
+--------+----------------+------------------------------------+
| repo01 | plugins/repo01 | [email protected]:SimonBaeumer/repo01 |
| repo02 | plugins/repo02 | [email protected]:SimonBaeumer/repo02 |
+--------+----------------+------------------------------------+
clone

clone clones all projects into the specified operating-directory.

# If the operating-directory exists the command fails 
$ monorepo-operator clone
> Cloning repo01
2019/10/22 14:05:34 error while cloning: fatal: destination path '.git/.subtree-repos/repo01' already exists and is not an empty directory.

# Overwrite and re-clone all project with the --reset flag
$ monorepo-operator clone --reset
> Removing operating directory at .git/.subtree-repos
> Cloning repo01
> Cloning repo02
sync

sync the current branch to a target branch on the remote subtree repositories. This command only works in the root directory of your mono-repo.

If the --force flag is set the sync will perform a force push with git push -f [...].

The --remove-branches flag removes branches in subtree repos which do not exist in the mono-repo.

The --tags flag syncs a tag instead of the given branch.

# Sync branches
$ monorepo-operator sync [branch-name]

# Sync tags
$ monorepo-operator sync [tag-name] --tags
exec

exec executes shell commands on all projects.

$ monorepo-operator exec "echo hello"
> Execute on project01
hello
> Execute on project02
hello
add

add adds a new project mapping to the .monorepo-operator.yml.

# Add project to your mapping config
$ monorepo-operator add repo03 [email protected]:SimonBaeumer/repo03.git repos/
> Write config file .monorepo-operator.yml

# Directly clone the repo of the project with --clone
$ monorepo-operator add --clone repo03 [email protected]:SimonBaeumer/repo03.git repos/
> Write config file .monorepo-operator.yml
> Cloning repo03
[...]
remove-branches

remove-branches removes branches which do not exist locally or on the remote mono-repo in subtree repos.

--no-local disables removing local branches which do not exist in the remote mono repo. --no-remote disables removing remote branches in subtree-repos which do not exist in the remote mono repo.

project

project lets you execute some commands or tasks on a single project.

exec

project exec [name] executes shell commands on a project.

$ monorepo-operator project exec repo01 "echo pwd"
> Execute on project01
/tmp/monorepo/.git/.subtree-repos/repo01
split

project split [name] creates a subtree split of the project and returns the hash of it.

$ monorepo-operator project split repo01
44a603d1720dee64e8c4f5b13f5b5f2e87d54402
Configuration
# Mapping of projects to path inside the mono-repo and the corresponding git-url
projects:
- name: project01
  path: projects/project01
  git-url: [email protected]:UserName/project02.git

- name: project02
  path: projects/project02
  git-url: [email protected]:UserName/project02.git
  
# Provide regexes for branches which should be excluded if the sync uses force pushes
protected:
  - master
  - \d{0,9}\.\p{N}\d{0,9}\.\p{N}\d{0,9}

# operating-directory stores the original repositories with the git configs
# the exec command executes all commands on all directories located under the operating dir
operating-directory: .git/.subtree-repos

Optionally you can define a directory which is scanned and creates for every directory a project:

projects:
- name: "{{.DirName}}"
  path: projects
  git-url: [email protected]/UserName/{{.DirName}}.git
  is-dir: true

Development

Build targets
# Init dev environment, i.e. git-hooks
$ make init

# Build project
$ make build

# Create releases
$ make release

# Execute unit tests
$ make tests
ToDo
  • Lock and Unlock projects while executing commands
  • Post and Pre-Hooks
    • Split
    • Push
    • Exec
  • Add pipeline examples

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL