xcop 0.10.3 → 0.11.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d60b5b604d878305feaee1897024cdb25f422e817e3c8fdd6ad03763d055e9fe
4
- data.tar.gz: 5d778bf7c386b682cb8f0d1df07c927e0c978c2a3c6c80d85b6cbfe5511f5052
3
+ metadata.gz: 682e51f3798d3495937a198b772be9a23be624990096e179575318285873761c
4
+ data.tar.gz: 9f4002c4337e4a2f90bea041a43c6eed471049694a78220855b02b31a1bd672c
5
5
  SHA512:
6
- metadata.gz: b2ab0ed8903b36aa5dd062e6056209166425c39801ef03dc61650e721af42715b39aaa11f325ea8f8f860aad3acaf826ae469591154337a8aab73dd98e564b64
7
- data.tar.gz: e8127c93fe4d435a775394a77bd737d3203243fdbb957207c32257f7905060a1eb264ce39484f1a1e518ce85528990bc9d30bcb7f239df2d33b7b08a235fcbbd
6
+ metadata.gz: 13b1cb456fb7d0aabd5e5d1222af05ff1ac4c50c080e31c63a7085c48a4ad248c421fe2736dee02e2bcb574e74dc4634a77e30637ac37a7f441212a4ed4d8b20
7
+ data.tar.gz: 7a8d17f560e2b635eab9b63319d4c7bdcd34cd658ae22a45c102269575486ca4704952f17ba7320cd5fbc170cd322a2e06e0e3157983bf3c70314de88bc7a5b0
data/Gemfile.lock CHANGED
@@ -45,7 +45,7 @@ GEM
45
45
  docile (1.4.1)
46
46
  drb (2.2.3)
47
47
  ellipsized (0.3.0)
48
- erb (6.0.5)
48
+ erb (6.0.6)
49
49
  ffi (1.17.4-aarch64-linux-gnu)
50
50
  ffi (1.17.4-aarch64-linux-musl)
51
51
  ffi (1.17.4-arm-linux-gnu)
@@ -55,7 +55,7 @@ GEM
55
55
  ffi (1.17.4-x86_64-darwin)
56
56
  ffi (1.17.4-x86_64-linux-gnu)
57
57
  ffi (1.17.4-x86_64-linux-musl)
58
- json (2.20.0)
58
+ json (2.21.1)
59
59
  language_server-protocol (3.17.0.6)
60
60
  lint_roller (1.1.0)
61
61
  logger (1.7.0)
@@ -91,8 +91,8 @@ GEM
91
91
  racc (~> 1.4)
92
92
  nokogiri (1.19.3-x86_64-linux-musl)
93
93
  racc (~> 1.4)
94
- parallel (1.28.0)
95
- parser (3.3.11.1)
94
+ parallel (2.1.0)
95
+ parser (3.3.12.0)
96
96
  ast (~> 2.4.1)
97
97
  racc
98
98
  prism (1.9.0)
@@ -112,13 +112,13 @@ GEM
112
112
  rubocop-ast (>= 1.49.0, < 2.0)
113
113
  ruby-progressbar (~> 1.7)
114
114
  unicode-display_width (>= 2.4.0, < 4.0)
115
- rubocop-ast (1.49.1)
115
+ rubocop-ast (1.50.0)
116
116
  parser (>= 3.3.7.2)
117
117
  prism (~> 1.7)
118
118
  rubocop-elegant (0.7.1)
119
119
  lint_roller (~> 1.1)
120
120
  rubocop (~> 1.75)
121
- rubocop-minitest (0.39.1)
121
+ rubocop-minitest (0.40.0)
122
122
  lint_roller (~> 1.1)
123
123
  rubocop (>= 1.75.0, < 2.0)
124
124
  rubocop-ast (>= 1.38.0, < 2.0)
@@ -151,7 +151,7 @@ GEM
151
151
  unicode-emoji (~> 4.1)
152
152
  unicode-emoji (4.2.0)
153
153
  win32ole (1.9.3)
154
- yard (0.9.44)
154
+ yard (0.9.45)
155
155
 
156
156
  PLATFORMS
157
157
  aarch64-linux-gnu
data/README.md CHANGED
@@ -55,6 +55,14 @@ xcop .
55
55
  xcop --fix src/resources
