Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mtree: implement manifest comparisons #48

Merged
merged 6 commits into from
Nov 11, 2016
Merged

mtree: implement manifest comparisons #48

merged 6 commits into from
Nov 11, 2016

Conversation

cyphar
Copy link
Contributor

@cyphar cyphar commented Jul 27, 2016

This patchset implements manifest comparison as a first-class primitive and then refactors all of the other checking and validation code into manifest comparison operations. This ensures consistency of comparisons, less code to maintain as well as providing some extra features to the client that are not available already. It also increases the usefulness of go-mtree as a standalone library.

Supersedes #34.

Signed-off-by: Aleksa Sarai asarai@suse.de

@vbatts
Copy link
Owner

vbatts commented Aug 1, 2016

@cyphar how much of this can be incrementally done? If I am merging other fixes and features, I'd hate for so much rebasing for you 😬

@cyphar
Copy link
Contributor Author

cyphar commented Aug 3, 2016

Right now, this is good enough for my usecase (you could in principle do all of the comparisons you ever need manually). But there's still a bunch of code refactoring that needs to take place (especially in the tar handling code).

@vbatts
Copy link
Owner

vbatts commented Aug 3, 2016

ok. so, much tar refactoring and fixes have happened in #55
I need to review the ordering of getting both of these PRs merged

@cyphar
Copy link
Contributor Author

cyphar commented Aug 8, 2016

You can merge #55 first, because I'm also doing a clean-up of the dhCreator code (everyone is using it even though it actually isn't necessary because there's a bug that I fixed). I also probably will reconsider rewriting parts of the tar handling code because I don't understand why it is so complicated (what is the purpose of flatten?).

I'm also going to change the comparison interfaces. You don't need interfaces here.

@imsteev
Copy link

imsteev commented Aug 8, 2016

The purpose of flatten is there because of the fact that the archive stream could give us files in any order. Thus, if we are trying to keep track of positions, as well as inserting more Entry's, we would constantly have to shift items in order to retain correct ordering.

@cyphar
Copy link
Contributor Author

cyphar commented Aug 8, 2016

Okay, I'll see how much my dhCreator and related fixes can make flatten and the other tar-handling functions cleaner. But I'll work on that after #55 is merged (currently I'm super busy with other rewriting in runC).

@vbatts
Copy link
Owner

vbatts commented Aug 10, 2016

@cyphar please2rebase?

@vbatts
Copy link
Owner

vbatts commented Oct 12, 2016

@cyphar would love to see this merged 😸

@cyphar
Copy link
Contributor Author

cyphar commented Oct 12, 2016

I know, and I've been drowing in other issues since I started this PR. 😉 I'll take a look at this next week.

@cyphar
Copy link
Contributor Author

cyphar commented Oct 30, 2016

The comparison code fails some tar to regular dir tests because the tar code appears to be broken. I'll open an issue about it separately. Also Go 1.5.3 is failing for reasons outside of my issue.

@cyphar
Copy link
Contributor Author

cyphar commented Oct 31, 2016

@vbatts I've reimplemented everything using Compare(). PTAL. My biggest question is whether the changes I've made to gomtree (the CLI interface) are fine for BSD compatibility.

@vbatts
Copy link
Owner

vbatts commented Oct 31, 2016

