braid 1.1.3 → 1.1.4

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
- SHA1:
3
- metadata.gz: 07fd598555c607d5617f6cd2707362ef6ea9ffce
4
- data.tar.gz: e7dcb8b70240e76d8f0f05b46956838d29f71e18
2
+ SHA256:
3
+ metadata.gz: adb13d280f397cd42919d311d849056087324f1ffec5c57f7b126b82013048f9
4
+ data.tar.gz: cfb5432addac3a9167f3e8f61bed948cc2651af2a84d32d3984194759fcc1ee7
5
5
  SHA512:
6
- metadata.gz: c9ce4a5239bf290606de2a828586d0f876cd8d3dfac0b465293eb8f0368326571ea7523244d9e70ae613337b9246f7dc46f99d3becdb458892d788a27d835f57
7
- data.tar.gz: 3bd9e43d3a3bb6f838d4c9f02fb4ece0b10ca28e5120366933dee559cbbd07f9aa8771db4ea7b2d06a31ed3b43eb410f80979c72c5e032fbdbc6fcc5b2f1d1ff
6
+ metadata.gz: a4e725e85c4b487409575d530aa012c4cd5a3e1b90b71e14e09fd100bbdd7ee5fd3c11afde95548436df35a0286c105121953578af5cca2470c9674b68d60d59
7
+ data.tar.gz: 73ac1fc248da08c36d9b3fe5e77a12bdbda4f858efe48951a697ec352ea9e29422e3f4931001b6c2f729a9a91fb4679196cc1293eb5f01ab96bb91999412cc3f
data/README.md CHANGED
@@ -144,6 +144,17 @@ Go back to tracking a particular branch.
144
144
 
145
145
  braid diff vendor/rails
146
146
 
147
+ ## Supported environments
148
+
149
+ As of this writing (2022-01-20), we try to keep Braid working at least on Linux,
150
+ OSX and Windows with recent versions of its dependencies (Git, Ruby, gems, etc.).
151
+ Your mileage on other operating systems or with other versions of dependencies
152
+ may vary. We don't have a procedure in place to systematically test Braid in
153
+ multiple environments; typically, Braid developers just run the test suite on
154
+ their own systems with whatever is installed. So breakages may sometimes occur.
155
+ If you run into an environment-related problem, please report it and we'll fix
156
+ it if feasible. Contributions to improve testing of Braid would be welcome.
157
+
147
158
  ## Braid version compatibility
148
159
 
149
160
  Since Braid has been regularly changing the configuration format and adding new
@@ -208,6 +219,7 @@ re-add and maintain the Subversion support, please contact the authors.
208
219
  * Cristi Balan
209
220
  * Norbert Crombach
210
221
  * Peter Donald
222
+ * Matt McCutchen
211
223
 
212
224
  ## Contributors (alphabetically)
213
225
 
@@ -216,7 +228,6 @@ re-add and maintain the Subversion support, please contact the authors.
216
228
  * Christoph Sturm
217
229
  * Dennis Muhlestein
218
230
  * Ferdinand Svehla
219
- * Matt McCutchen
220
231
  * Michael Klishin
221
232
  * Roman Heinrich
222
233
  * Travis Tilley
data/braid.gemspec CHANGED
@@ -7,8 +7,8 @@ Gem::Specification.new do |s|
7
7
  s.version = Braid::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
9
 
10
- s.authors = ['Cristi Balan', 'Norbert Crombach', 'Peter Donald']
11
- s.email = %q{evil@che.lu norbert.crombach@primetheory.org peter@realityforge.org}
10
+ s.authors = ['Cristi Balan', 'Norbert Crombach', 'Peter Donald', 'Matt McCutchen']
11
+ s.email = %q{evil@che.lu norbert.crombach@primetheory.org peter@realityforge.org matt@mattmccutchen.net}
12
12
 
