Coder Social home page Coder Social logo

nilslice / protolock Goto Github PK

View Code? Open in Web Editor NEW
586.0 12.0 35.0 541 KB

Protocol Buffer companion tool. Track your .proto files and prevent changes to messages and services which impact API compatibility.

Home Page: https://protolock.dev

License: BSD 3-Clause "New" or "Revised" License

Go 98.06% Shell 0.65% JavaScript 1.04% Dockerfile 0.25%
protocol-buffers protoc protobuf tools productivity cli golang proto-files

protolock's Introduction

protolock

Track your .proto files and prevent changes to messages and services which impact API compatibility.

Tests GoDoc

Why

Ever accidentally break your API compatibility while you're busy fixing problems? You may have forgotten to reserve the field number of a message or you re-ordered fields after removing a property. Maybe a new team member was not familiar with the backward-compatibility of Protocol Buffers and made an easy mistake.

protolock attempts to help prevent this from happening.

Overview

  1. Initialize your repository:

     $ protolock init
     # creates a `proto.lock` file
    
  2. Add changes to .proto messages or services, verify no breaking changes made:

     $ protolock status
     CONFLICT: "Channel" is missing ID: 108, which had been reserved [path/to/file.proto]
     CONFLICT: "Channel" is missing ID: 109, which had been reserved [path/to/file.proto]
    
  3. Commit a new state of your .protos (rewrites proto.lock if no warnings):

     $ protolock commit
     # optionally provide --force flag to disregard warnings
    
  4. Integrate into your protobuf compilation step:

     $ protolock status && protoc -I ...
    

In all, prevent yourself from compiling your protobufs and generating code if breaking changes have been made.

Recommended: commit the output proto.lock file into your version control system

Install

If you have Go installed, you can install protolock by running:

  • Go >= 1.17:

     go install github.com/nilslice/protolock/cmd/protolock@latest
  • Go < 1.17:

     go get github.com/nilslice/protolock/cmd/protolock

Otherwise, download a pre-built binary for Windows, macOS, or Linux from the latest release page.

Usage

protolock <command> [options]

Commands:
	-h, --help, help	display the usage information for protolock
	init			initialize a proto.lock file from current tree
	status			check for breaking changes and report conflicts
	commit			rewrite proto.lock file with current tree if no conflicts (--force to override)

Options:
	--strict [true]		enable strict mode and enforce all built-in rules
	--debug	[false]		enable debug mode and output debug messages
	--ignore 		comma-separated list of filepaths to ignore
	--force [false]		forces commit to rewrite proto.lock file and disregards warnings
	--plugins 		comma-separated list of executable protolock plugin names
	--lockdir [.]		directory of proto.lock file
	--protoroot [.]		root of directory tree containing proto files
	--uptodate [false]	enforce that proto.lock file is up-to-date with proto files

Related Projects & Users

Rules Enforced

No Using Reserved Fields

Compares the current vs. updated Protolock definitions and will return a list of warnings if any message's previously reserved fields or IDs are now being used as part of the same message.

No Removing Reserved Fields

Compares the current vs. updated Protolock definitions and will return a list of warnings if any reserved field has been removed.

Note: This rule is not enforced when strict mode is disabled.

No Changing Field IDs

Compares the current vs. updated Protolock definitions and will return a list of warnings if any field ID number has been changed.

No Changing Field Types

Compares the current vs. updated Protolock definitions and will return a list of warnings if any field type has been changed.

No Changing Field Names

Compares the current vs. updated Protolock definitions and will return a list of warnings if any message's previous fields have been renamed.

Note: This rule is not enforced when strict mode is disabled.

No Removing Fields Without Reserve

Compares the current vs. updated Protolock definitions and will return a list of warnings if any field has been removed without a corresponding reservation of that field name or ID.

No Removing RPCs

Compares the current vs. updated Protolock definitions and will return a list of warnings if any RPCs provided by a Service have been removed.

Note: This rule is not enforced when strict mode is disabled.

No Changing RPC Signature

Compares the current vs. updated Protolock definitions and will return a list of warnings if any RPC signature has been changed while using the same name.


Docker

docker pull nilslice/protolock:latest
docker run -v $(pwd):/protolock -w /protolock nilslice/protolock init