56
56
  ```
57
57
 
58
+ When you run `xcop` without any files, directories, or `--include`
59
+ globs, it checks the current directory, exactly as if you called
60
+ `xcop .`:
61
+
62
+ ```bash
63
+ xcop
64
+ ```
65
+
58
66
  ## Defaults
59
67
 
60
68
  You can put command line options into a `.xcop` file in the directory
data/REUSE.toml CHANGED
@@ -8,6 +8,7 @@ path = [
8
8
  ".gitattributes",
9
9
  ".gitignore",
10
10
  ".pdd",
11
+ "fixtures/**",
11
12
  "**.json",
12
13
  "**.md",
13
14
  "**.png",
data/bin/xcop CHANGED
@@ -56,7 +56,9 @@ if opts[:include]
56
56
  end
57
57
  end
58
58
 
59
- files += opts.arguments.map { |f| File.expand_path(f) }
59
+ targets = opts.arguments
60
+ targets = ['.'] if targets.empty? && Array(opts[:include]).empty?
61
+ files += targets.map { |f| File.expand_path(f) }
60
62
 
61
63
  if opts[:exclude]
62
64
  opts[:exclude].each do |glob|
@@ -66,7 +68,11 @@ end
66
68
 
67
69
  if opts.fix?
68
70
  Xcop::CLI.new(files).fix do |f, status|
69
- puts "#{f} #{status}" unless opts.quiet?
71
+ if status == :malformed
72
+ puts "#{f} is not a well-formed XML, cannot fix it"
73
+ elsif !opts.quiet?
74
+ puts "#{f} #{status}"
75
+ end
70
76
  end
71
77
  else
72
78
  begin
data/features/cli.feature CHANGED
@@ -44,6 +44,34 @@ Feature: Command Line Processing
44
44
  Then I run bin/xcop with "broken.xml"
45
45
  Then Exit code is zero
46
46
 
47
+ Scenario: Refusing to fix a non-well-formed XML file
48
+ Given I have a "garbage.xml" file with content:
49
+ """
50
+ this is not XML
51
+ """
52
+ When I run bin/xcop with "--fix garbage.xml"
53
+ Then Stdout contains "is not a well-formed XML"
54
+ And Exit code is zero
55
+ And The file "garbage.xml" contains "this is not XML"
56
+
57
+ Scenario: Validating all files in the current directory by default
58
+ Given I have a "auto.xml" file with content:
59
+ """
60
+ <?xml version="1.0"?>
61
+ <hello>Hello, world!</hello>
62
+
63
+ """
64
+ And I have a "nested/deep.xsl" file with content:
65
+ """
66
+ <?xml version="1.0"?>
67
+ <hello>Hello, world!</hello>
68
+
69
+ """
70
+ When I run bin/xcop with ""
71
+ Then Stdout contains "auto.xml looks good"
72
+ And Stdout contains "deep.xsl looks good"
73
+ And Exit code is zero
74
+
47
75
  Scenario: Validating a directory of XML files recursively
48
76
  Given I have a "pkg/top.xml" file with content:
49
77
  """
@@ -38,6 +38,11 @@ Then(/^Stdout contains "([^"]*)"$/) do |txt|
38
38
  raise(StandardError, "STDOUT doesn't contain '#{txt}':\n#{@stdout}") unless @stdout.include?(txt)
39
39
  end
40
40
 
41
+ Then(/^The file "([^"]*)" contains "([^"]*)"$/) do |file, txt|
42
+ body = File.read(file)
43
+ raise(StandardError, "File '#{file}' doesn't contain '#{txt}':\n#{body}") unless body.include?(txt)
44
+ end
45
+
41
46
  Then(/^Stdout is empty$/) do
42
47
  raise(StandardError, "STDOUT is not empty:\n#{@stdout}") unless @stdout == ''
43
48
  end
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0"?>
2
+ <config debug="true" level="5">
3
+ <item name="alpha" value="1"/>
4
+ <item name="beta" value="2"/>
5
+ </config>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0"?>
2
+ <script><![CDATA[if (a < b) { return; }]]></script>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0"?>
2
+ <a>
3
+ <!--
4
+ line1
5
+ line2
6
+ -->
7
+ </a>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0"?>
2
+ <a>
3
+ <!-- text -->
4
+ </a>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0"?>
2
+ <a>
3
+ <b>
4
+ <c>
5
+ <d>deep</d>
6
+ </c>
7
+ </b>
8
+ </a>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0"?>
2
+ <gallery>
3
+ <image src="a.png"/>
4
+ <image src="b.png"/>
5
+ <break/>
6
+ </gallery>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0"?>
2
+ <text>a &lt; b &amp; c &gt; d</text>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0"?>
2
+ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
+ <modelVersion>4.0.0</modelVersion>
4
+ </project>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0"?>
2
+ <p>Hello <b>bold</b> world</p>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0"?>
2
+ <root xmlns:x="urn:x">
3
+ <x:child>value</x:child>
4
+ </root>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0"?>
2
+ <root>
3
+ <parent>
4
+ <child>text</child>
5
+ </parent>
6
+ </root>
@@ -0,0 +1 @@
1
+ hello world
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0"?>
2
+ <hello>Hello, world!</hello>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0"?>
2
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
3
+ <xsl:variable name="n" as="xs:integer" select="1"/>
4
+ </xsl:stylesheet>
data/lib/xcop/document.rb CHANGED
@@ -24,9 +24,11 @@ class Xcop::Document
24
24
  end
25
25
 
26
26
  # Fixes the document, returning +:fixed+ when the file content
27
- # changed on disk and +:untouched+ when the file was already
28
- # canonical.
27
+ # changed on disk, +:untouched+ when the file was already canonical,
28
+ # and +:malformed+ when the file is not well-formed XML and thus
29
+ # left on disk exactly as it was.
29
30
  def fix
31
+ return :malformed unless wellformed?
30
32
  canonical = ideal
31
33
  return :untouched if canonical == File.read(@path)
32
34
  File.write(@path, canonical)
@@ -50,6 +52,14 @@ class Xcop::Document
50
52
 
51
53
  private
52
54
 
55
+ # Is the document well-formed XML? Nokogiri parses in recover mode
56
+ # and never raises, so a broken file yields a rootless document that
57
+ # +to_xml+ renders as an empty declaration; a fatal parse error is
58
+ # the signal that the file cannot be safely reformatted. See #173.
59
+ def wellformed?
60
+ Nokogiri::XML(File.read(@path)).errors.none?(&:fatal?)
61
+ end
62
+
53
63
  # The canonical, well-formatted version of the document.
54
64
  def ideal
55
65
  xml = Nokogiri::XML(File.read(@path), &:noblanks)
data/lib/xcop/version.rb CHANGED
@@ -6,5 +6,5 @@
6
6
  # Copyright:: Copyright (c) 2017-2026 Yegor Bugayenko
7
7
  # License:: MIT
8
8
  module Xcop
9
- VERSION = '0.10.3'.freeze
9
+ VERSION = '0.11.1'.freeze
10
10
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xcop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.3
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-07-17 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: differ
@@ -72,8 +71,8 @@ executables:
72
71
  - xcop
73
72
  extensions: []
74
73
  extra_rdoc_files:
75
- - README.md
76
74
  - LICENSE.txt
75
+ - README.md
77
76
  files:
78
77
  - Gemfile
79
78
  - Gemfile.lock
@@ -90,6 +89,20 @@ files:
90
89
  - features/rake.feature
91
90
  - features/step_definitions/steps.rb
92
91
  - features/support/env.rb
92
+ - fixtures/idempotent/attributes.xml
93
+ - fixtures/idempotent/cdata.xml
94
+ - fixtures/idempotent/comment-multi-line.xml
95
+ - fixtures/idempotent/comment-single-line.xml
96
+ - fixtures/idempotent/deep-nesting.xml
97
+ - fixtures/idempotent/empty-elements.xml
98
+ - fixtures/idempotent/entities.xml
99
+ - fixtures/idempotent/maven-pom.xml
100
+ - fixtures/idempotent/mixed-content.xml
101
+ - fixtures/idempotent/namespace-used.xml
102
+ - fixtures/idempotent/nested.xml
103
+ - fixtures/idempotent/non-xml.txt
104
+ - fixtures/idempotent/simple.xml
105
+ - fixtures/idempotent/xslt-xpath-namespace.xml
93
106
  - lib/xcop/cli.rb
94
107
  - lib/xcop/document.rb
95
108
  - lib/xcop/rake_task.rb
@@ -101,7 +114,6 @@ licenses:
101
114
  - MIT
102
115
  metadata:
103
116
  rubygems_mfa_required: 'true'
104
- post_install_message:
105
117
  rdoc_options:
106
118
  - "--charset=UTF-8"
107
119
  require_paths:
@@ -117,8 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
129
  - !ruby/object:Gem::Version
118
130
  version: '0'
119
131
  requirements: []
120
- rubygems_version: 3.4.10
121
- signing_key:
132
+ rubygems_version: 3.6.9
122
133
  specification_version: 4
123
134
  summary: XML Formatting Static Validator
124
135
  test_files: []