13
13
  s.homepage = %q{https://github.com/cristibalan/braid}
14
14
  s.summary = %q{A simple tool for tracking vendor branches in git.}
@@ -19,10 +19,8 @@ Gem::Specification.new do |s|
19
19
  s.files = `git ls-files`.split("\n")
20
20
  s.test_files = `git ls-files -- {spec}/*`.split("\n")
21
21
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
22
- s.default_executable = %q{braid}
23
22
  s.require_paths = %w(lib)
24
23
 
25
- s.has_rdoc = false
26
24
  s.rdoc_options = %w(--line-numbers --inline-source --title braid --main)
27
25
 
28
26
  s.required_ruby_version = '>= 2.2.0'
@@ -0,0 +1,91 @@
1
+ {
2
+ "title": "schema for .braids.json configuration file",
3
+ "type": "object",
4
+ "properties": {
5
+ "config_version": {
6
+ "type": "number",
7
+ "enum": [
8
+ 1
9
+ ],
10
+ "description": "configuration format version (see https://cristibalan.github.io/braid/#braid-version-compatibility)",
11
+ "$comment": "So far, only version 1 is defined. (Version \"0\" is a mess and not worth writing a schema for.) When we have more than one defined version, we can look into the best way to make the rest of the schema dependent on the version."
12
+ },
13
+ "mirrors": {
14
+ "type": "object",
15
+ "description": "container for all added vendor repository mirrors",
16
+ "patternProperties": {
17
+ ".*": {
18
+ "allOf": [
19
+ {
20
+ "type": "object",
21
+ "description": "local path where the vendor content is placed, relative to the .braids.json file",
22
+ "properties": {
23
+ "url": {
24
+ "type": "string",
25
+ "description": "remote URL of the vendor repository"
26
+ },
27
+ "path": {
28
+ "type": "string",
29
+ "description": "path to a subdirectory or single file in the vendor tree (instead of the whole tree) to place at the specified local path"
30
+ },
31
+ "branch": {
32
+ "type": "string",
33
+ "description": "branch name of the vendor repository to track"
34
+ },
35
+ "tag": {
36
+ "type": "string",
37
+ "description": "tag name of the vendor repository to track"
38
+ },
39
+ "revision": {
40
+ "type": "string",
41
+ "description": "commit ID of the vendor repository currently used by the mirror"
42
+ }
43
+ },
44
+ "required": [
45
+ "url",
46
+ "revision"
47
+ ],
48
+ "additionalProperties": false
49
+ },
50
+ {
51
+ "$comment": "At most one of \"branch\" and \"tag\". Technique from https://stackoverflow.com/a/33358676 .",
52
+ "oneOf": [
53
+ {
54
+ "not": {
55
+ "anyOf": [
56
+ {
57
+ "required": [
58
+ "branch"
59
+ ]
60
+ },
61
+ {
62
+ "required": [
63
+ "tag"
64
+ ]
65
+ }
66
+ ]
67
+ }
68
+ },
69
+ {
70
+ "required": [
71
+ "branch"
72
+ ]
73
+ },
74
+ {
75
+ "required": [
76
+ "tag"
77
+ ]
78
+ }
79
+ ]
80
+ }
81
+ ]
82
+ }
83
+ }
84
+ }
85
+ },
86
+ "required": [
87
+ "config_version",
88
+ "mirrors"
89
+ ],
90
+ "additionalProperties": false
91
+ }
@@ -68,9 +68,45 @@ module Braid
68
68
  f.puts(odb_paths)
69
69
  }
70
70
  git.fetch(remote_url, mirror.remote_ref)
71
- git.checkout(base_revision)
72
- git.rm_r(mirror.remote_path || '.')
73
- git.add_item_to_index(local_mirror_item, mirror.remote_path || '', true)
71
+ new_tree = git.make_tree_with_item(base_revision,
72
+ mirror.remote_path || '', local_mirror_item)
73
+ if git.require_version('2.27')
74
+ # Skip checking files out into the working tree by turning on sparse
75
+ # checkout with an empty list of include patterns (which is an error
76
+ # before Git 2.27). This improves performance and avoids problems
77
+ # with filters that are enabled globally but aren't set up properly
78
+ # in the temporary repository (e.g., potentially, Git LFS).
79
+ #
80
+ # It's not ideal to rely on an edge case of an advanced Git feature,
81
+ # but the alternatives aren't great either. We want to run `git
82
+ # commit` interactively for the user; we can't just call
83
+ # git.make_tree_with_item + `git commit-tree`. And if we populate
84
+ # the index and not the working tree without using sparse checkout,
85
+ # then `git commit` will show all files as deleted under "Changes
86
+ # not staged for commit", which is distracting.
87
+ #
88
+ # Manipulating index entries that are excluded by sparse checkout is
89
+ # extremely dicey: depending on the Git version, `git checkout` and
90
+ # `git rm` may leave them unchanged and not perform the operation we
91
+ # requested. So it's safest to generate the new tree before we
92
+ # enable sparse checkout. After enabling sparse checkout (if our
93
+ # copy of Git indeed supports it), `git read-tree -u` is one
94
+ # operation that should be safe: the index update is unconditional,
95
+ # and the working tree update honors sparse checkout.
96
+ #
97
+ # TODO: Audit Braid for operations that could be broken by use of
98
+ # sparse checkout by the user (rather than internal to `braid
99
+ # push`)?
100
+ git.config(['--local', 'core.sparsecheckout', 'true'])
101
+ File.open('.git/info/sparse-checkout', 'wb') { |f|
102
+ # Leave the file empty.
103
+ }
104
+ end
105
+ # Update HEAD the same way git.checkout(base_revision) would, but
106
+ # don't populate the index or working tree (to save us the trouble of
107
+ # emptying them again before the git.read_tree).
108
+ git.update_ref('--no-deref', 'HEAD', base_revision)
109
+ git.read_tree('-mu', new_tree)
74
110
  system('git commit -v')
75
111
  msg "Pushing changes to remote branch #{branch}."
76
112
  git.push(remote_url, "HEAD:refs/heads/#{branch}")
@@ -66,25 +66,11 @@ module Braid
66
66
  end
67
67
 
68
68
  def require_version(required)
69
- required = required.split('.')
70
- actual = version.split('.')
71
-
72
- actual.each_with_index do |actual_piece, idx|
73
- required_piece = required[idx]
74
-
75
- return true unless required_piece
76
-
77
- case (actual_piece <=> required_piece)
78
- when -1
79
- return false
80
- when 1
81
- return true
82
- when 0
83
- next
84
- end
85
- end
86
-
87
- return actual.length >= required.length
69
+ # Gem::Version is intended for Ruby gem versions, but various web sites
70
+ # suggest it as a convenient way of comparing version strings in
71
+ # general. None of the fine points of its semantics compared to those
72
+ # of Git version numbers seem likely to cause a problem for Braid.
73
+ Gem::Version.new(version) >= Gem::Version.new(required)
88
74
  end
89
75
 
90
76
  def require_version!(required)
@@ -343,7 +329,10 @@ module Braid
343
329
 
344
330
  def make_tree_with_item(main_content, item_path, item)
345
331
  with_temporary_index do
