Merge remote-tracking branch 'origin/pr/721'

* origin/pr/721:
  Add tests for model.GetIgnores model.SetIgnores
  Expose ignores in the UI
  Add comments directive to ignores
  Expose ignores rest endpoints
  Expose ignores from model
This commit is contained in:
Jakob Borg committed 2014-09-22 14:59:13 +02:00
commit 737a28050c
9 files changed
+295 -2

No files matched your search

+2 -2
View File
@@ -27,7 +27,7 @@ func Assets() map[string][]byte {
bs, _ = ioutil.ReadAll(gr)
assets["angular/angular.min.js"] = bs
bs, _ = base64.StdEncoding.DecodeString("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 truncated
bs, _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/+w9f3fbNpL/+1MgulwlJQrtJG3eXlynlzrJnrdpkrOT7r3nuvdoCZJYU6RKUna0jb/7zQwAEj8pyk6z2/dOr40lAhgMBoP5hQG4u8sO8+W6SGbzig0Oh+zR3sOv2d/ii/ycfZ8XMxZnE6iRVUVyvqryomSDknNWzTk7fPvm/fHR9x/evz0+YdMk5cNoB8A9T1NG4EpW8JIXl3wSsQ8lZ/kUmiUlK/NVMeZsnE84g5+z/JIXGZ+w8zV0xn48ev+grNYpR1hpMuZZid3FFRtD6Tln03wFKCUZ4fD66PDlm5OX1H20s7N779cyTbKKnRf5FfT9lFXFio+gr6xKshVXv5fpqsT/xW92bxdaztL8PE7Z3adsGqclVIqz2SqNi/o3ACnzlNe/L+M0mbyGWqV8hHB2+iv4UgK5xlV/f2fnMi5Yuc7GMPJsxg4U0GiRT1YpH/Trsv6InfaXcTmO02XBx/Mqqoo4K9O44v2z4T4BWhXpeQzgD1gfSIvw8WnBf1vBr/fJguerCgof7+FnnwEBj3lVrIlSxy9P3quqLJ5WvGDfsAUQpeIlu0qqObYt+DJdS6BT6GLeAP1GgXyRsyyvVAWCPeMZhwHDsONqVQIxSgQPk5ZBHyUHwk1KHep/r5LxhQE6BPk3rElwLbB7e4B8miYK+k5NyAgeTJPZYLqCB0mescHdeVUt3xX5ZTLhxYjdrQmrng3Z7zsMPkbFaMKn8SqtyuhjWUz/i8fw7E28IOr/z4PDk+NXD97nFzyDWdjQ9jDPLxKu2hotRVMHoQiY6AQGnYxfAWOXr3PsfCCQxA9wyDT5+JT1U+CnXfznQX9Ul5arqSiNfi3zrE/Pr4GF8H+TTlWRpylA7r+85Fl1WBUpsKFGuHKcL4HTaWw1kehhlMJsUCsYU7ZKU0EFnGQsOXoBj/fk+GgNrMZjXpavMnjedDCJq1jBxQ8wwd/nPGMn9YpBPo8LmP2rOVCCeCLN4fkSEMdyGETGBTSQJUmmg1oW+Qzal9RKSgQGFcscZmIJ9J7mxQKlVLUqspLFIPv2QLwl2Zg60kHNafpLNo9LkEGA4RSkxxyEFq4cgi+gCKkGcIYjUZTlDAcZ6cDeoxSEhZzAWk/XbMFh9oWIQ0DaiOreUJBWI5LFVAXa6QCvoB6unHhcrQgkUBvGPV2lTb/JlA3u2PTGDy+KvHiVibnYN4rEmJpn1zv1V8kFd/kiqQb9D0dvM5gO3h/u7xg9Sl54xvbsbokqMAEv4/FcW6scWcquix8pfaM0nw16VKs3YvQ3SibqW7VGdhXfPeNxEHdaWQ2uh22D15cA9nZKY0p5NoOJf8AenjWN6zVhNwXkNZLBLEuxqJHEpgatxmjGq4HSB/dZf5fQL78j7j3owyPR5dAhQCSX4qBekp46xBQDyRo6EUYoeuWDa219y6qtq9vhmenUYZrbUyBNAPzBw/7nH/nDPWfoW2LShoHTc4u4ruVju8jWdR18T/NxjLUUOXHeQJNcvoBiIa7VUxjQ2x/gEVpHzdMsvkxmACGbPb+K1zjVaPU05TnJAPe5lOHCAJJluioZ54tlygn/A/b79b5Zhso89PwoQ0oYiDblUoqWbmOiMT4/PTOeg1HGU7f6Yk1Lt983nmZQ2QMDlE6Vj/P0EMyUGSgIgxqyDphZeVEB2WO3M1H2DqYl4VfB1p5BgVmevcSBuaiulrMC9NdRNs097ci4Eo+DPN0jI6M3rBm44TgsKC0l/iqRmmqaFGBuYpVVPOPKagezrULtjLYO2f34EEyeol8qPa1DI9WYoIIWdg96EnED9IqDorzkLL6MkzQ+Bx0BGpZajFiPZz0dVInSWnaoLIIrsCPZIq7Gc6rOgILw98GHE1Awwuro/WP+4P3fe1RThyYaAduv6yqoolEV4+/DN72okWzCNMpmI9EMVkMjXEAPsgFWSGgdwp9vqW4ptQk8uX/floJYAapTvdPkzNRcQvmC2JDq6Fv2KKBVyTGy1J7xS6ELfTUuTwQeF1jjGh8AU5YJUB+LfV2R4cMFutKyaCZ/F2XErihD60ZMyjlxTJpfafyggRsDb0bs72gyLZZxAUZbLg1EaICFDDzLEpEj15PXLOMFhoZbzUpgb/JUs57URx8k0EP/GVX5a+z4EDoeeAwPnBGjvpyZZ0ybJx/h8COtS6M9rDH+8e2UpnnIDg5qCW5MJePombZCTXVo5jSGoAatJDVSxTT1KA/YQ9/gGgWFPk/d7HTvzENC2x41Ubk2JBAw0XkMviMgA+uR+JeA88lOoG9c/Eq9K5Pk7uAKCJNfDaNz+Dvon3NYqnyVpeCRGXpXH5ujJxvt1ACWtlCeDXq1YhY640SI2F4IvBIkaE2qliD94wIM6WGEJfuWDe4uSGvoVGXfoqSNa8b55HmjUuva/WLRB2fzBU81HxQeTpJCPgdTMCmGeimaNViI6lt/XuWr8RwLPiwnGPkYKWvLwuNoHMCi4Iv8knsRcYsUFjDBckY9mFDUISkvGlzsCWzcH33KyAgEn60wiI8TIu2kr75idxrTyJ6hFt8LYYQbTvLxaoGeRc0bBcfBDZAL9Un2SQbdyzK8Or2SHHqSgRlvFdUmYMPyzYBcK9CAOuj/W8arq7y4IDOmP0R7LE4H/TmYCQ4OULuBuLluOV9VOM3hmn6mV/MrXZVuE2wJgE+f2B1BmC0m2Z6JxldyaG0Rkzz9MH8E6dyNFhiW4tK47UAOFFYTYehCCTnlJqa66S0caLRvzxys/dXIeuXS/wYN3GkIr2FhpEeo74SUufU4ZMTyGDAa1LjpXi0oJNEV03wdFS0F2w8tHuFPkK0LZkg5J4MGI0UIjIJJke1JkyegU+MNwvBEVRD24dQjYwjvwxonVZEAHb0YMX00NWUdJanR9hiEbMW/BHHDg6BaOBIXfy/OONgXSSldxk4YAxdymE3X2TxVA4iSyZmDJPaEC6gcbMLncAtkaMFvQCWwnkLVDdVa95OdL8unbG/klOSrKlR0lH2/rnj5Pq/i1Fvh7araUOP5ZIJh3Kc1c0QxPDHrXXtVVLPaNo/ufyuBwMO9vSDoFqFySAEJitR75syeLiOKEb1d0gxEH46fg+m3rDBsgIa3PWkgRo6m4Cij1yviBKhN6yhxxkFIgEMbKyAZiJYJH6OamIxsSCBkrmLwhsFpisuL2gXH34v4AnwgNp7nyRg8rO9XJJImedavqI0NCpqcr2YIYsEmqwKRQuMgiVOM562WI1bmJNR4hWBpO4QkmgMIkKiSBVcOmwgfXCZlUkViZ0DsBAoIIBuXGBl3EVKBcoIF1RY5CdM4w93Dgs3hn5LFs3yEWMnR2zBopwzNpx2jBGUVofUTYoWaR9lbAiuUNmk85oPdwXdP4b9fPkX39n8u7w2bRvDr5wP4Z3D6y/7ZvWF07+7w0y/w7+6I9e4+7Hm8qTtNY58TZaEASPWaBgc9dp9hiA9E4hU4EvdZb38Rf3wATERFj/fYPfboa/jn8ZM9y9cLeo+I1H2NDN/qPTxgChr8oaBpwP9EU2TlNUBqBFp9vZaFeAJufBfZuSIlRRaBaDhQgkLX3/4wr1i9u+RF+CJjvt0Wf/iSBJP+rEXbUiSWf6wO0WjQwnZ1v7rCJNVnadoLjj5pT6uGbIA1TctMdXIKDc7QWzEfPNOmfLNdq76ZMA5MxjR3svc3kJ9swe8Qb9rv4BmGcD4cH6ElkGcw2WL0XWdmA2b6drhX1wjTlOwwOaP7QdfKIP6IaC9sFZ+ZZU2vy7GCcexpBrVwqILnd5Ly5WJZrd+e/wra3tQ+Bp9bQXfxZd9fXqut1wm4yNlJVTT7W94aUo9Hv+YJrNMR63u6VlF1Ew7ZtQ4a2XbWrmsTmNbuLcyCYQC3ElS0QEdEKD0DVtF8/PtjvLQsA2QQkK95kfBS60TMYwScWg50OEMPNWwRgB9HRHg5WrgXN/IstE5avAtP19fWCjCN3JqnA3MrtxYNW8x1a/3y8mQNPLpwIm2mtBSVen8qOVkSzp01VBc5qCfw+IWh2DIjvYbfvZUEYp2FpaR9Z0Hp5z/JdXbEBqP/aHNr+G8RrHEZpekVlSuB/zPq2EZYfodjIEUrB9P/6p+vek3P15DrjserMZ5dVdsUdanZ0s7Q9lrpvusygBbBrT3XuR1T+ohld9f7gePFErfAthgikgRbITP3hPLqhexv/+6fO3z84ADuHwQpAV2euWBwcNDo4Q1oGwncMZQMPe8iKIusPhmhLbsRa5b7KEjBLcSIipTIAE6rnrBq/7kUhhYU+kJag3ya/Mpo5y6VCrMpBljvQZ23MgTWQBfTrW0kVuFHS3UBGJ4Fl1BasW90auYogS4CK+TtVfauAIYqqjU0c6ZJfbZaYMU6AIVyy5LJWUQBOED/x7iaR+DDD/ZG7C/gYw/qGnq0DajkifLZtZCA1cTjehs9iwBfa9dGHC/ct1Et2Pk1G1NuxcDZMgkSxbNN7R/C5v3sgMeuJRR1s1gaKVBubbbQ3swmMSMq/bmki0i++rLmaJ3wRetX/No8fZK62xuc5JUbmY8t8aPOlHAdf0+Ka4ANobZ/HP9SIa4mwGXvlxh5pe1rAtv0/kxWdm+XUvB20SDxZtj9EdEqlfXnCrLa9iQ7vzE+qUWLUU3l0nZ7HZfVCW5JgKrlV4TcoKVaOE3bV/tFvC7JEFCQh4228UKXJgL8+cuTr50Q98blUzPhRkmgJUYEGdaKNnj2MYX08BWYBmj77uKGhS0z47Zd1CqhTq5n+XMrkSI2rrbt2EiZNZm2Q58yAXbbTs28WbtXmbDdkqbeln1rsI+5jaEOQN2ChTZwijIuAt0v8xORm6Bj4Aub4MmJfOqNgIP72V9lEz7Fzce+X6xijYsMs3K8URUnPUSEIpOM0lDZHewiCLms8uUSevZCVpUweOHpgZJKgrQ5TOPyC5AmAX75A+gywcydwg+YDmrJhJoOtFG4yCbQJpmkPLine truncated
gr, _ = gzip.NewReader(bytes.NewBuffer(bs))
bs, _ = ioutil.ReadAll(gr)
assets["app.js"] = bs
@@ -92,7 +92,7 @@ func Assets() map[string][]byte {
bs, _ = ioutil.ReadAll(gr)
assets["img/logo-text-64.png"] = bs
bs, _ = base64.StdEncoding.DecodeString("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 truncated
bs, _ = base64.StdEncoding.DecodeString("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 truncated
gr, _ = gzip.NewReader(bytes.NewBuffer(bs))
bs, _ = ioutil.ReadAll(gr)
assets["index.html"] = bs
+37
View File
@@ -84,6 +84,7 @@ func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) erro
getRestMux.HandleFunc("/rest/discovery", restGetDiscovery)
getRestMux.HandleFunc("/rest/errors", restGetErrors)
getRestMux.HandleFunc("/rest/events", restGetEvents)
getRestMux.HandleFunc("/rest/ignores", withModel(m, restGetIgnores))
getRestMux.HandleFunc("/rest/lang", restGetLang)
getRestMux.HandleFunc("/rest/model", withModel(m, restGetModel))
getRestMux.HandleFunc("/rest/model/version", withModel(m, restGetModelVersion))
@@ -105,6 +106,7 @@ func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) erro
postRestMux.HandleFunc("/rest/discovery/hint", restPostDiscoveryHint)
postRestMux.HandleFunc("/rest/error", restPostError)
postRestMux.HandleFunc("/rest/error/clear", restClearErrors)
postRestMux.HandleFunc("/rest/ignores", withModel(m, restPostIgnores))
postRestMux.HandleFunc("/rest/model/override", withModel(m, restPostOverride))
postRestMux.HandleFunc("/rest/reset", restPostReset)
postRestMux.HandleFunc("/rest/restart", restPostRestart)
@@ -457,6 +459,41 @@ func restGetReport(m *model.Model, w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(reportData(m))
}
func restGetIgnores(m *model.Model, w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query()
w.Header().Set("Content-Type", "application/json; charset=utf-8")
ignores, err := m.GetIgnores(qs.Get("repo"))
if err != nil {
http.Error(w, err.Error(), 500)
return
}
json.NewEncoder(w).Encode(map[string][]string{
"ignore": ignores,
})
}
func restPostIgnores(m *model.Model, w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query()
var data map[string][]string
err := json.NewDecoder(r.Body).Decode(&data)
r.Body.Close()
if err != nil {
http.Error(w, err.Error(), 500)
return
}
err = m.SetIgnores(qs.Get("repo"), data["ignore"])
if err != nil {
http.Error(w, err.Error(), 500)
return
}
restGetIgnores(m, w, r)
}
func restGetEvents(w http.ResponseWriter, r *http.Request) {
qs := r.URL.Query()
sinceStr := qs.Get("since")
+36
View File
@@ -888,6 +888,42 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http, $translate, $loca
$scope.saveConfig();
};
$scope.editIgnores = function () {
if (!$scope.editingExisting) {
return;
}
$('#editIgnoresButton').attr('disabled', 'disabled');
$http.get(urlbase + '/ignores?repo=' + encodeURIComponent($scope.currentRepo.ID))
.success(function (data) {
$('#editRepo').modal('hide');
var textArea = $('#editIgnores textarea');
textArea.val(data.ignore.join('\n'));
$('#editIgnores').modal()
.on('hidden.bs.modal', function () {
$('#editRepo').modal();
})
.on('shown.bs.modal', function () {
textArea.focus();
});
})
.then(function () {
$('#editIgnoresButton').removeAttr('disabled');
});
};
$scope.saveIgnores = function () {
if (!$scope.editingExisting) {
return;
}
$http.post(urlbase + '/ignores?repo=' + encodeURIComponent($scope.currentRepo.ID), {
ignore: $('#editIgnores textarea').val().split('\n')
});
};
$scope.setAPIKey = function (cfg) {
cfg.APIKey = randomString(30, 32);
};
+29
View File
@@ -522,6 +522,35 @@
<button type="button" class="btn btn-primary btn-sm" ng-click="saveRepo()" ng-disabled="repoEditor.$invalid"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Save</span></button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
<button ng-if="editingExisting" type="button" class="btn btn-danger pull-left btn-sm" ng-click="deleteRepo()"><span class="glyphicon glyphicon-minus"></span>&emsp;<span translate>Delete</span></button>
<button id="editIgnoresButton" ng-if="editingExisting" type="button" class="btn btn-default pull-left btn-sm" ng-click="editIgnores()"><span class="glyphicon glyphicon-pencil"></span>&emsp;<span translate>Edit ignored files and directories</span></button>
</div>
</div>
</div>
</div>
<!-- Ignores editor modal -->
<div id="editIgnores" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 translate class="modal-title">Ignored files and directories</h4>
</div>
<div class="modal-body">
<p translate>Supported patterns:</p>
<ul>
<li><code>*</code> - <span translate>Single-level wildcard (matches anything within a single directory)</span>
<li><code>**</code> - <span translate>Multi-level wildcard (matches anything within all directories at any depth)</span>
<li><code>!</code> - <span translate>Inversion of the given condition, which excludes the given pattern from any previous matches</span>
<li><code>#include</code> - <span translate>Including ignores from another file</span>
<li><code>//</code> - <span translate>Comment</span>
</ul>
<textarea class="form-control" rows="15"></textarea>
</div>
<div class="modal-footer">
<div class="pull-left"><span translate >Ignore file location</span>:<code>{{ currentRepo.Directory }}/.stignore</code></div>
<button type="button" class="btn btn-primary btn-sm" data-dismiss="modal" ng-click="saveIgnores()"><span class="glyphicon glyphicon-ok"></span>&emsp;<span translate>Save</span></button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span>&emsp;<span translate>Close</span></button>
</div>
</div>
</div>
+10
View File
@@ -11,6 +11,7 @@
"Bugs": "Bugs",
"CPU Utilization": "CPU Utilization",
"Close": "Close",
"Comment": "Comment",
"Connection Error": "Connection Error",
"Copyright © 2014 Jakob Borg and the following Contributors:": "Copyright © 2014 Jakob Borg and the following Contributors:",
"Delete": "Delete",
@@ -20,6 +21,7 @@
"Edit": "Edit",
"Edit Node": "Edit Node",
"Edit Repository": "Edit Repository",
"Edit ignored files and directories": "Edit ignored files and directories",
"Enable UPnP": "Enable UPnP",
"Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.": "Enter comma separated \"ip:port\" addresses or \"dynamic\" to perform automatic discovery of the address.",
"Error": "Error",
@@ -37,7 +39,11 @@
"Global Repository": "Global Repository",
"Idle": "Idle",
"Ignore Permissions": "Ignore Permissions",
"Ignore file location": "Ignore file location",
"Ignored files and directories": "Ignored files and directories",
"Including ignores from another file": "Including ignores from another file",
"Incoming Rate Limit (KiB/s)": "Incoming Rate Limit (KiB/s)",
"Inversion of the given condition, which excludes the given pattern from any previous matches": "Inversion of the given condition, which excludes the given pattern from any previous matches",
"Keep Versions": "Keep Versions",
"Last seen": "Last seen",
"Latest Release": "Latest Release",
@@ -48,6 +54,7 @@
"Max File Change Rate (KiB/s)": "Max File Change Rate (KiB/s)",
"Max Outstanding Requests": "Max Outstanding Requests",
"Maximum Age": "Maximum Age",
"Multi-level wildcard (matches anything within all directories at any depth)": "Multi-level wildcard (matches anything within all directories at any depth)",
"Never": "Never",
"No": "No",
"No File Versioning": "No File Versioning",
@@ -90,11 +97,13 @@
"Shown instead of Node ID in the cluster status. Will be updated to the name the node advertises if left empty.": "Shown instead of Node ID in the cluster status. Will be updated to the name the node advertises if left empty.",
"Shutdown": "Shutdown",
"Simple File Versioning": "Simple File Versioning",
"Single-level wildcard (matches anything within a single directory)": "Single-level wildcard (matches anything within a single directory)",
"Source Code": "Source Code",
"Staggered File Versioning": "Staggered File Versioning",
"Start Browser": "Start Browser",
"Stopped": "Stopped",
"Support / Forum": "Support / Forum",
"Supported patterns:": "Supported patterns:",
"Sync Protocol Listen Addresses": "Sync Protocol Listen Addresses",
"Synchronization": "Synchronization",
"Syncing": "Syncing",
@@ -116,6 +125,7 @@
"The number of old versions to keep, per file.": "The number of old versions to keep, per file.",
"The number of versions must be a number and cannot be blank.": "The number of versions must be a number and cannot be blank.",
"The repository ID cannot be blank.": "The repository ID cannot be blank.",
"The repository ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.": "The repository ID must be a short identifier (64 characters or less) consisting of letters, numbers and the dot (.), dash (-) and underscode (_) characters only.",
"The repository ID must be a short identifier (64 characters or less) consisting of letters, numbers and the the dot (.), dash (-) and underscode (_) characters only.": "The repository ID must be a short identifier (64 characters or less) consisting of letters, numbers and the the dot (.), dash (-) and underscode (_) characters only.",
"The repository ID must be unique.": "The repository ID must be unique.",
"The repository path cannot be blank.": "The repository path cannot be blank.",
+2
View File
@@ -122,6 +122,8 @@ func parseIgnoreFile(fd io.Reader, currentFile string, seen map[string]bool) (Pa
switch {
case line == "":
continue
case strings.HasPrefix(line, "//"):
continue
case strings.HasPrefix(line, "#"):
err = addPattern(line)
case strings.HasSuffix(line, "/**"):
+18
View File
@@ -133,3 +133,21 @@ func TestCaseSensitivity(t *testing.T) {
}
}
}
func TestCommentsAndBlankLines(t *testing.T) {
stignore := `
// foo
//bar
//!baz
//#dex
// ips
`
pats, _ := ignore.Parse(bytes.NewBufferString(stignore), ".stignore")
if len(pats) > 0 {
t.Errorf("Expected no patterns")
}
}
+75
View File
@@ -5,10 +5,12 @@
package model
import (
"bufio"
"crypto/tls"
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"os"
"path/filepath"
@@ -22,6 +24,7 @@ import (
"github.com/syncthing/syncthing/files"
"github.com/syncthing/syncthing/ignore"
"github.com/syncthing/syncthing/lamport"
"github.com/syncthing/syncthing/osutil"
"github.com/syncthing/syncthing/protocol"
"github.com/syncthing/syncthing/scanner"
"github.com/syncthing/syncthing/stats"
@@ -579,6 +582,78 @@ func (m *Model) ConnectedTo(nodeID protocol.NodeID) bool {
return ok
}
func (m *Model) GetIgnores(repo string) ([]string, error) {
var lines []string
cfg, ok := m.repoCfgs[repo]
if !ok {
return lines, fmt.Errorf("Repo %s does not exist", repo)
}
m.rmut.Lock()
defer m.rmut.Unlock()
fd, err := os.Open(filepath.Join(cfg.Directory, ".stignore"))
if err != nil {
if os.IsNotExist(err) {
return lines, nil
}
l.Warnln("Loading .stignore:", err)
return lines, err
}
defer fd.Close()
scanner := bufio.NewScanner(fd)
for scanner.Scan() {
lines = append(lines, strings.TrimSpace(scanner.Text()))
}
return lines, nil
}
func (m *Model) SetIgnores(repo string, content []string) error {
cfg, ok := m.repoCfgs[repo]
if !ok {
return fmt.Errorf("Repo %s does not exist", repo)
}
fd, err := ioutil.TempFile("", "stignore-"+repo)
if err != nil {
l.Warnln("Saving .stignore:", err)
return err
}
writer := bufio.NewWriter(fd)
for _, line := range content {
fmt.Fprintln(writer, line)
}
err = writer.Flush()
if err != nil {
l.Warnln("Saving .stignore:", err)
fd.Close()
return err
}
err = fd.Close()
if err != nil {
l.Warnln("Saving .stignore:", err)
return err
}
file := filepath.Join(cfg.Directory, ".stignore")
m.rmut.Lock()
os.Remove(file)
err = osutil.Rename(fd.Name(), file)
m.rmut.Unlock()
if err != nil {
l.Warnln("Saving .stignore:", err)
return err
}
return m.ScanRepo(repo)
}
// AddConnection adds a new peer connection to the model. An initial index will
// be sent to the connected peer, thereafter index updates whenever the local
// repository changes.
+86
View File
@@ -369,3 +369,89 @@ func TestClusterConfig(t *testing.T) {
t.Errorf("Incorrect node ID %x != %x", id, node2)
}
}
func TestIgnores(t *testing.T) {
arrEqual := func(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
db, _ := leveldb.Open(storage.NewMemStorage(), nil)
m := NewModel("/tmp", nil, "node", "syncthing", "dev", db)
m.AddRepo(config.RepositoryConfiguration{ID: "default", Directory: "testdata"})
expected := []string{
".*",
"quux",
}
ignores, err := m.GetIgnores("default")
if err != nil {
t.Error(err)
}
if !arrEqual(ignores, expected) {
t.Errorf("Incorrect ignores: %v != %v", ignores, expected)
}
ignores = append(ignores, "pox")
err = m.SetIgnores("default", ignores)
if err != nil {
t.Error(err)
}
ignores2, err := m.GetIgnores("default")
if err != nil {
t.Error(err)
}
if arrEqual(expected, ignores2) {
t.Errorf("Incorrect ignores: %v == %v", ignores2, expected)
}
if !arrEqual(ignores, ignores2) {
t.Errorf("Incorrect ignores: %v != %v", ignores2, ignores)
}
err = m.SetIgnores("default", expected)
if err != nil {
t.Error(err)
}
ignores, err = m.GetIgnores("default")
if err != nil {
t.Error(err)
}
if !arrEqual(ignores, expected) {
t.Errorf("Incorrect ignores: %v != %v", ignores, expected)
}
ignores, err = m.GetIgnores("doesnotexist")
if err == nil {
t.Error("No error")
}
err = m.SetIgnores("doesnotexist", expected)
if err == nil {
t.Error("No error")
}
m.AddRepo(config.RepositoryConfiguration{ID: "fresh", Directory: "XXX"})
ignores, err = m.GetIgnores("fresh")
if err != nil {
t.Error(err)
}
if len(ignores) > 0 {
t.Errorf("Expected no ignores, got: %v", ignores)
}
}