Plugins

The default rules enforced by protolock may not cover everything you want to do. If you have custom checks you'd like run on your .proto files, create a plugin, and have protolock run it and report your warnings. Read the wiki to learn more about creating and using plugins.


Contributing

Please feel free to make pull requests with better support for various rules, optimized code and overall tests. Filing an issue when you encounter a bug or any unexpected behavior is very much appreciated.

For current issues, see: open issues


Acknowledgement

Thank you to Ernest Micklei for his work on the excellent parser heavily relied upon by this tool and many more: https://github.com/emicklei/proto

protolock's People

Contributors

aroch avatar btc avatar celrenheit avatar evanlknapp avatar irejanodev avatar jeffmendoza avatar lidavidm avatar liusheng avatar milton0825 avatar mooons avatar nilslice avatar noel-yap avatar pdecks avatar prernagoyal avatar wikiwong avatar yaseenalk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

protolock's Issues

Rule "No Removing Fields Without Reserve" Should not break while renaming an existing field

Let's say I have this proto definition.

syntax = "proto2";

package tutorial;

option java_package = "com.test.address";
option java_outer_classname = "AddressBookProtos";

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phones = 4;
}

message AddressBook {
  repeated Person people = 1;
}

And if I change the required string name = 1 . to required string full_name = 1 then when I use status command then i get a warning regarding rule No Removing Fields Without Reserve.

As per my understanding this should not happen because I am keeping the tag number same (and even the data type).

Enum aliases not supported

Using protolock v0.15.0, with the following proto:

syntax="proto3";

enum Foo {
  BAR = 0;
  BAZ = 1;
}

After committing the lockfile, and making the following (backwards compatible) changes:

syntax="proto3";

enum Foo {
  option allow_alias = true;
  BAR = 0;
  BAZ = 1;
  QUUX = 1;
}

Running protolock status, we get the following error:

→ protolock status
CONFLICT: "Foo" field: "QUUX" integer: 1 has an updated name, previously "BAZ" [foo.proto]

Release asset naming

Currently release asset names look like this: protolock.20180621T191216Z.darwin-amd64.tgz

It's quite hard to build tooling around this naming convention. It would be nice to have the version in the file name instead of the build date.

WDYT?

Removing entire message triggers NoRemovingFieldsWithoutReserve

For the following test file:

syntax = "proto3";

package foo;

message Bar {
	int32 baz = 1;
}

Running protolock init, then deleting message Bar entirely. Then running protolock status.

Expected Behavior

No error.

Actual Behavior

CONFLICT: "Bar" field: "baz" has been removed, but is not reserved [test.proto]
CONFLICT: "Bar" ID: "1" has been removed, but is not reserved [test.proto]

When run with --strict false, the errors do not appear.


Would be glad to do a PR if there's consensus that these errors are erroneous.

Commit command no longer saves the lock under certain circumstances

This change 7c91881#diff-57de67624b47e4a29ab98fbcc5904d81
introduced a bug when commit is used with force set to false (the default).

Previously committing an empty json proto lock would generate the proper proto lock file, now it does nothing.

Root cause:

	case "commit":
		// if force option is false (default), then disallow commit if
		// there are any warnings encountered by runing a status check.
		if !*force {
			status(cfg) // <-- this currently always exits on all code paths.
		}

		r, err := protolock.Commit(*cfg)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		err = saveToLockFile(*cfg, r) // <-- never reached even if there were no warnings.
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

Since the linked change, status always exits the process and this never reaches saveToLockFile even if there were no warnings.

Breaking change was the unconditional exit at the end of the status function with the code from the refactored handleReport, previously the status would only exit on non-zero.

I suggest the behavior is reverted.

use yaml for proto.lock to reduce diff