346
- if main_content
332
+ # If item_path is '', then rm_r_cached will fail. But in that case,
333
+ # we can skip loading the main content because it would be deleted
334
+ # anyway.
335
+ if main_content && item_path != ''
347
336
  read_tree_im(main_content)
348
337
  rm_r_cached(item_path)
349
338
  end
data/lib/braid/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Braid
2
- VERSION = '1.1.3'.freeze
2
+ VERSION = '1.1.4'.freeze
3
3
  end
data/lib/braid.rb CHANGED
@@ -3,7 +3,18 @@ require 'braid/version'
3
3
  module Braid
4
4
  OLD_CONFIG_FILE = '.braids'
5
5
  CONFIG_FILE = '.braids.json'
6
- REQUIRED_GIT_VERSION = '1.6'
6
+
7
+ # See the background in the "Supported environments" section of README.md.
8
+ #
9
+ # The newest Git feature that Braid is currently known to rely on is
10
+ # `receive.denyCurrentBranch = updateInstead` (in
11
+ # spec/integration/push_spec.rb), which was added in Git 2.3.0 (in 2015). It
12
+ # doesn't seem worth even a small amount of work to remove that dependency and
13
+ # support even older versions of Git. So set that as the declared requirement
14
+ # for now. In general, a reasonable approach might be to try to support the
15
+ # oldest version of Git in current "long-term support" versions of popular OS
16
+ # distributions.
17
+ REQUIRED_GIT_VERSION = '2.3.0'
7
18
 
8
19
  def self.verbose
9
20
  !!@verbose