(i've opened #78 which will address the CI failure)

@cyphar cyphar changed the title [WIP] mtree: implement manifest comparisons mtree: implement manifest comparisons Oct 31, 2016
@vbatts
Copy link
Owner

vbatts commented Oct 31, 2016

go vet for go1.7.3 complains compare_test.go:381: syscall.Timespec composite literal uses unkeyed fields

@cyphar
Copy link
Contributor Author

cyphar commented Oct 31, 2016

I'm reimplementing it using os.Chtimes now.

@cyphar
Copy link
Contributor Author

cyphar commented Oct 31, 2016

@vbatts Okay, I've cleaned up all of the commits and it all appears to work. I've even included the tar testing (though I have to ignore the known bugs in #77).

@vbatts
Copy link
Owner

vbatts commented Oct 31, 2016

as i'm checking, a simple use of gomtree -c (which should default to creating a manifest from the current directory) fails on a nil pointer.

[vbatts@bananaboat] {(46d449e...)} ~/src/vb/go-mtree$ ./gomtree -c
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x402b7b]

goroutine 1 [running]:
panic(0x511c00, 0xc420016110)
        /home/vbatts/go1.7/src/runtime/panic.go:500 +0x1a1
main.main()
        /home/vbatts/src/vb/go-mtree/cmd/gomtree/main.go:315 +0xfab

@cyphar
Copy link
Contributor Author

cyphar commented Oct 31, 2016

Fixed. I forgot about that usage of the CLI.

@vbatts
Copy link
Owner

vbatts commented Oct 31, 2016

couple more issues:

[vbatts@bananaboat] {(5024980...)} ~/src/vb/go-mtree$ ./gomtree -f ~/mtree.mtree -p .
2016/10/31 13:12:59 Unknown keyword "flags" for file "."
[vbatts@bananaboat] {(5024980...)} ~/src/vb/go-mtree$ ./gomtree -f ~/mtree.mtree -p $(pwd)
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x70 pc=0x4949b5]

goroutine 1 [running]:
panic(0x511be0, 0xc420018110)
        /home/vbatts/go1.7/src/runtime/panic.go:500 +0x1a1
github.com/vbatts/go-mtree.Walk.func1.3(0x7bdf00, 0xc420079450, 0x7ffc68bcfad2, 0x1c, 0xc4200dd240, 0xc4200d4ce0, 0xc4200cec80, 0x0, 0x0)
        /home/vbatts/src/github.com/vbatts/go-mtree/walk.go:184 +0x155
github.com/vbatts/go-mtree.Walk.func1(0x7ffc68bcfad2, 0x1c, 0x7bdf00, 0xc420079450, 0x0, 0x0, 0xc420000340, 0x4d4109)
        /home/vbatts/src/github.com/vbatts/go-mtree/walk.go:188 +0x6d4
github.com/vbatts/go-mtree.walk(0xc4200d4ce0, 0x7ffc68bcfad2, 0x1c, 0x7bdf00, 0xc420079450, 0xc4200d0140, 0x1, 0xc4200d0140)
        /home/vbatts/src/github.com/vbatts/go-mtree/walk.go:237 +0x97
github.com/vbatts/go-mtree.startWalk(0xc4200d4ce0, 0x7ffc68bcfad2, 0x1c, 0xc4200d0140, 0x3, 0xc42009a400)
        /home/vbatts/src/github.com/vbatts/go-mtree/walk.go:232 +0xdf
github.com/vbatts/go-mtree.Walk(0x7ffc68bcfad2, 0x1c, 0x0, 0x0, 0x0, 0xc42000a600, 0x9, 0x10, 0x215544b200791e8, 0xc8, ...)
        /home/vbatts/src/github.com/vbatts/go-mtree/walk.go:208 +0x281
main.main()
        /home/vbatts/src/vb/go-mtree/cmd/gomtree/main.go:294 +0x1508

@vbatts
Copy link
Owner

vbatts commented Oct 31, 2016

oh. nm. hold that thought. ...
/me checks something else ...

@vbatts
Copy link
Owner

vbatts commented Oct 31, 2016

(it was something else)

@cyphar
Copy link
Contributor Author

cyphar commented Nov 4, 2016

@vbatts What remaining issues did you have with this?

Copy link
Owner

@vbatts vbatts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall i'm ready to merge it. The panics ought to get gone and a few other questions. I'm still yet to fully compare the behavoir of the cli of this PR vs. master