We are managing hundreds of protos which result in a lock file with one hundred thousand lines. When we changed something, and commit the changes to the lock, a very large diff will be produced with many many lines changed, though in fact I only added a few files or fields. I think this is because the json file has many braces. The braces always match in diff, causing diff believes that the paths or the field names have changed. I think yaml shoul be a better choice for this lock file, which has no braces in independent lines, and it can store small objects in one line (so that there won't be many id: 0).

Deterministic definition order.

For readability it would be nice if the proto paths would sorted alphabetically

{
  "definitions": [
    {
      "protopath": "fub:/:baz:/:some_proto.proto",
     ....
    },
   {
      "protopath": "other:/:foo:/:other_proto.proto",
   {
  ]
}

Add flag option to ignore paths in init / commit / status

It could be desirable to only track your own .proto files, and not those included in directories such as vendor, other 3rd party libraries, etc.

an option such as --ignore=vendor,lib/include,extern could enable users to have this flexibility.

Strings using single quotes not parsed correctly.

I only have a description of the issue.

Someone reported a .proto file with reserved 'is_success', 'error_response'. The proto.lock file that's generated has:

                        "reserved_names": [
                            "",
                            "",
                            "",
                            ""
                        ]

If double quotes are used in the .proto file, the generated file looks better.

use protobuf instead of json for proto.lock file

I'm wondering if there is interest in using binary protobufs as the lock file encoding, rather than JSON.

The main benefit would be serialization speed (each status check will deserialize the proto.lock file, and if it is large, can slow down the tool). Additionally, protolock itself could be used to guarantee no breaking changes to its own internal lock model.

I personally have not found that the human-readable JSON format is entirely useful... readability would be lost if the file was in binary encoding. However, it would be trivial to have a --output=json|yaml|toml flag and write the lock data to stdout for user consumption.

Add support for Field Options

We would like to use protolock with plugins which would validate specific field options.
I saw that Message Options are supported, but couldn't find support for Field Options.
Are there any plans to add support for Field Options to be saved also in the proto.lock file?
If not and you like the feature, we would be glad to implement and contribute.

Add support for custom RPC Options

I would like to use protolock with plugins i intend on making that validate custom RPC options. I saw that Field and Message Options are now recently supported in #61 and #71 . Are there any plans to support custom RPC options in the proto.lock file? If not let me know and I can work on contributing. Thanks!

Propose to publish ARM64 binary in releases

Hi there, I would like to propose to publish ARM64/aarch64 specific arch binaries in protolock releases. I have tried to make other projects such as Alluxio running on ARM64 server, because it depend on protolock (loaded by proto-backwards-compat-maven-plugin maven plugin) while protolock does not have ARM64 binary in releases. I have tried manually compiling protolock on my ARM64 server, everything looks OK, So is there possible to also publish protolock binary for ARM64 platform ?

FYI:
Alluxio ARM support issue: Alluxio/alluxio#12704
proto-backwards-compat-maven-plugin ARM support issue: salesforce/proto-backwards-compat-maven-plugin#21

Thanks.

Absolute fully qualified packages incorrectly produces empty `{}` block in `proto.lock` file.

$ cat aoeu.proto
syntax = "proto3";

package com.example.aoeu;

import "snth.proto";

service AoeuService {
  rpc Method (Request) returns(Empty);
}

message Request {
  .example.snth.Field field1 = 1;
  .example.snth.Field field2 = 2;
}
$ cat snth.proto
syntax = "proto3";

package example.snth;

message Field {}

protolock init will produce:

$ cat proto.lock
…
                        "name": "Request",
                        "fields": [
                            {
                                
                            },
                            {
                                "id": 1,
                                "name": "field1",
                                "type": "example.snth.Field"
                            },
                            {
                                
                            },
                            {
                                "id": 2,
                                "name": "field2",
                                "type": "example.snth.Field"
                            }
                        ]
…

Upon protolock status, the empty {} blocks will error with:

CONFLICT: "Request" is re-using ID: 0, a reserved field number [src/main/proto/aoeu.proto]
CONFLICT: "Request" is re-using name: "", a reserved field name [src/main/proto/aoeu.proto]

Nested messages not locking

It seems that nested messages are not currently support unless I have missed something.

Repro

syntax = "proto3";

package test;

message Outer {
    message Inner {
        string name = 1;
    }

    Inner inner_msg = 1;
}
protolock init && protolock commit && protolock status

Change the the name field identifier.

message Outer {
    message Inner {
        string name = 2;
    }

    Inner inner_msg = 1;
}

Running protolock status will exit cleanly. Is this a known issue or is there planned support for nested messages? I can take a stab at adding it if not.

Thanks!

gRPC Conf talk mention: collaborators, companies, use-cases, etc

Hey -- excited to share that I'll be speaking about protolock at the first gRPC Conf! I wanted to mention the support and many contributions made from community members and if possible, the companies using the tool and if you have plugins or workflow use cases that could be briefly mentioned as well.

If you're open to it, please either comment here or add your company/link to the Related Users & Projects section of the README 👍 as well as comments on this thread with any detail at all about your team/projects/workflows/plugins etc related to protolock. I'd really like to highlight the work done by contributors and how you all have significantly improved the tooling.

cc: @wikiwong @celrenheit @btc @jeffmendoza @aroch @november-yankee @milton0825 @evanlknapp @mmmveggies

Thanks!

Processing a single file

Hi there, thanks for a great tool! We're using pre-commit (pre-commit.com) to run checks before committing to my company's repo, and I'd love to integrate protolock to validate and commit changed .proto files.

Pre-commit is set up to pass filenames (either one at a time or a list, depending on what the tool can support) of modified files matching a pattern (like .proto) to a particular command-line tool. So the first enhancement would be to support protolock commit <filename>.

The second enhancement is minor but would also be helpful - if there were an option to make protolock commit <filename> return a non-zero status when proto.lock is actually updated (optionally with a message like "Updated proto.lock"), that would allow pre-commit to abort a git commit so that the user can add the modified file.

Let me know if you need additional information or would like an example of how to configure!

Considering a configuration file for protolock

Has a generic configuration file been considered for the tool (in addition to command line args)? It seems like a nice to have, especially for our workflow. We could have a similar setup prior to invoking protolock, but I'm happy to open a PR for a more generic solution if this aligns with the project's goals.

Lock file does not record aggregate options with array values

Reproduction

  1. Construct a message with a field with a compound option with an array value.
message FloatIn { float val = 1 [(validate.rules).float = {in: [4.56, 7.89]}]; }
  1. Run protolock init
  2. Inspect proto.lock

Expected

  • Lock file tracks option values

Actual

  • Lock file tracks option presence and name, but value is missing.
          {
            "name": "FloatIn",
            "fields": [
              {
                "id": 1,
                "name": "val",
                "type": "float",
                "options": [
                  {
                    "name": "(validate.rules).float",
                    "aggregated": [
                      {
                        "name": "in"
                      }
                    ]
                  }
                ]
              }
            ]
          },

Website incorrectly reports backwards compatibility with invalid proto files

My guess is this is the proper place to post issues for the website protolock.dev If it isn't, feel free to point me somewhere else.

Go to protolock.dev, hit the init button. Make an incompatible change to the proto file (e.g. change SERVICE_UNKNOWN = 3 -> SERVICE_UNKNOWN = 9) and then make the proto file invalid, e.g. s/rpc/dog/g and it will mark it as backwards compatible.

This actually isn't the case with the CLI:

$ protolock status         
[protolock]: root.proto:17:5: found "dog" but expected [service comment|rpc]

So I figure this is a bug.

Error building protolock on ppc64le

The below error appears when I try to build protolock repo on a ppc64le system.

Error:-
bash-4.4# go get -u github.com/nilslice/protolock/...
github.com/nilslice/protolock/cmd/protolock
/root/go/src/github.com/nilslice/protolock/cmd/protolock/plugins.go:147:20: undefined: strings.ReplaceAll
bash-4.4#

go version go1.9.1 linux/ppc64le

Need to generate the protolock file. Inputs around the issue would be of help.

oneof structure is not persisted in protolock

I'd like to add some additional rules for my own use case of protolock. From reading the wiki, it's my understanding that the preferred way to add more rules is to implement them in a plugin, which takes as input a Protolock go struct that is built from the output of the proto parser.

One rule I'd like to add is to check if a field becomes part of a oneof, or if it is removed from a oneof. However, I don't believe this is possible because the Protolock file does not track which fields are in oneofs. One way around this could be to introduce an optional "oneof parent" pointer for fields (demonstrated here) but I'm not sure if that is the most elegant solution.

I would like to hear your thoughts on this and whether this was previously considered and rejected, or if there is a way to find oneofs in the plugins that I am not aware of. Happy to also author a PR or help out however I can! CCing @adisuissa

Add Support for RPC Comments

I would like to use protolock with a plugin that I plan to use to verify custom logic in my .proto files. Specifically, for some of our RPC's we have an internal way of decorating them as "Incubating" (under development) and therefor we want to have them skipped when doing validation as they may be in flux a bit. My intention was to mark each of these RPC's with a "@protolock:skip" comment and make a rule that if protolock finds an RPC with the "Incubating" tag to make a warning for it.

But I noticed that RPC's don't have Comments right now. Was there any plan to add support for this? Or should I go ahead with adding support for this myself?

Allow users to ignore specific built-in rules by name

I would like to be able to specify which built-in rules to ignore on the command line. Currently, the closest mechanism that exists is the strict flag, but the rules that disables aren't the ones I would like to disable. (I'm facing a situation where I want to prevent proto message breakages, but I'm okay with RPC compatibility breakages.)

If you agree this would be good to have, I'm happy to send a PR for this your way. 🙂

conflicts in built-in rules will fail the execution of plugins

Hi,

When running with plugins, I noticed that when I get warnings from the built-in rules, it fails during the execution of the plugins and exits with failure.

For example, when running without plugins:

$ protolock status
CONFLICT: "XXX" field: "yyy" has been removed, but is not reserved [zzz.proto]
...

Then, if running with a plugin:

$ protolock status --plugins=plugin_name
[protolock:plugin] accumulated plugin errors:
plugin_name: exit status 2 (/path/to/plugin)

I didn't test this, but what I believe is happening is that as plugins run in their own goroutines, the execution continues and reaches the handleReport function which writes the report to STDOUT which is being read by the plugins, causing the plugins input to be invalid like:

CONFLICT: "XXX" field: "yyy" has been removed, but is not reserved [zzz.proto]
...
{
protolock-json
}

report, err := protolock.Status(*cfg)
if err != protolock.ErrWarningsFound && err != nil {
fmt.Println("[protolock]:", err)
os.Exit(1)
}
// if plugins are provided, attempt to execute each as a exeutable
// located in the user's OS executable path as reported by stdlib's
// exec.LookPath func
if *plugins != "" {
report, err = runPlugins(*plugins, report)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
handleReport(report, err)

But my analysis might be wrong :)

Add Support for Entry Level Options

I am looking to add options at a file (Entry) level in protolock. A lot of our protobuf files resemble the following:

syntax = "proto3";

package test.package.v1;

import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";

option java_multiple_files = true;
option java_package = "com.test.package.v1";
option java_outer_classname = "TestProto";

service MyService {
 ...
}

message MyMessage {
 ...
}

In addition to general protobuf file options my workplace has custom options that are also used at a file level. We'd like to add rules to makes sure in our custom plugin that options don't change. Would this be something we can add to protolock.

Options not parsed at the Enum level

Hi,
Recently I've been working on creating a custom protolock plugin specific to my codebase. My plugin relies on a few custom options I've defined. Using protolock, custom options defined at the file level and message level are parsed by the tool into the Protolock struct, but options defined inside enums are not parsed by the tool.

The Entry struct contains the Options field which receives all of the file level options after parsing.

type Entry struct {
	Enums    []Enum    `json:"enums,omitempty"`
	Messages []Message `json:"messages,omitempty"`
	Services []Service `json:"services,omitempty"`
	Imports  []Import  `json:"imports,omitempty"`
	Package  Package   `json:"package,omitempty"`
	Options  []Option  `json:"options,omitempty"`
}

Similarly, the Message struct also contains an Options field which the message level options are parsed into.

type Message struct {
	Name          string    `json:"name,omitempty"`
	Fields        []Field   `json:"fields,omitempty"`
	Maps          []Map     `json:"maps,omitempty"`
	ReservedIDs   []int     `json:"reserved_ids,omitempty"`
	ReservedNames []string  `json:"reserved_names,omitempty"`
	Filepath      Protopath `json:"filepath,omitempty"`
	Messages      []Message `json:"messages,omitempty"`
	Options       []Option  `json:"options,omitempty"`
}

However, Enum options are ignored during parse. The Enum struct does not include an Options field, but it does include the AllowAlias option which is one of many possible enum level options.

type Enum struct {
	Name          string      `json:"name,omitempty"`
	EnumFields    []EnumField `json:"enum_fields,omitempty"`
	ReservedIDs   []int       `json:"reserved_ids,omitempty"`
	ReservedNames []string    `json:"reserved_names,omitempty"`
	AllowAlias    bool        `json:"allow_alias,omitempty"`
}

Is there a reason for this decision to not include the Options field for enums? If not, would it be difficult/possible to include enum level options?

An example of what I'm trying to do is:

enum TestEnum {
    option (custom_option) = true;
    DEFAULT = 0;
    FIRST = 1;
    SECOND = 2;
}

Thank you!

commit command doesn't run plugins

If --force option is not used, the 'commit' command runs 'status' before doing the commit.
If the user uses plugins as part of the 'status' command (with the --plugins option), I think he would expect that the same plugins would be run as part of the 'commit' command with same plugins option, so no validation is missed.

skip hint should also prevent members from being compared

currently, // @protolock:skip hints prevent a proto member such as a message from being added to the proto.lock file. But if a hint was added after the proto.lock file was written, then protolock thinks the message was just removed and several conflicts are reported.

consider skipping the message in the comparison step in addition to the serialization step.

Does protolock support proto2 ?

when I remove a required field from the following file, protolock status is ok.

`syntax = "proto2";

message IdCard {
reserved 1;
reserved "id";
//required string id = 1;
required string name = 2;
optional string addr = 3;
required string log = 4;
}
`

Nested messages conflicts

Hello,

I think there is an issue when using nested messages that have the same name. The following example should trigger a conflict:

syntax = "proto3";

package main;

message A {
    message I {
        int32 index = 1;
    }

    string id = 1;
    I i = 2;
}

message B {
    message I {
        int32 index = 1;
    }

    string id = 1;
    I i = 2;
}

This gives me the following error:

➜  protolock init
➜  protolock status
CONFLICT: "I" is re-using ID: 1, a reserved field [main.proto]
CONFLICT: "I" is re-using name: "index", a reserved field [main.proto]

auto-ignore paths/files in .gitignore

Wondering if this is a feature anyone wants, or if there is a better idea for cases where:

  • other proto-based tools (i.e. protoc) are kept in a repo but ignored by git. these tools contain their own .proto files that, most likely should be ignored.

Check if lockfile is up to date

Currently protolock will tell you if you made a breaking change, but it doesn't have a way to tell you whether the lock file is up-to-date with the input Protobuf files. Would adding that as a flag to status or adding a new subcommand be acceptable?

While you currently can have it generate a new lock file and diff the files, that's not so stable.

Plugin wiki readme json missing fields

I'm writing a Scala plugin to implement a compatibility check. For some reason I wrote the structure of the plugin input from the wiki readme rather than the code. In the process of getting it working I found some differences between the JSON structure in the readme and what is sent by protolock.

It seems I can't fork the wiki, so I'll attach a patch to this issue (apparently as a text file because Github won't accept a .patch file type...)
0001-update-readme-with-missing-fields.txt

PS: Thanks for writing protolock! It's a really elegant tool.

proto.lock file cross OS compatibility

Within the lock file, the current OS filepath separator is used to compare entries. This will be an issue where a unix system writes and checks in a lock file, and a windows system runs a status check (or vice versa).

Instead of using the current system's filepath separator, replace it with something like : or another character that couldn't be used in a valid filepath. This would need to be reversed when writing out the filepath in a report's warning.

Weird flag parser

Hi, just found out about the project - that's a neat tool!
I've just tried to add it to our Makefile and encountered a problem with flag parser.
Command protolock --ignore=vendor status seems to be parsed as

protolock
ignore="vendor status"

It looks like a bug to me esp since ignore should be comma-delimited.
--ignore="vendor" status behaves like that as well.

Ignore Option Not Working on Windows

I was using protolock locally when I started having issues with ignoring directories. I found eventually that the parse_test.go tests were failing for me on windows (with no local changes) and that stepping through the code things weren't behaving right.

I think I limited it down to this line not working correctly.

if !strings.HasPrefix(rel, "../") {

My assumption is that this line is making a big assumption about path separators depending on what the operating system in use is. When I changed it to be this:

if !strings.HasPrefix(rel, ".." + string(os.PathSeparator)) {

Everything appeared to work as expected.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.