@@ -0,0 +1 @@
1
+ *.png filter=broken
@@ -0,0 +1,219 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ {{ '/feed/atom.xml' | assign_to: 'global_feed' }}
4
+ {{ '/feed/all_comments.xml' | assign_to: 'global_comments_feed' }}
5
+ <head>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <title>
8
+ {{ site.title }}
9
+ {% if site.current_section %}
10
+ - {{ site.current_section.name }}
11
+ {% endif %}
12
+ {% if article %}
13
+ - {{ article.title }}
14
+ {% endif %}
15
+ </title>
16
+ <link rel="alternate" type="application/atom+xml" title="{{ site.title }} feed" href="{{ global_feed }}"/>
17
+ <link rel="alternate" type="application/atom+xml" title="{{ site.title }} comments feed" href="{{ global_comments_feed }}"/>
18
+ {{ 'base' | stylesheet }}
19
+ {{ 'app' | javascript }}
20
+ <!--[if IE]>
21
+ {{ 'base_ie' | stylesheet }}
22
+ <![endif]-->
23
+ </head>
24
+
25
+ <body class="fixed green">
26
+ <script type="text/javascript">loadPreferences()</script>
27
+
28
+ <div id="wrapper">
29
+
30
+ <div id="header" class="clearfix">
31
+ <div id="title" class="clearfix">
32
+ <h1><a href="/">{{ site.title }}</a></h1>
33
+ </div>
34
+ <h2>Sections</h2>
35
+ <ul id="menu">
36
+ {% for section in site.sections %}
37
+ {% if section.articles_count > 0 %}
38
+ {% if section.is_home %}
39
+ <li{% if section.current %} class="selected"{% endif %}>{{ section | link_to_section }}</li>
40
+ {% else %}
41
+ {% if section.is_paged %}
42
+ <li{% if section.current %} class="selected"{% endif %}>{{ section | link_to_section }}</li>
43
+ {% endif %}
44
+ {% endif %}
45
+ {% endif %}
46
+ {% endfor %}
47
+ </ul>
48
+ </div>
49
+
50
+ <div id="contentwrapper" class="clearfix">
51
+
52
+ <div id="content">
53
+
54
+ <div id="innerwrapper">
55
+
56
+ <div class="article">
57
+ <div class="body">
58
+ <h2>Skittlish Tips'n'Tricks</h2>
59
+ <ul>
60
+ <li>Change the classes for the body tag to set your default site style. also change these in the app.js file (line 66).</li>
61
+ <li>Remove the scripts and the #options div if you don't want the option switcher.</li>
62
+ <li>The top menu shows the home section and the sections that are not blogs.</li>
63
+ <li>Email me at <a href="mailto:evil@che.lu">evil@che.lu</a> if you have any questions.</li>
64
+ <li>Happy hacking!</li>
65
+ </ul>
66
+ </div>
67
+ </div>
68
+
69
+ {{ content_for_layout }}
70
+
71
+ </div>
72
+
73
+ </div>
74
+
75
+ <div id="sidebar">
76
+
77
+ <div class="boxy short">
78
+ <h3>boxy short</h3>
79
+
80
+ <p>You can have, boxes with a short, tall or no background shade, just change the class of the containing div.</p>
81
+
82
+ <p>Have boxes with smaller text with the class "minor". See the "Recent" boxy below.</p>
83
+
84
+ </div>
85
+
86
+ <div id="search" class="boxy short">
87
+ <h3>Search</h3>
88
+ <form method="get" action="/search">
89
+ <fieldset>
90
+ <input class="text" type="text" id="q" value="" name="q"/>
91
+ </fieldset>
92
+ </form>
93
+ </div>
94
+
95
+ <div class="boxy tall minor">
96
+ <h3>Recent</h3>
97
+
98
+ <dl>
99
+ <dt>Articles <a class="feed" href="{{ global_feed }}"><span>feed</span></a></dt>
100
+ <dd>
101
+ <ul>
102
+ {% for article in site.latest_articles %}
103
+ <li>{{ article | link_to_article }} <em>({{ article.published_at | format_date: 'stub', true }})</em></li>
104
+ {% endfor %}
105
+ </ul>
106
+ </dd>
107
+
108
+ <dt>Comments <a class="feed" href="{{ global_comments_feed }}"><span>feed</span></a></dt>
109
+ <dd>
110
+ <ul>
111
+ {% for comment in site.latest_comments %}
112
+ <li>{{ comment.author_link }} on <a href="{{ comment.url }}#comment-{{ comment.id }}">{{ comment.title }}</a></li>
113
+ {% endfor %}
114
+ </ul>
115
+ </dd>
116
+ </dl>
117
+ </div>
118
+
119
+ <div class="boxy short">
120
+ <h3>Archives</h3>
121
+ <p>This would be much nicer with jamis' month_drop thingy.</p>
122
+ {{ '' | section | months | assign_to: 'home_section' }}
123
+ <ul>
124
+ {% for month in home_section.months %}
125
+ {{ home_section | monthly_articles: month | size | assign_to: 'articles_count' }}
126
+ {% if articles_count > 0 %}
127
+ <li>{{ home_section | link_to_month: month }} ({{ articles_count }})</li>
128
+ {% endif %}
129
+ {% endfor %}
130
+ </ul>
131
+ </div>
132
+
133
+ {% if site.blog_sections.size > 1 %}
134
+ <div class="boxy short">
135
+ <h3>Categories</h3>
136
+ <p>Lists only blog type categories with at least one article.</p>
137
+ <p>This list uses an ul. You could use a dl with only dd's in it for the same effect. Wouldn't be semantic tho.</p>
138
+ <ul class="sections">
139
+ {% for section in site.blog_sections %}
140
+ {% if section.articles_count > 0 %}
141
+ {% unless section.is_home %}
142
+ <li>{{ section | link_to_section }} ({{ section.articles_count }})</li>
143
+ {% endunless %}
144
+ {% endif %}
145
+ {% endfor %}
146
+ </ul>
147
+ </div>
148
+
149
+ {% endif %}
150
+ {% unless site.tags == empty %}
151
+ <div class="boxy short">
152
+ <p>This would be nicer if we could get the number of articles for each tag.</p>
153
+ <h3>tags: </h3>
154
+ <ul>
155
+ {% for tag in site.tags %}
156
+ <li>{{ tag | link_to_tag }}</li>
157
+ {% endfor %}
158
+ </ul>
159
+ </div>
160
+
161
+ {% endunless %}
162
+ <div class="boxy tall">
163
+ <h3>boxy tall</h3>
164
+ <p>When using a tall box, make sure it's got plenty of content or that it's immediately followed by a short boxy. It might look a bit chopped off otherwise.</p>
165
+ <dl>
166
+ <dt>thing 1</dt>
167
+ <dd><a href="#">value 1</a></dd>
168
+ <dd><a href="#">value 2</a></dd>
169
+ <dd><a href="#">value 3</a></dd>
170
+ <dd><a href="#">value 4</a></dd>
171
+ <dd><a href="#">value 5</a></dd>
172
+ <dd><a href="#">value 6</a></dd>
173
+ <dd><a href="#">value 6</a></dd>
174
+
175
+ <dt>thing 1</dt>
176
+ <dd><a href="#">value 1</a></dd>
177
+ <dd><a href="#">value 2</a></dd>
178
+ <dd><a href="#">value 3</a></dd>
179
+ <dd>value 4</dd>
180
+ <dd>value 5</dd>
181
+ <dd><a href="#">value 6</a></dd>
182
+ <dd><a href="#">value 6</a></dd>
183
+
184
+ </dl>
185
+ </div>
186
+
187
+ </div>
188
+
189
+ </div>
190
+
191
+ <div id="options">
192
+ <h2>Options:</h2>
193
+ <h3>Size</h3>
194
+ <ul id="option_size">
195
+ <li id="option_size_fixed" class="fixed" ><a><span>fixed </span></a></li>
196
+ <li id="option_size_fluid" class="fluid" ><a><span>fluid </span></a></li>
197
+ </ul>
198
+ <h3>Colors</h3>
199
+ <ul id="option_color">
200
+ <li id="option_color_orange" class="orange"><a><span>orange</span></a></li>
201
+ <li id="option_color_blue" class="blue" ><a><span>blue </span></a></li>
202
+ <li id="option_color_green" class="green" ><a><span>green </span></a></li>
203
+ <li id="option_color_pink" class="pink" ><a><span>pink </span></a></li>
204
+ <li id="option_color_cyan" class="cyan" ><a><span>cyan </span></a></li>
205
+ <li id="option_color_red" class="red" ><a><span>red </span></a></li>
206
+ <li id="option_color_violet" class="violet"><a><span>violet</span></a></li>
207
+ </ul>
208
+ </div>
209
+
210
+ <div id="footer">
211
+ <p>Copyright &copy; 2006, Your Name. Valid <a href="http://validator.w3.org/check/referer">XHTML</a> and <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>.</p>
212
+ <p>Using <a href="http://evil.che.lu/projects/skittlish">skittlish</a> on <a href="http://publishwithimpunity.com/">mephisto</a>.</p>
213
+ </div>
214
+
215
+ </div>
216
+
217
+ </body>
218
+
219
+ </html>
@@ -0,0 +1 @@
1
+ *.png filter=broken
@@ -0,0 +1,219 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ {{ '/feed/atom.xml' | assign_to: 'global_feed' }}
4
+ {{ '/feed/all_comments.xml' | assign_to: 'global_comments_feed' }}
5
+ <head>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <title>
8
+ {{ site.title }}
9
+ {% if site.current_section %}
10
+ - {{ site.current_section.name }}
11
+ {% endif %}
12
+ {% if article %}
13
+ - {{ article.title }}
14
+ {% endif %}
15
+ </title>
16
+ <link rel="alternate" type="application/atom+xml" title="{{ site.title }} feed" href="{{ global_feed }}"/>
17
+ <link rel="alternate" type="application/atom+xml" title="{{ site.title }} comments feed" href="{{ global_comments_feed }}"/>
18
+ {{ 'base' | stylesheet }}
19
+ {{ 'app' | javascript }}
20
+ <!--[if IE]>
21
+ {{ 'base_ie' | stylesheet }}
22
+ <![endif]-->
23
+ </head>
24
+
25
+ <body class="fixed orange">
26
+ <script type="text/javascript">loadPreferences()</script>
27
+
28
+ <div id="wrapper">
29
+
30
+ <div id="header" class="clearfix">
31
+ <div id="title" class="clearfix">
32
+ <h1><a href="/">{{ site.title }}</a></h1>
33
+ </div>
34
+ <h2>Sections</h2>
35
+ <ul id="menu">
36
+ {% for section in site.sections %}
37
+ {% if section.articles_count > 0 %}
38
+ {% if section.is_home %}
39
+ <li{% if section.current %} class="selected"{% endif %}>{{ section | link_to_section }}</li>
40
+ {% else %}
41
+ {% if section.is_paged %}
42
+ <li{% if section.current %} class="selected"{% endif %}>{{ section | link_to_section }}</li>
43
+ {% endif %}
44
+ {% endif %}
45
+ {% endif %}
46
+ {% endfor %}
47
+ </ul>
48
+ </div>
49
+
50
+ <div id="contentwrapper" class="clearfix">
51
+
52
+ <div id="content">
53
+
54
+ <div id="innerwrapper">
55
+
56
+ <div class="article">
57
+ <div class="body">
58
+ <h2>Skittlish Tips'n'Tricks</h2>
59
+ <ul>
60
+ <li>Change the classes for the body tag to set your default site style. also change these in the app.js file (line 66).</li>
61
+ <li>Remove the scripts and the #options div if you don't want the option switcher.</li>
62
+ <li>The top menu shows the home section and the sections that are not blogs.</li>
63
+ <li>Email me at <a href="mailto:evil@che.lu">evil@che.lu</a> if you have any questions.</li>
64
+ <li>Happy hacking!</li>
65
+ </ul>
66
+ </div>
67
+ </div>
68
+
69
+ {{ content_for_layout }}
70
+
71
+ </div>
72
+
73
+ </div>
74
+
75
+ <div id="sidebar">
76
+
77
+ <div class="boxy short">
78
+ <h3>boxy short</h3>
79
+
80
+ <p>You can have, boxes with a short, tall or no background shade, just change the class of the containing div.</p>
81
+
82
+ <p>Have boxes with smaller text with the class "minor". See the "Recent" boxy below.</p>
83
+
84
+ </div>
85
+
86
+ <div id="search" class="boxy short">
87
+ <h3>Search</h3>
88
+ <form method="get" action="/search">
89
+ <fieldset>
90
+ <input class="text" type="text" id="q" value="" name="q"/>
91
+ </fieldset>
92
+ </form>
93
+ </div>
94
+
95
+ <div class="boxy tall minor">
96
+ <h3>Recent</h3>
97
+
98
+ <dl>
99
+ <dt>Articles <a class="feed" href="{{ global_feed }}"><span>feed</span></a></dt>
100
+ <dd>
101
+ <ul>
102
+ {% for article in site.latest_articles %}
103
+ <li>{{ article | link_to_article }} <em>({{ article.published_at | format_date: 'stub', true }})</em></li>
104
+ {% endfor %}
105
+ </ul>
106
+ </dd>
107
+
108
+ <dt>Comments <a class="feed" href="{{ global_comments_feed }}"><span>feed</span></a></dt>
109
+ <dd>
110
+ <ul>
111
+ {% for comment in site.latest_comments %}
112
+ <li>{{ comment.author_link }} on <a href="{{ comment.url }}#comment-{{ comment.id }}">{{ comment.title }}</a></li>
113
+ {% endfor %}
114
+ </ul>
115
+ </dd>
116
+ </dl>
117
+ </div>
118
+
119
+ <div class="boxy short">
120
+ <h3>Archives</h3>
121
+ <p>This would be much nicer with jamis' month_drop thingy.</p>
122
+ {{ '' | section | months | assign_to: 'home_section' }}
123
+ <ul>
124
+ {% for month in home_section.months %}
125
+ {{ home_section | monthly_articles: month | size | assign_to: 'articles_count' }}
126
+ {% if articles_count > 0 %}
127
+ <li>{{ home_section | link_to_month: month }} ({{ articles_count }})</li>
128
+ {% endif %}
129
+ {% endfor %}
130
+ </ul>
131
+ </div>
132
+
133
+ {% if site.blog_sections.size > 1 %}
134
+ <div class="boxy short">
135
+ <h3>Categories</h3>
136
+ <p>Lists only blog type categories with at least one article.</p>
137
+ <p>This list uses an ul. You could use a dl with only dd's in it for the same effect. Wouldn't be semantic tho.</p>
138
+ <ul class="sections">
139
+ {% for section in site.blog_sections %}
140
+ {% if section.articles_count > 0 %}
141
+ {% unless section.is_home %}
142
+ <li>{{ section | link_to_section }} ({{ section.articles_count }})</li>
143
+ {% endunless %}
144
+ {% endif %}
145
+ {% endfor %}
146
+ </ul>
147
+ </div>
148
+
149
+ {% endif %}
150
+ {% unless site.tags == empty %}
151
+ <div class="boxy short">
152
+ <p>This would be nicer if we could get the number of articles for each tag.</p>
153
+ <h3>tags: </h3>
154
+ <ul>
155
+ {% for tag in site.tags %}
156
+ <li>{{ tag | link_to_tag }}</li>
157
+ {% endfor %}
158
+ </ul>
159
+ </div>
160
+
161
+ {% endunless %}
162
+ <div class="boxy tall">
163
+ <h3>boxy tall</h3>
164
+ <p>When using a tall box, make sure it's got plenty of content or that it's immediately followed by a short boxy. It might look a bit chopped off otherwise.</p>
165
+ <dl>
166
+ <dt>thing 1</dt>
167
+ <dd><a href="#">value 1</a></dd>
168
+ <dd><a href="#">value 2</a></dd>
169
+ <dd><a href="#">value 3</a></dd>
170
+ <dd><a href="#">value 4</a></dd>
171
+ <dd><a href="#">value 5</a></dd>
172
+ <dd><a href="#">value 6</a></dd>
173
+ <dd><a href="#">value 6</a></dd>
174
+
175
+ <dt>thing 1</dt>
176
+ <dd><a href="#">value 1</a></dd>
177
+ <dd><a href="#">value 2</a></dd>
178
+ <dd><a href="#">value 3</a></dd>
179
+ <dd>value 4</dd>
180
+ <dd>value 5</dd>
181
+ <dd><a href="#">value 6</a></dd>
182
+ <dd><a href="#">value 6</a></dd>
183
+
184
+ </dl>
185
+ </div>
186
+
187
+ </div>
188
+
189
+ </div>
190
+
191
+ <div id="options">
192
+ <h2>Options:</h2>
193
+ <h3>Size</h3>
194
+ <ul id="option_size">
195
+ <li id="option_size_fixed" class="fixed" ><a><span>fixed </span></a></li>
196
+ <li id="option_size_fluid" class="fluid" ><a><span>fluid </span></a></li>
197
+ </ul>
198
+ <h3>Colors</h3>
199
+ <ul id="option_color">
200
+ <li id="option_color_orange" class="orange"><a><span>orange</span></a></li>
201
+ <li id="option_color_blue" class="blue" ><a><span>blue </span></a></li>
202
+ <li id="option_color_green" class="green" ><a><span>green </span></a></li>
203
+ <li id="option_color_pink" class="pink" ><a><span>pink </span></a></li>
204
+ <li id="option_color_cyan" class="cyan" ><a><span>cyan </span></a></li>
205
+ <li id="option_color_red" class="red" ><a><span>red </span></a></li>
206
+ <li id="option_color_violet" class="violet"><a><span>violet</span></a></li>
207
+ </ul>
208
+ </div>
209
+
210
+ <div id="footer">
211
+ <p>Copyright &copy; 2006, Your Name. Valid <a href="http://validator.w3.org/check/referer">XHTML</a> and <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>.</p>
212
+ <p>Using <a href="http://evil.che.lu/projects/skittlish">skittlish</a> on <a href="http://publishwithimpunity.com/">mephisto</a>.</p>
213
+ </div>
214
+
215
+ </div>
216
+
217
+ </body>
218
+
219
+ </html>
@@ -400,7 +400,7 @@ PATCH
400
400
  describe 'with changes' do