// ensure that we don't accidentally expose pointers to the caller that are
// internal data.
func ePtr(e Entry) *Entry { return &e }
func sPtr(s string) *string { return &s }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would not do this. Since these functions are not pointer receivers to begin with, then you may already have a copy of the object, not the original.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. This is just a function, not a function of Entry. Still, perhaps it is not necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "not returning the actual pointer" is intentional. The purpose of these is so that I can return a pointer (namely so I can say whether or not an entry is nil) that is not actually able to access the entries we're iterating over.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see that, though it is misleading as if it is the pointer to the item passed.

Also, not sure that it matters, but the ptr to an empty string is string is not nil. So, I'm not sure whether there is ever a case that a ptr to a string is returned, even though the string is empty (I realize that the predicate does not check the string contents)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I mean is that the callers of ePtr can return nil or a pointer to an entry. However, they don't want to leak the pointer to the actual entry and rather want to return a pointer to a copy. Because structs are passed by value in arguments, it works out.

As a point of comparison, how would you implement returning a "safe" pointer to an entry in the case of this line?

though it is misleading as if it is the pointer to the item passed.

I've seen this pattern in a few places. Problem is that I don't think there's another nice way of doing this without three lines of temporary variable stuff. To be fair, I was confused about it for a while because of how much I write C code ;).

