ipynbdiff 0.3.5 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.VERSION.TMPL +5 -0
- data/.gitlab-ci.yml +39 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +3 -1
- data/README.md +6 -6
- data/ipynbdiff.gemspec +5 -3
- data/lib/ipynbdiff.rb +7 -7
- data/lib/output_transformer.rb +65 -0
- data/lib/transformer.rb +10 -36
- data/lib/version.rb +5 -0
- metadata +18 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a0b43a4e07caec84f0a356fddf739dcbfd8a851031414a2d3dd8de52d399ba7
|
4
|
+
data.tar.gz: efa08ed43c9afcbbac0d895d2bc7306601581609cbbf51398d1a8f0b7e7d5171
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df6258024f5bad0cd1a74be669d9156910ddc08cd626a9785664367fa599ef2f53da8e71276d5126a0858c5446efd0e33c6ba84c192b8c5b628f40f6f101c5ab
|
7
|
+
data.tar.gz: c64d0ba535a8b5b3d20df51b7937f514ef188eb7a93f2204b27ad2fd1cbdc13401fe2564987fc559e26f66bd5d55044c7fc1b57dc1958f0fccf624f94c9ab1af
|
data/.VERSION.TMPL
ADDED
data/.gitlab-ci.yml
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
image: ruby:2.7
|
2
|
+
|
3
|
+
stages:
|
4
|
+
- test
|
5
|
+
- build
|
6
|
+
- rubygems
|
7
|
+
|
8
|
+
specs:
|
9
|
+
stage: test
|
10
|
+
script:
|
11
|
+
- bundle install
|
12
|
+
- bundle exec rspec
|
13
|
+
|
14
|
+
build-gem:
|
15
|
+
stage: build
|
16
|
+
script:
|
17
|
+
- bundle install
|
18
|
+
- cat .VERSION.TMPL | sed s/GEM_VERSION/$CI_COMMIT_REF_NAME/ > lib/version.rb
|
19
|
+
- gem build ipynbdiff.gemspec
|
20
|
+
artifacts:
|
21
|
+
paths:
|
22
|
+
- ipynbdiff-$CI_COMMIT_REF_NAME.gem
|
23
|
+
needs:
|
24
|
+
- specs
|
25
|
+
|
26
|
+
deploy-gem:
|
27
|
+
stage: rubygems
|
28
|
+
script:
|
29
|
+
- bundle install
|
30
|
+
- gem push ipynbdiff-$CI_COMMIT_TAG.gem
|
31
|
+
only:
|
32
|
+
- master
|
33
|
+
- tags
|
34
|
+
needs:
|
35
|
+
- build-gem
|
36
|
+
when: manual
|
37
|
+
|
38
|
+
|
39
|
+
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
GEM
|
2
|
+
remote: https://rubygems.org/
|
2
3
|
specs:
|
3
4
|
diff-lcs (1.4.4)
|
4
5
|
diffy (3.3.0)
|
@@ -18,6 +19,7 @@ GEM
|
|
18
19
|
rspec-support (3.10.2)
|
19
20
|
|
20
21
|
PLATFORMS
|
22
|
+
ruby
|
21
23
|
x86_64-darwin-20
|
22
24
|
|
23
25
|
DEPENDENCIES
|
@@ -26,4 +28,4 @@ DEPENDENCIES
|
|
26
28
|
rspec (= 3.10.0)
|
27
29
|
|
28
30
|
BUNDLED WITH
|
29
|
-
2.2.
|
31
|
+
2.2.29
|
data/README.md
CHANGED
@@ -28,16 +28,16 @@ Options:
|
|
28
28
|
|
29
29
|
```ruby
|
30
30
|
@default_transform_options = {
|
31
|
-
preprocess_input:
|
31
|
+
preprocess_input: true, # Whether the input should be transformed
|
32
32
|
write_output_to: nil, # Pass a path to save the output to a file
|
33
33
|
format: :text, # These are the formats Diffy accepts https://github.com/samg/diffy
|
34
|
-
sources_are_files:
|
35
|
-
raise_if_invalid_notebook:
|
34
|
+
sources_are_files: false, # Weather to use the from/to as string or path to a file
|
35
|
+
raise_if_invalid_notebook: false, # Raises an error if the notebooks are invalid, otherwise returns nil
|
36
36
|
transform_options: @default_transform_options, # See below for transform options
|
37
37
|
diff_opts: {
|
38
|
-
include_diff_info:
|
38
|
+
include_diff_info: false # These are passed to Diffy https://github.com/samg/diffy
|
39
39
|
}
|
40
|
-
}
|
40
|
+
}
|
41
41
|
```
|
42
42
|
|
43
43
|
### Transforming the notebooks
|
@@ -52,7 +52,7 @@ Options:
|
|
52
52
|
|
53
53
|
```ruby
|
54
54
|
@default_transform_options = {
|
55
|
-
include_metadata:
|
55
|
+
include_metadata: false, # Whether to include or not the notebook metadata (kernel, language, etc)
|
56
56
|
cell_decorator: :html # :html is useful to add styling with css, :percent is better for text format
|
57
57
|
}
|
58
58
|
```
|
data/ipynbdiff.gemspec
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "lib/version"
|
4
|
+
|
3
5
|
Gem::Specification.new do |s|
|
4
6
|
s.name = 'ipynbdiff'
|
5
|
-
s.version =
|
7
|
+
s.version = IpynbDiff::VERSION
|
6
8
|
s.summary = 'Human Readable diffs for Jupyter Notebooks'
|
7
9
|
s.description = 'Better diff for Jupyter Notebooks by first preprocessing them and removing clutter'
|
8
10
|
s.authors = ['Eduardo Bonet']
|
@@ -18,8 +20,8 @@ Gem::Specification.new do |s|
|
|
18
20
|
|
19
21
|
s.require_paths = ['lib']
|
20
22
|
|
21
|
-
s.add_runtime_dependency 'diffy', '3.3
|
22
|
-
s.add_runtime_dependency 'json', '2.5.1'
|
23
|
+
s.add_runtime_dependency 'diffy', '~> 3.3'
|
24
|
+
s.add_runtime_dependency 'json', '~> 2.5', '>= 2.5.1'
|
23
25
|
|
24
26
|
s.add_development_dependency 'bundler', '~> 2.2'
|
25
27
|
s.add_development_dependency 'guard-rspec'
|
data/lib/ipynbdiff.rb
CHANGED
@@ -6,19 +6,19 @@ module IpynbDiff
|
|
6
6
|
require 'diffy'
|
7
7
|
|
8
8
|
@default_transform_options = {
|
9
|
-
include_metadata:
|
9
|
+
include_metadata: false,
|
10
10
|
cell_decorator: :html
|
11
11
|
}
|
12
12
|
|
13
13
|
@default_diff_options = {
|
14
|
-
preprocess_input:
|
14
|
+
preprocess_input: true,
|
15
15
|
write_output_to: nil,
|
16
16
|
format: :text,
|
17
|
-
sources_are_files:
|
18
|
-
raise_if_invalid_notebook:
|
17
|
+
sources_are_files: false,
|
18
|
+
raise_if_invalid_notebook: false,
|
19
19
|
transform_options: @default_transform_options,
|
20
20
|
diff_opts: {
|
21
|
-
include_diff_info:
|
21
|
+
include_diff_info: false
|
22
22
|
}
|
23
23
|
}.freeze
|
24
24
|
|
@@ -27,7 +27,7 @@ module IpynbDiff
|
|
27
27
|
|
28
28
|
prep = to_prepare
|
29
29
|
prep = File.read(prep) if options[:sources_are_files]
|
30
|
-
prep = transform(prep, raise_errors:
|
30
|
+
prep = transform(prep, raise_errors: true, options: options[:transform_options]) if options[:preprocess_input]
|
31
31
|
prep
|
32
32
|
end
|
33
33
|
|
@@ -48,7 +48,7 @@ module IpynbDiff
|
|
48
48
|
raise if options[:raise_if_invalid_notebook]
|
49
49
|
end
|
50
50
|
|
51
|
-
def self.transform(notebook, raise_errors:
|
51
|
+
def self.transform(notebook, raise_errors: false, options: @default_transform_options)
|
52
52
|
options = @default_transform_options.merge(options)
|
53
53
|
|
54
54
|
Transformer.new(**options).transform(notebook)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IpynbDiff
|
4
|
+
|
5
|
+
# Transforms Jupyter output data into markdown
|
6
|
+
class OutputTransformer
|
7
|
+
|
8
|
+
ORDERED_KEYS = {
|
9
|
+
'execute_result' => %w[image/png image/svg+xml image/jpeg text/markdown text/latex text/plain],
|
10
|
+
'display_data' => %w[image/png image/svg+xml image/jpeg text/markdown text/latex]
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
def transform(output)
|
14
|
+
case (output_type = output['output_type'])
|
15
|
+
when 'error'
|
16
|
+
transform_error(output['traceback'])
|
17
|
+
when 'execute_result', 'display_data'
|
18
|
+
transform_non_error(ORDERED_KEYS[output_type], output['data'])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def transform_error(traceback)
|
23
|
+
traceback.map do |t|
|
24
|
+
t.split("\n").map do |line|
|
25
|
+
line.gsub(/\[[0-9][0-9;]*m/, '').sub("\u001B", ' ').gsub(/\u001B/, '').rstrip << "\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def transform_non_error(accepted_keys, elements)
|
31
|
+
accepted_keys.map do |key|
|
32
|
+
transform_element(key, elements[key]) if elements.key?(key)
|
33
|
+
end.flatten
|
34
|
+
end
|
35
|
+
|
36
|
+
def transform_element(output_type, output_element)
|
37
|
+
case output_type
|
38
|
+
when 'image/png', 'image/jpeg'
|
39
|
+
transform_image(output_type, output_element)
|
40
|
+
when 'image/svg+xml'
|
41
|
+
transform_svg(output_element)
|
42
|
+
when 'text/markdown', 'text/latex', 'text/plain'
|
43
|
+
transform_text(output_element)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def transform_image(image_type, image_content)
|
48
|
+
[" })", "\n"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def transform_svg(image_content)
|
52
|
+
lines = image_content.is_a?(Array) ? image_content : [image_content]
|
53
|
+
|
54
|
+
single_line = lines.map(&:strip).join('').gsub(/\s+/, ' ')
|
55
|
+
|
56
|
+
[" ", "\n"]
|
57
|
+
end
|
58
|
+
|
59
|
+
def transform_text(text_content)
|
60
|
+
lines = text_content.is_a?(Array) ? text_content : [text_content]
|
61
|
+
|
62
|
+
lines.map { |line| " #{line}" }.append("\n")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/transformer.rb
CHANGED
@@ -8,19 +8,22 @@ module IpynbDiff
|
|
8
8
|
class Transformer
|
9
9
|
require 'json'
|
10
10
|
require 'yaml'
|
11
|
+
require 'output_transformer'
|
11
12
|
|
12
13
|
@cell_decorator = :html
|
13
|
-
@include_metadata =
|
14
|
+
@include_metadata = true
|
14
15
|
|
15
|
-
|
16
|
+
|
17
|
+
def initialize(include_metadata: true, cell_decorator: :html)
|
16
18
|
@include_metadata = include_metadata
|
17
19
|
@cell_decorator = cell_decorator
|
20
|
+
@output_transformer = OutputTransformer.new
|
18
21
|
end
|
19
22
|
|
20
23
|
def validate_notebook(notebook)
|
21
24
|
notebook_json = JSON.parse(notebook)
|
22
25
|
|
23
|
-
return notebook_json if notebook_json.key?('cells')
|
26
|
+
return notebook_json if notebook_json.key?('cells')
|
24
27
|
|
25
28
|
raise InvalidNotebookError
|
26
29
|
rescue JSON::ParserError
|
@@ -66,51 +69,22 @@ module IpynbDiff
|
|
66
69
|
|
67
70
|
def transform_code_cell(cell, notebook)
|
68
71
|
[
|
69
|
-
%(``` #{notebook
|
72
|
+
%(``` #{notebook.dig('metadata', 'kernelspec', 'language') || ''}\n),
|
70
73
|
*cell['source'],
|
71
74
|
"\n```\n",
|
72
75
|
*cell['outputs'].map { |output| transform_output(output) }
|
73
76
|
]
|
74
77
|
end
|
75
78
|
|
76
|
-
def format_traceback(traceback)
|
77
|
-
traceback.map do |t|
|
78
|
-
t.split("\n").map do |line|
|
79
|
-
line.gsub(/\[[0-9][0-9;]*m/, '').sub("\u001B", ' ').gsub(/\u001B/, '').rstrip << "\n"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def transform_execute_result(output)
|
85
|
-
output['data']['text/plain'].map { |line| " #{line}" }.append("\n")
|
86
|
-
end
|
87
|
-
|
88
|
-
def transform_image_result(output)
|
89
|
-
if output['data'].key?('image/png')
|
90
|
-
["})", "\n"]
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def transform_error_result(output)
|
95
|
-
format_traceback(output['traceback'])
|
96
|
-
end
|
97
|
-
|
98
79
|
def transform_output(output)
|
99
|
-
transformed =
|
100
|
-
case output['output_type']
|
101
|
-
when 'execute_result'
|
102
|
-
transform_execute_result(output)
|
103
|
-
when 'display_data'
|
104
|
-
transform_image_result(output)
|
105
|
-
when 'error'
|
106
|
-
transform_error_result(output)
|
107
|
-
end
|
80
|
+
transformed = @output_transformer.transform(output)
|
108
81
|
|
109
82
|
decorate_output(transformed, output).join('') if transformed
|
110
83
|
end
|
111
84
|
|
112
85
|
def transform_text_cell(cell)
|
113
|
-
cell['source']
|
86
|
+
source = cell['source']
|
87
|
+
(source.is_a?(Array) ? source : [source]).append("\n")
|
114
88
|
end
|
115
89
|
|
116
90
|
def transform_metadata(notebook_json)
|
data/lib/version.rb
ADDED
metadata
CHANGED
@@ -1,41 +1,47 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ipynbdiff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eduardo Bonet
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: diffy
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.3
|
19
|
+
version: '3.3'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.3
|
26
|
+
version: '3.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: json
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.5'
|
34
|
+
- - ">="
|
32
35
|
- !ruby/object:Gem::Version
|
33
36
|
version: 2.5.1
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
|
-
- -
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.5'
|
44
|
+
- - ">="
|
39
45
|
- !ruby/object:Gem::Version
|
40
46
|
version: 2.5.1
|
41
47
|
- !ruby/object:Gem::Dependency
|
@@ -115,13 +121,17 @@ executables: []
|
|
115
121
|
extensions: []
|
116
122
|
extra_rdoc_files: []
|
117
123
|
files:
|
124
|
+
- ".VERSION.TMPL"
|
118
125
|
- ".gitignore"
|
126
|
+
- ".gitlab-ci.yml"
|
119
127
|
- Gemfile
|
120
128
|
- Gemfile.lock
|
121
129
|
- README.md
|
122
130
|
- ipynbdiff.gemspec
|
123
131
|
- lib/ipynbdiff.rb
|
132
|
+
- lib/output_transformer.rb
|
124
133
|
- lib/transformer.rb
|
134
|
+
- lib/version.rb
|
125
135
|
homepage: https://gitlab.com/gitlab-org/incubation-engineering/mlops/rb-ipynbdiff
|
126
136
|
licenses:
|
127
137
|
- MIT
|