401
401
  before do
402
402
  FileUtils.cp_r(File.join(FIXTURE_PATH, 'skit1.1') + '/layouts/layout.liquid', "#{@repository_dir}/skit-layout.liquid",
403
- {preserve: true})
403
+ preserve: true)
404
404
  in_dir(@repository_dir) do
405
405
  run_command('git add *')
406
406
  run_command('git commit -m "Some local changes"')
@@ -463,7 +463,7 @@ PATCH
463
463
  @filemode_enabled = filemode_enabled
464
464
  end
465
465
  FileUtils.cp_r(File.join(FIXTURE_PATH, 'skit1.1x') + '/layouts/layout.liquid', "#{@repository_dir}/skit-layout.liquid",
466
- {preserve: true})
466
+ preserve: true)
467
467
  in_dir(@repository_dir) do
468
468
  run_command('git add *')
469
469
  run_command('git commit -m "Some local changes"')
@@ -20,6 +20,12 @@ FileUtils.mkdir_p(TMP_PATH)
20
20
 
21
21
  BRAID_BIN = ((defined?(JRUBY_VERSION) || Gem.win_platform?) ? 'ruby ' : '') + File.join(BRAID_PATH, 'bin', 'braid')
22
22
 
23
+ # Use a separate, clean cache for each test case (because TMP_PATH is deleted
24
+ # and recreated for each test case). We don't want to mess with the user's real
25
+ # cache, and this ensures that previous cache contents can't affect the behavior
26
+ # of the tests.
27
+ ENV['BRAID_LOCAL_CACHE_DIR'] = File.join(TMP_PATH, 'braid-cache')
28
+
23
29
  # Must run in a git repository, though we expect the setting to be the same for