// determined by the ordering of parameters to Compare).
func (i InodeDelta) Old() *Entry {
if i.diff == Modified || i.diff == Missing {
return ePtr(i.old)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shorthand seems like it is more cumbersome than just &i.old.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my above point. We don't want to return the actual pointer because then the caller could modify it (messing around with the mtree.DirectoryHierarchy).

// present in one manifest [Missing, Extra], keys only present in one of the
// manifests [Modified] or a difference between the keys of the same object in
// both manifests [Modified].
type InodeDelta struct {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only a slight nit. As the inode themselves are not being compared, only the attributes of the inodes, is it confusing to have this name be InodeDelta?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. It's ultimately up to you, but IMO we are comparing inodes here (namely their attributes, not just the contents). Which is kinda what the point of an inode is (to provide attributes of data).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair.

key := kv.Keyword()

// We cannot just take &kv here because it's the iterator. I
// learned this the hard way.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heh. Thanks for such a comment. :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can remove it, it just took me a while to figure that out. :P

// cached version of inode.keys.
func compareEntry(oldEntry, newEntry Entry) []KeyDelta {
// Represents the new and old states for an entry's keys.
type stateT struct {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

particular reason for defining this type inside the function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only used inside the function. I get that it's not the prettiest thing in the world but because it's effectively just a way of holding a tuple I don't really see the benefit of making it a type external to the function. Your call though.


diffs["tar_time"].New = newTime
} else {
panic("time and tar_time set in the same manifest")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ouch, panic()? 😬
Is there no error condition? perhaps this compareEntry() could have the capacity to also return error :-)

Copy link
Contributor Author

@cyphar cyphar Nov 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, I'll make these return errors. 😛 Real programmers don't need error handling.

for name, diff := range diffs {
// Invalid
if diff.Old == nil && diff.New == nil {
panic("invalid state: both old and new are nil")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah.

for path, diff := range diffs {
// Invalid
if diff.Old == nil && diff.New == nil {
panic("invalid state: both old and new are nil")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

}
return &result, nil
// TODO: Handle tar_time, if necessary.
return Compare(dh, newDh, keywords)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is much nicer of an API

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cheers. 😸

@cyphar
Copy link
Contributor Author

cyphar commented Nov 4, 2016

@vbatts I fixed up the panics and comments. I think that your other comments about the ptr functions are note correct, but please check my responses. Ultimately if you want I can fix up all of these implementation details in a follow-up PR.

@vbatts
Copy link
Owner

vbatts commented Nov 4, 2016

Understood

On Fri, Nov 4, 2016, 10:25 Aleksa Sarai notifications@github.com wrote:

@cyphar commented on this pull request.

In compare.go #48:

  • // Extra represents a discrepancy where the object is not present in
  • // the @old manifest but is present in the @new manifest.
  • Extra DifferenceType = "extra"
    +
  • // Modified represents a discrepancy where the object is present in
  • // both the @old and @new manifests, but one or more of the keys
  • // have different values (or have not been set in one of the
  • // manifests).
  • Modified DifferenceType = "modified"
    +)
    +
    +// These functions return *type from the parameter. It's just shorthand, to
    +// ensure that we don't accidentally expose pointers to the caller that are
    +// internal data.
    +func ePtr(e Entry) *Entry { return &e }
    +func sPtr(s string) *string { return &s }

What I mean is that the callers of ePtr can return nil or a pointer to an
entry. However, they don't want to leak the pointer to the actual entry
and rather want to return a pointer to a copy. Because structs are passed
by value in arguments, it works out.

As a point of comparison, how would you implement returning a "safe"
pointer to an entry in the case of this line
https://github.com/vbatts/go-mtree/pull/48/files#diff-441184bdb490a3dda4d6f21fb9db907cR76
?

though it is misleading as if it is the pointer to the item passed.

I've seen this pattern in a few places. Problem is that I don't think
there's another nice way of doing this without three lines of temporary
variable stuff. To be fair, I was confused about it for a while because of
how much I write C code ;).


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
#48, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAEF6f9M1YdDlT082vrRGITrgIUM0-aEks5q62pWgaJpZM4JWH66
.

@cyphar
Copy link
Contributor Author

cyphar commented Nov 7, 2016

@vbatts Ping. If you want me to switch to returning the internal Entry inside the InodeDelta, just say the word 😉. Currently I'm vendoring my fork of this project into umoci which is a bit of a pain IMO. Not to mention that it means I can't merge my layer diff generation to image-tools upstream.

@vbatts
Copy link
Owner

vbatts commented Nov 7, 2016

@cyphar i was about to merge it, and just clean up the panic() afterwards, but when testing and comparing the cli behavior against master, it seems there is a regression, but no tests that catch it. So I started on getting a test to pin the behavior.

@cyphar
Copy link
Contributor Author

cyphar commented Nov 7, 2016

@vbatts Ah okay, fair enough. Once you get a test case tell me and I'll fix it. Even if you can just give me an example of the regression I can work on fixing it this week.

@vbatts
Copy link
Owner

vbatts commented Nov 7, 2016

@cyphar so with #82, I rebased your branch on this, and and see a difference like:

[0001.sh] Running in /tmp/go-mtree.sUqF0I
~/syncthing/workspace/go-mtree ~/src/vb/go-mtree
"testdata/collection/dir5/dir6": keyword "size": expected ; got 60
"testdata/dirwithbrokenlink/deepdir/dir3/dir4/dir5/dir6": keyword "size": expected ; got 60
"testdata/dirwithbrokenlink/dir1/dir2/.hidden": keyword "size": expected ; got 60
"testdata/dirwithbrokenlink/deepdir/dir3/dir4/dir5": keyword "size": expected ; got 80
"testdata/dirwithbrokenlink/dir1/dir2": keyword "size": expected ; got 60
"testdata/traversal": keyword "size": expected ; got 60
"cmd/gomtree": keyword "size": expected ; got 60
"testdata/collection/dir3": keyword "size": expected ; got 60
"testdata/collection/dir5": keyword "size": expected ; got 60
"testdata/dirwithbrokenlink/deepdir/dir3/dir4": keyword "size": expected ; got 80
"testdata/traversal/dir2": keyword "size": expected ; got 60
"testdata/collection/dir2": keyword "size": expected ; got 60
"testdata/traversal/dir2/dir3/actualdir1": keyword "size": expected ; got 80
"testdata/collection/dir4": keyword "size": expected ; got 60
"testdata/singlefile/dir2": keyword "size": expected ; got 60
"testdata/dirwithbrokenlink/deepdir/dir3/dir4/dir5/dir7": keyword "size": expected ; got 60
"testdata/dirwithbrokenlink/dir1": keyword "size": expected ; got 120
"testdata/collection/dir1": keyword "size": expected ; got 60
"testdata/collection": keyword "size": expected ; got 200
"test/cli": keyword "size": expected ; got 60
"testdata/dirwithbrokenlink/deepdir": keyword "size": expected ; got 80
"testdata/traversal/dir2/dir3": keyword "size": expected ; got 120
"testdata/dirwithbrokenlink/deepdir/dir3": keyword "size": expected ; got 120
"testdata/traversal/dir2/dir3/actualdir2": keyword "size": expected ; got 100
"testdata/dirwithbrokenlink": keyword "size": expected ; got 140
"testdata/collection/dir5/dir6/dir7": keyword "size": expected ; got 60
"cmd": keyword "size": expected ; got 60
"xattr": keyword "size": expected ; got 100
"testdata/singlefile": keyword "size": expected ; got 60
"test": keyword "size": expected ; got 60
"testdata": keyword "size": expected ; got 240
"testdata/singlefile/dir2/dir3": keyword "size": expected ; got 60
".": keyword "size": expected ; got 780

@vbatts
Copy link
Owner

vbatts commented Nov 7, 2016

I merged the tests, so you can now rebase on master.

Fix a bug in the parser that caused all iterators to have to handle the
/set and /unset semantics separately. In addition, provide a helper
function to correctly generate the merged set of keywords for a
particular entry.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
This is part of a patchset that refactors all of the checking logic into
comparison operations. Essentially, provide a Compare(...) function that
allows for two different manifests to be compared. Extra and missing
entries are supported in addition to the standard modified entry, and by
implementing as a manifest comparison there is no double-scanning of the
manifest source.

The main annoyance is that we have to also include tar_time handling,
which has not been abstracted inside keywords.go. This is a bit ugly
right now, but works fine for the moment.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
Switch the commandline to use the .Compare() API when checking
specification files against the state of a tar archive or other archive.
The main purpose is to completely remove the check.go code from being
necessary (outside of a wrapper).

Signed-off-by: Aleksa Sarai <asarai@suse.de>
While the full testing is broken due to bugs in the tar DH generator, we
ignore known bugs in the tar generator to at least allow us to test some
of the other semantics of Compare.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
This removes all of the special handling code for both TarCheck() and
Check() so that everything now uses the new (generic) Compare() code. In
addition, the tests had to be modified to reflect the new classes of
errors.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
@cyphar
Copy link
Contributor Author

cyphar commented Nov 10, 2016

@vbatts I've figured it out. It's not because of any of my changes. It's because the tar spec generation is utterly broken. Look at the output of a -T generated mtree file:

#          user: cyphar
#       machine: gordon
#          tree: <user specified tar archive>
#          date: Thu Nov 10 11:55:03 2016

# .
. type=dir

# cmd
/set type=file mode=0664 uid=0 gid=0
cmd type=dir mode=0775 tar_time=1478739303.000000000

# cmd/gomtree
gomtree type=dir mode=0775 tar_time=1478739303.000000000
    main.go size=7438 tar_time=1478739303.000000000 sha256digest=f1486c95ca1528abd10f75b57eb0329656fcd18845fccdeff615558d598b4a2b

The main thing to note is that directory entries don't contain the keyword that we were asked to check against. I've added a commit which ignores keywords that are missing from a manifest, but this isn't a nice solution to the problem.

Of course, another issue is that you actually can't get size from a tar archive for a directory. So there's just a certain class of issues we can't solve. Another issue (which is legitimately a problem with the tar generation code) is that . doesn't have any information filled in. I can fix it with the above hack too, but that's just getting nasty.

Due to several unsolveable problems in tar generation, such as the
size=... keyword, we have to special case quite a few things in the
checking code. We might want to move this to mtree properly (but I'm
hesitant about ignoring errors that only happen for tar DHes).

Signed-off-by: Aleksa Sarai <asarai@suse.de>
@cyphar
Copy link
Contributor Author

cyphar commented Nov 10, 2016

@vbatts I've fixed the test failures by using the above hack (implemented in 3bfdecf). IMO we should have a way inside an mtree manifest to specify that a particular key is "unsupported" so that this skipping logic can be implemented inside Compare.

@vbatts
Copy link
Owner

vbatts commented Nov 10, 2016

Yeah. It is one of the cases that we have to only check what we can or
check what applies. And '.' in most tar archives is just implied, so no
mode/UID/gid. The 'size' of dirs is something that IIRC asking Stephen to
drop, because they are 0size in an archive, but usually 4096b on disk (and
even at that, dir inside size varies from Linux to bsd for even the same
dir).

Having a way to give a keyword context of being supported or not would be
helpful.

On Wed, Nov 9, 2016, 20:08 Aleksa Sarai notifications@github.com wrote:

@vbatts https://github.com/vbatts I've figured it out. It's not because
of any of my changes. It's because the tar spec generation is utterly
broken. Look at the output of a -T generated mtree file:

user: cyphar

machine: gordon

tree:

date: Thu Nov 10 11:55:03 2016

.

. type=dir

cmd

/set type=file mode=0664 uid=0 gid=0
cmd type=dir mode=0775 tar_time=1478739303.000000000

cmd/gomtree

gomtree type=dir mode=0775 tar_time=1478739303.000000000
main.go size=7438 tar_time=1478739303.000000000 sha256digest=f1486c95ca1528abd10f75b57eb0329656fcd18845fccdeff615558d598b4a2b

The main thing to note is that directory entries don't contain the
keyword that we were asked to check against
. I've added a commit which
ignores keywords that are missing from a manifest, but this isn't a nice
solution to the problem.

Of course, another issue is that you actually can't get size from a tar
archive for a directory. So there's just a certain class of issues we can't
solve. Another issue (which is legitimately a problem with the tar
generation code) is that . doesn't have any information filled in. I can
fix it with the above hack too, but that's just getting nasty.


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
#48 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAEF6fF2Ocse44VlvyHkSyYEJqw53Uxbks5q8m55gaJpZM4JWH66
.

@cyphar
Copy link
Contributor Author

cyphar commented Nov 10, 2016

@vbatts Fixing the supported / unsupported issue should be solved separately IMO. It will require changes to how we generate spec files. We could do something like using \x00 as the value in the case where a key requested to be included was not supported.

@vbatts
Copy link
Owner

vbatts commented Nov 10, 2016

Oh, certainly agree to bikeshed it separately, just acknowledging it is an
issue.

On Wed, Nov 9, 2016, 21:13 Aleksa Sarai notifications@github.com wrote:

@vbatts https://github.com/vbatts Fixing the supported / unsupported
issue should be solved separately IMO. It will require changes to how we
generate spec files. We could do something like using \x00 as the value
in the case where a key requested to be included was not supported.


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
#48 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAEF6ZmHSuBbaazhvHNqrTuc33ZAhXyJks5q8n3CgaJpZM4JWH66
.

@cyphar
Copy link
Contributor Author

cyphar commented Nov 10, 2016

@vbatts I've opened #83 to track that issue. The tests now pass on this PR.

@vbatts
Copy link
Owner

vbatts commented Nov 11, 2016

LGTM

@vbatts vbatts merged commit 690c85d into vbatts:master Nov 11, 2016
@vbatts
Copy link
Owner

vbatts commented Nov 11, 2016

Thanks @cyphar !

@cyphar cyphar deleted the core-manifest-diff branch November 11, 2016 17:07
@cyphar
Copy link
Contributor Author

cyphar commented Nov 11, 2016

I'll get to work on #83 soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants