Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
lockblocks
Advanced tools
LockBlocks is a Node.js command line utility that allows you to easily update projects created from a starter.
Starters are an excellent way to hit the ground running with any new project without needing to write a bunch of boilerplate code. Simply clone the starter and build.
However, the moment you create a new project from a starter, you create a new maintenance fork. If you update the starter, any projects created from that starter will also need to be updated, and usually this must be done manually.
This can quickly snowball into a lot of work if you are maintaining several projects created from the same starter. Bugs can easily be introduced when manually updating projects, or you may simply forget to copy updates to each project.
Enter LockBlocks. With LockBlocks, you can configure an updater that specifies which files and directories should be updated from the starter.
You can specify fields to update in JSON and YAML files, such as your dependencies in package.json
, with granular control over how the updates are made for each field (merge, fill, replace, etc).
In addition, you can specify blocks of code that will be pulled from the starter when updating. This gives you a lot of control over what can be maintained in the starter, as you can lock parts of a file that are maintained in the starter, while leaving the rest of the file to be changed as the developer sees fit.
package.json
scripts and dependencies, or any other JSON or YAML files, as you see fit!If this project helped out or made your day a little brighter and you'd like to return the favor, why not buy me a coffee or become a sponsor? It'll make my day and help keep the project chugging along.
Plus, I'll do a little dance in your honor. Maybe not a very good one, but a dance nonetheless.
npm i lockblocks
Create a new file at the root of your starter project called lockblocks.yml
:
# lockblocks.yml
renameFiles: []
replaceFiles:
- lockblocks.yml
fillFiles: []
deleteFiles: []
excludePaths:
- .git
- .lockblocks
- node_modules
updateJson:
- path: package.json
root:
fill: true
updateFields:
- key: version
as: starterVersion
- key: scripts
merge: true
- key: dependencies
merge: true
- key: devDependencies
merge: true
updateYaml: []
This config will keep your
lockblocks.yml
and npm scripts and packages up to date, and will copy the starter'sversion
inpackage.json
asstarterVersion
.
Then create an npm script in package.json
to execute LockBlocks using a git project or npm package as the origin and the current project as the target. See below.
To update your project with LockBlocks using a git project as the origin, add this script to package.json
:
"scripts": {
"update": "git clone -q git@github.com:my-username/my-starter.git ./.lockblocks && lockblocks ./.lockblocks . --verbose && rm -rf .lockblocks"
},
...where git@github.com:my-username/my-starter.git
is the location to your starter git project.
This script will silently clone your project to the .lockblocks
directory, then run LockBlocks using that dir as the origin and the current directory as the target. The .lockblocks
directory will then be deleted when finished.
With this approach, be sure .lockblocks
is specified in excludePaths
.
To update your project with LockBlocks using an npm package as the origin, add this script to package.json
:
"scripts": {
"update": "npm i my-starter@latest && lockblocks ./node_modules/my-starter . --verbose"
},
...where my-starter
is the name of your npm package.
With this approach, LockBlocks will use the latest version of your starter from npm as the origin, and the current directory as the target.
This utility uses a config file, lockblocks.yml
, to determine which files and directories to update in your project.
It also scans all files in the starter (origin directory) for special tags that specify additional updates to make, including blocks of code.
You can reference the order in which LockBlocks performs updates below.
LockBlocks operates in the following order:
renameFiles
and the lock-rename
tags found in origin.replaceFiles
and the lock-all
tags found in origin.fillFiles
.deleteFiles
.lock
block tags found in origin.updateJson
.updateYaml
.LockBlocks is a command line utility that takes two arguments: an origin directory, and a target directory.
lockblocks origin target
Files, directories, and code blocks are transferred from the origin directory to the target directory as per the configuration and special tags found in the origin files.
The origin directory must contain a config file called lockblocks.yml
for LockBlocks to run. See below for configuration options.
By default, warn
and error
level events will be printed to the console. Pass the --verbose
arg to print info
and action
type events as well. Pass --silent
to silence all console output. Logs are saved to lockblocks.log
by default.
You must create a config file in the root of the project called lockblocks.yml
. This file must be present for LockBlocks to work.
Field specifications are as follows:
Specify files and directories to be renamed.
Specification:
renameFiles: Reassignment[]
Reassignment
is an object with the following fields:
from: string
- The previous file or directory name.to: string
- The new file or directory name.Example:
renameFiles:
- from: src/config.json
to: src/settings.json
- from: src/comps
to: src/components
Specify what files or directories to replace completely with the origin. The target file will be removed, then the origin file will be copied to the target.
Changes will only be made if there are file differences.
Specification:
replaceFiles: (string | OriginTarget)[]
You can specify an array of strings, which are filenames relative to the root, or a pair of from/to filenames if you'd like to rename the file during the operation.
OriginTarget
is an object with the following fields:
origin: string
- The filename in the origin project.target: string
- The filename in the target project.If specifying origin or target, both are required for a renaming to occur.
Example:
replaceFiles:
- core
- .node-version
Specify files to copy to the target only if they don't already exist. If a directory is specified, missing files and directories will be copied recursively.
Specification:
fillFiles: (string | OriginTarget)[]
You can specify an array of strings, which are filenames relative to the root, or a pair of from/to filenames if you'd like to fill a different filename/dir during the operation.
OriginTarget
is an object with the following fields:
origin: string
- The filename in the origin project.target: string
- The filename in the target project.If specifying origin or target, both are required for a renaming to occur.
Example:
fillFiles:
- src/components
- origin: defaults/settings/default.yml
target: src/settings/settings.yml
Specify files and directories to be deleted in the target.
Specification:
deleteFiles: string[]
Example:
deleteFiles:
- media/icon-placeholder.png
- src/components/LegacyWrapper.tsx
- src/stuff
Specify the paths to exclude scanning for lock tags. Paths are relative to the origin directory (do not prefix paths with ./
). Can be directories or files.
Only UTF-8 files will be scanned for tags. These paths are only applicable to files scanned for tags.
Specification:
excludePaths: string[]
Example:
excludePaths:
- .git
- .lockblocks
- node_modules
- README.md
Specify the fields to be updated in JSON and YAML files.
This is useful for keeping fields (scripts, deps, etc) updated in package.json
, or for updating fields in YAML files.
Specification:
For JSON files:
updateJson: ConfigUpdate[]
For YAML files:
updateYaml: ConfigUpdate[]
The value is an array of ConfigUpdate
s. These define how a config file should be updated. A path to the file is required and LockBlocks expects the file to contain an object at the root. All other fields are optional. You can specify fields to be updated, deleted, and renamed. You can also specify the behavior for each update. See below for details.
ConfigUpdate
is an object with the following fields:
path: string
- The path to the file to updateroot: FieldUpdateOptions
- An object specifying how the fields should be updated. See below.renameFields: Reassignment[]
- An array of from/to pairs for renaming fields.updateFields: FieldUpdate[]
- An array of updates specs. See below.deleteFields: string[]
- An array of field names. Supports dot notation for nested fields (e.g. my.field.name)FieldUpdateOptions
is an object with the following fields:
merge: boolean
- Optional. Copy all fields from origin to target, leaving all others.fill: boolean
- Optional. Copy only missing fields from origin to target.prune: boolean
- Optional. Remove all target fields missing from origin.replace: boolean
- Optional. Copy all fields from origin to target, deleting all others. Same as merge + prune.FieldUpdate
is an object with the following fields:
key: string
- The key of the field to update. Supports dot notation for nested fields (e.g. my.field.name)as: string
- Optional. When specified, this field name will be used in the target. Supports dot notation for nested fields (e.g. new.key.title).FieldUpdateOptions
fields. These only apply if the field is an object. Otherwise, it is simply replaced.Reassignment
is an object with the following fields:
from: string
- The previous field name.to: string
- The new field name.The root
option will affect all fields at the root of the file. This expects a FieldUpdateOptions
object (see above).
Order of updates:
Example:
updateJson:
- path: package.json
root:
fill: true
renameFields:
- from: oldName
to: newName
updateFields:
- key: version
as: starterVersion
- key: scripts
merge: true
- key: dependencies
merge: true
- key: devDependencies
merge: true
deleteFields:
- scripts.remove
updateYaml:
- path: settings/settings.yml
renameFields:
- from: analyticsCode
to: analyticsMeasurementId
- from: site.header
to: site.title
updateFields:
- key: defaults
merge: true
deleteFields:
- theme
LockBlocks saves a log of the updates made to lockblocks.log
, unless otherwise specified with the log
option.
You can specify a filename to change the output file, or specify false
to disable logging.
Specification:
log: boolean | string
If log
is not specified, or if log
is set to true
, logs will be saved to lockblocks.log
by default. If set to false
, no logs will be saved.
Examples:
log: true # Logs are saved to lockblocks.log when true
log: false # No logs will be saved
log: logs/updater.log # Logs are saved to this file
Log levels:
action
- Indicates a change to the files in your project.info
- Indicates helpful information about the execution.warn
- Indicates a warning that may require your attention.error
- Indicates an error that occurred during execution.All file changes are indicated by the action
log level. These identify actual file changes (write, copy, delete, move) in the target.
In addition to all action
log events, you can also use a simple git status
to confirm which files were modified after an update.
LockBlocks will scan the origin directory for special tags that allow you to transfer and rename files, and synchronize code blocks.
These tags can be placed in comments. Only UTF-8 files will be scanned.
Use the [lock-all/]
tag anywhere in a file to cause the entire file to be replaced in the target.
// [lock-all/]
Surround code with the [lock:block]
and [/lock:block]
tags to cause a block of code in the origin to be replaced in the target file of the same name.
The block
part of this tag should be a unique ID that names that block in the file. This convention allows you to have multiple locked code blocks per file.
The IDs need only be unique for each given file (you can use the same ID in multiple files).
You can also lock a single line with the following: [lock:block/]
// [lock:block]
// Code
// ...
// [/lock:block]
// ...
// [lock:another-block]
// More code
// ...
// [/lock:another-block]
// ...
// Single line locked // [lock:single-line/]
Add the tag [lock-rename: path/to/previous/filename.txt /]
to a file to rename the old filepath to the current one. LockBlocks will search the target for the old filepath and rename the file to the current filepath if the old file exists. Paths are relative to the root.
You can specify multiple rename tags in any given file.
// [lock-rename: path/to/previous/filename.txt /]
Add the [lock-ignore/]
tag to tell LockBlocks to ignore the line and any other tags it may contain.
// [lock-all/] [lock-ignore/]
In the target project, simply remove a tag from the file to prevent LockBlocks from making that update.
For instance, you can remove the [lock:block] ... [/lock:block]
tags around a block of code to "eject" from the starter. That code block will no longer be updated.
Type definitions have been included for TypeScript support.
Open source software is awesome and so are you. 😎
Feel free to submit a pull request for bugs or additions, and make sure to update tests as appropriate. If you find a mistake in the docs, send a PR! Even the smallest changes help.
For major changes, open an issue first to discuss what you'd like to change.
If you found this project helpful, let the community know by giving it a star: 👉⭐
Copyright © 2022 Justin Mahar https://github.com/justinmahar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
FAQs
Node.js utility for updating projects created from starters.
The npm package lockblocks receives a total of 189 weekly downloads. As such, lockblocks popularity was classified as not popular.
We found that lockblocks demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.