24
30
  # most repositories on a given OS.
25
31
  def filemode_enabled
@@ -83,10 +89,18 @@ def run_command_expect_failure(command)
83
89
  output
84
90
  end
85
91
 
92
+ # Rough equivalent of git.require_version within Braid, but without pulling in a
93
+ # bunch of dependencies from Braid::Operations. This small amount of code
94
+ # duplication seems like a lesser evil than sorting out all the dependencies.
95
+ def git_require_version(required)
96
+ actual = run_command('git --version').sub(/^.* version/, '').strip
97
+ Gem::Version.new(actual) >= Gem::Version.new(required)
98
+ end
99
+
86
100
  def update_dir_from_fixture(dir, fixture = dir)
87
101
  to_dir = File.join(TMP_PATH, dir)
88
102
  FileUtils.mkdir_p(to_dir)
89
- FileUtils.cp_r(File.join(FIXTURE_PATH, fixture) + '/.', to_dir, {preserve: true})
103
+ FileUtils.cp_r(File.join(FIXTURE_PATH, fixture) + '/.', to_dir, preserve: true)
90
104
  end
91
105
 
92
106
  def create_git_repo_from_fixture(fixture_name, options = {})
@@ -97,6 +111,9 @@ def create_git_repo_from_fixture(fixture_name, options = {})
97
111
  update_dir_from_fixture(directory, fixture_name)
98
112
 
99
113
  in_dir(git_repo) do
114
+ # Avoid a warning emitted by because we use the old default default branch name
115
+ run_command('git config --global init.defaultBranch master')
116
+
100
117
  run_command('git init')
101
118
  run_command("git config --local user.email \"#{email}\"")
102
119
  run_command("git config --local user.name \"#{name}\"")
@@ -1,10 +1,17 @@
1
1
  require File.dirname(__FILE__) + '/integration_helper'
2
2
 
3
+ BRAID_PUSH_USES_SPARSE_CHECKOUT = git_require_version('2.27')
4
+
3
5
  describe 'Pushing to a mirror' do
4
6
 
5
- before do
7
+ # This code needs to run before the `around` hook in the required-filter test
8
+ # that sets up the virtual home directory inside TMP_PATH, but per-example
9
+ # `before` hooks always run after `around` hooks. So make this an `around`
10
+ # hook just to get it to run at the time we want.
11
+ around do |example|
6
12
  FileUtils.rm_rf(TMP_PATH)
7
13
  FileUtils.mkdir_p(TMP_PATH)
14
+ example.run
8
15
  end
9
16
 
10
17
  describe 'from a git repository' do
@@ -166,7 +173,7 @@ describe 'Pushing to a mirror' do
166
173
  end
167
174
 
168
175
  FileUtils.cp_r(File.join(FIXTURE_PATH, 'skit1.1x') + '/layouts/layout.liquid', "#{@repository_dir}/skit-layout.liquid",
169
- {preserve: true})
176
+ preserve: true)
170
177
  in_dir(@repository_dir) do
171
178
  run_command('git add *')
172
179
  run_command('git commit -m "Make some changes to vendored files"')
@@ -294,4 +301,102 @@ describe 'Pushing to a mirror' do
294
301
  end
295
302
  end
296
303
  end
304
+
305
+ describe 'from a git repository with a required filter', :if => BRAID_PUSH_USES_SPARSE_CHECKOUT do
306
+ # This tests that a Git filter that is configured as "required" at the user
307
+ # account level but fails without additional repository-level configuration
308
+ # (which currently may be the case for Git LFS:
309
+ # https://github.com/cristibalan/braid/pull/98) does not interfere with
310
+ # pushing using a temporary repository. Braid achieves this by using an
311
+ # empty sparse checkout in the temporary repository to avoid triggering the
312
+ # filter.
313
+
314
+ around do |example|
315
+ # In order to simulate configuring the filter at the user account level
316
+ # without modifying the user's real Git configuration, we have to
317
+ # temporarily change $HOME. Unfortunately, this may break other things
318
+ # that need the real $HOME. So far, the only problem we've seen is the
319
+ # Braid subprocess not finding Ruby gems, and setting $GEM_PATH seems to
320
+ # be a sufficient workaround.
321
+ orig_gem_path = run_command('gem environment gempath').strip
322
+ virtual_home = File.join(TMP_PATH, 'home')
323
+ FileUtils.mkdir_p(virtual_home)
324
+ Braid::Operations::with_modified_environment({
325
+ 'HOME' => virtual_home,
326
+ # If the user has an $XDG_CONFIG_HOME-based configuration file, ensure
327
+ # that Git doesn't use it, to maintain consistency with not using the
328
+ # original ~/.gitconfig. TODO: Would it be better to `include` both
329
+ # files in case they have a setting that we actually need?
330
+ 'XDG_CONFIG_HOME' => nil,
331
+ 'GEM_PATH' => orig_gem_path
332
+ }) do
333
+ example.run
334
+ end
335
+ end
336
+
337
+ before do
338
+ # create_git_repo_from_fixture('skit1_with_filter') would check out the
339
+ # working tree and trigger the broken filter before we have an opportunity
340
+ # to turn it off in the repository configuration. Avoiding this problem
341
+ # would take some extra code, so as a workaround, we just don't configure
342
+ # the filter until after that step. :/
343
+ @vendor_repository_dir = create_git_repo_from_fixture('skit1_with_filter')
344
+
345
+ # Avoid a warning emitted by because we use the old default default branch name
346
+ run_command('git config --global init.defaultBranch master')
347
+
348
+ # Configure the broken filter globally. Here, `false` is the command that
349
+ # always exits 1.
350
+ run_command('git config --global filter.broken.clean false')
351
+ run_command('git config --global filter.broken.smudge false')
352
+ run_command('git config --global filter.broken.required true')
353
+
354
+ # This won't trigger the filter because the .gitattributes file is only in
355
+ # the vendor repository.
356
+ @repository_dir = create_git_repo_from_fixture('shiny', :name => 'Some body', :email => 'somebody@example.com')
357
+ @file_name = 'layouts/layout.liquid'
358
+
359
+ in_dir(@repository_dir) do
360
+ # Make the filter a no-op in the superproject repository.
361
+ run_command('git config filter.broken.clean cat')
362
+ run_command('git config filter.broken.smudge cat')
363
+
364
+ run_command("#{BRAID_BIN} add #{@vendor_repository_dir} skit1")
365
+ end
366
+
367
+ in_dir(@vendor_repository_dir) do
368
+ run_command('git config receive.denyCurrentBranch updateInstead')
369
+ end
370
+
371
+ update_dir_from_fixture('shiny/skit1', 'skit1.1_with_filter')
372
+ in_dir(@repository_dir) do
373
+ run_command('git add *')
374
+ run_command('git commit -m "Make some changes to vendored files"')
375
+ end
376
+ end
377
+
378
+ it 'should push changes successfully' do
379
+ braid_output = nil
380
+ commit_message = 'Make some changes'
381
+ in_dir(@repository_dir) do
382
+ with_editor_message(commit_message) do
383
+ braid_output = run_command("#{BRAID_BIN} push skit1")
384
+ end
385
+ end
386
+ expect(braid_output).to match(/Braid: Cloning mirror with local changes./)
387
+ expect(braid_output).to match(/Make some changes/)
388
+ expect(braid_output).to match(/Braid: Pushing changes to remote branch master./)
389
+
390
+ assert_no_diff("#{FIXTURE_PATH}/skit1.1_with_filter/#{@file_name}", "#{@repository_dir}/skit1/#{@file_name}")
391
+ assert_no_diff("#{FIXTURE_PATH}/skit1.1_with_filter/#{@file_name}", "#{@vendor_repository_dir}/#{@file_name}")
392
+
393
+ in_dir(@vendor_repository_dir) do
394
+ run_command('git checkout master 2>&1')
395
+
396
+ assert_commit_subject(commit_message)
397
+ assert_commit_author('Some body')
398
+ assert_commit_email('somebody@example.com')
399
+ end
400
+ end
401
+ end
297
402
  end
metadata CHANGED
@@ -1,16 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: braid
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cristi Balan
8
8
  - Norbert Crombach
9
9
  - Peter Donald
10
+ - Matt McCutchen
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
13
- date: 2019-06-10 00:00:00.000000000 Z
14
+ date: 2022-01-24 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: main
@@ -97,14 +98,13 @@ dependencies:
97
98
  - !ruby/object:Gem::Version
98
99
  version: '0'
99
100
  description: A simple tool for tracking vendor branches in git.
100
- email: evil@che.lu norbert.crombach@primetheory.org peter@realityforge.org
101
+ email: evil@che.lu norbert.crombach@primetheory.org peter@realityforge.org matt@mattmccutchen.net
101
102
  executables:
102
103
  - braid
103
104
  extensions: []
104
105
  extra_rdoc_files: []
105
106
  files:
106
107
  - ".gitignore"
107
- - ".ruby-version"
108
108
  - ".travis.yml"
109
109
  - CONTRIBUTING.md
110
110
  - Gemfile
@@ -114,6 +114,7 @@ files:
114
114
  - _config.yml
115
115
  - bin/braid
116
116
  - braid.gemspec
117
+ - braids-json.schema.json
117
118
  - config_versions.md
118
119
  - lib/braid.rb
119
120
  - lib/braid/command.rb
@@ -164,12 +165,18 @@ files:
164
165
  - spec/fixtures/shiny_skit1_mergeable/layouts/layout.liquid
165
166
  - spec/fixtures/shiny_skit1_mergeable/preview.png
166
167
  - spec/fixtures/skit1.1/layouts/layout.liquid
168
+ - spec/fixtures/skit1.1_with_filter/.gitattributes
169
+ - spec/fixtures/skit1.1_with_filter/layouts/layout.liquid
170
+ - spec/fixtures/skit1.1_with_filter/preview.png
167
171
  - spec/fixtures/skit1.1x/layouts/layout.liquid
168
172
  - spec/fixtures/skit1.2/layouts/layout.liquid
169
173
  - spec/fixtures/skit1.3/layouts/README.md
170
174
  - spec/fixtures/skit1.3/layouts/layout.liquid
171
175
  - spec/fixtures/skit1/layouts/layout.liquid
172
176
  - spec/fixtures/skit1/preview.png
177
+ - spec/fixtures/skit1_with_filter/.gitattributes
178
+ - spec/fixtures/skit1_with_filter/layouts/layout.liquid
179
+ - spec/fixtures/skit1_with_filter/preview.png
173
180
  - spec/integration/adding_spec.rb
174
181
  - spec/integration/config_versioning_spec.rb
175
182
  - spec/integration/diff_spec.rb
@@ -204,8 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
204
211
  - !ruby/object:Gem::Version
205
212
  version: '0'
206
213
  requirements: []
207
- rubyforge_project: braid
208
- rubygems_version: 2.5.2.3
214
+ rubygems_version: 3.1.4
209
215
  signing_key:
210
216
  specification_version: 4
211
217
  summary: A simple tool for tracking vendor branches in git.
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.3.8