lyp 0.0.5 → 0.1.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.
data/lib/lyp.rb CHANGED
@@ -1,5 +1,23 @@
1
+ # test for existence of
2
+ $rugged_available = begin
3
+ gem 'rugged', '>=0.23.0'
4
+ require 'rugged'
5
+ rescue Exception
6
+ nil
7
+ end
8
+
9
+ $git_available = `git --version` rescue nil
10
+
11
+ unless $rugged_available || $git_available
12
+ raise "Lyp needs git in order to be able to install packages. Please install git and then try again."
13
+ end
14
+
15
+ unless $rugged_available
16
+ require 'lyp/git_based_rugged'
17
+ end
18
+
1
19
  %w{
2
- directories
20
+ base
3
21
  system
4
22
  settings
5
23
 
@@ -12,3 +30,4 @@
12
30
  }.each do |f|
13
31
  require File.expand_path("lyp/#{f}", File.dirname(__FILE__))
14
32
  end
33
+
@@ -3,8 +3,11 @@ require 'fileutils'
3
3
  module Lyp
4
4
  # A package specifier is of the form <package>@<version specifier>, where
5
5
  # the version specifier can be simply a version number, or include an operator
6
- # before the version number. Accepted operators: >=, ~>
7
- PACKAGE_RE = /^([^@]+)(?:@(.+))?$/
6
+ # before the version number.
7
+ #
8
+ # Accepted operators: >=, ~>
9
+ PACKAGE_RE = /^([^@\>~]+)(?:@?((?:\>=|~\>)?.+))?/ #/^([^@]+)(?:@(.+))?$/
10
+ LILYPOND_RE = /^lilypond(?:@?((?:\>=|~\>)?.+))?/
8
11
 
9
12
  LYP_DIRECTORY = File.expand_path('~/.lyp')
10
13
  LYP_BIN_DIRECTORY = File.join(LYP_DIRECTORY, 'bin')
data/lib/lyp/cli.rb CHANGED
@@ -51,7 +51,7 @@ class Lyp::CLI < Thor
51
51
  end
52
52
 
53
53
  desc "search [PATTERN|lilypond]", "List available packages matching PATTERN or versions of lilypond"
54
- def search(pattern)
54
+ def search(pattern = '')
55
55
  # Lyp::System.test_installed_status!
56
56
 
57
57
  pattern =~ Lyp::PACKAGE_RE
@@ -85,7 +85,7 @@ class Lyp::CLI < Thor
85
85
  if packages.empty?
86
86
  puts "\nNo matching package found in lyp-index\n\n"
87
87
  else
88
- puts "\nAvailable packages:\n\n"
88
+ puts "\nAvailable packages on lyp-index:\n\n"
89
89
  packages.each do |p|
90
90
  puts " #{p[:name]}"
91
91
  end
@@ -111,7 +111,7 @@ class Lyp::CLI < Thor
111
111
  case package
112
112
  when 'self'
113
113
  Lyp::System.install!
114
- when /^lilypond(?:@(.+))?$/
114
+ when Lyp::LILYPOND_RE
115
115
  Lyp::System.test_installed_status!
116
116
  Lyp::Lilypond.install($1, options)
117
117
  else
@@ -130,7 +130,7 @@ class Lyp::CLI < Thor
130
130
  case package
131
131
  when 'self'
132
132
  Lyp::System.uninstall!
133
- when /^lilypond(?:@(.+))?$/
133
+ when Lyp::LILYPOND_RE
134
134
  Lyp::System.test_installed_status!
135
135
  Lyp::Lilypond.uninstall($1)
136
136
  else
@@ -145,7 +145,7 @@ class Lyp::CLI < Thor
145
145
  def use(version)
146
146
  Lyp::System.test_installed_status!
147
147
 
148
- if version =~ /^lilypond@(.+)$/
148
+ if version =~ Lyp::LILYPOND_RE
149
149
  version = $1
150
150
  end
151
151
 
@@ -162,7 +162,24 @@ class Lyp::CLI < Thor
162
162
  Lyp::Lilypond.list.each {|info| puts format_lilypond_entry(info)}
163
163
  STDOUT.puts LILYPOND_LEGEND
164
164
  else
165
- Lyp::Package.list(args.first).each {|p| puts p}
165
+ list = Lyp::Package.list(args.first)
166
+ if list.empty?
167
+ if args.first
168
+ return puts "\nNo installed packages found matching '#{args.first}'\n\n"
169
+ else
170
+ return puts "\nNo packages are currently installed\n\n"
171
+ end
172
+ end
173
+
174
+ by_package = list.inject({}) do |m, p|
175
+ p =~ Lyp::PACKAGE_RE; (m[$1] ||= []) << $2; m
176
+ end
177
+
178
+ puts "\nInstalled packages:\n\n"
179
+ by_package.keys.sort.each do |p|
180
+ puts " #{p} => (#{by_package[p].sort.join(', ')})"
181
+ end
182
+ puts "\n\n"
166
183
  end
167
184
  end
168
185
 
@@ -177,6 +194,35 @@ class Lyp::CLI < Thor
177
194
  end
178
195
  end
179
196
 
197
+ desc "deps FILE", "Lists dependencies found in user's files"
198
+ def deps(fn)
199
+ resolver = Lyp::Resolver.new(fn)
200
+ tree = resolver.get_dependency_tree(ignore_missing: true)
201
+ tree[:dependencies].each do |package, leaf|
202
+ versions = leaf[:versions].keys.map {|k| k =~ Lyp::PACKAGE_RE; $2 }.sort
203
+ if versions.empty?
204
+ puts " #{leaf[:clause]} => (no local version found)"
205
+ else
206
+ puts " #{leaf[:clause]} => #{versions.join(', ')}"
207
+ end
208
+ end
209
+ end
210
+
211
+ desc "resolve FILE", "Resolves and installs missing dependencies found in user's files"
212
+ method_option :all, aliases: '-a', type: :boolean, desc: 'Install all found dependencies'
213
+ def resolve(fn)
214
+ resolver = Lyp::Resolver.new(fn)
215
+ tree = resolver.get_dependency_tree(ignore_missing: true)
216
+ tree[:dependencies].each do |package, leaf|
217
+ if options[:all] || leaf[:versions].empty?
218
+ Lyp::Package.install(leaf[:clause])
219
+ end
220
+ end
221
+ end
180
222
  end
181
223
 
182
- Lyp::CLI.start(ARGV)
224
+ begin
225
+ Lyp::CLI.start(ARGV)
226
+ rescue => e
227
+ puts e.message
228
+ end
@@ -0,0 +1,38 @@
1
+ # A quick-n-dirty rugged swap-in
2
+
3
+ puts "git_based_rugged"
4
+
5
+ module Rugged
6
+ class Repository
7
+ def self.clone_at(url, path)
8
+ `git clone -q \"#{url}\" \"#{path}\"`
9
+ new(path)
10
+ end
11
+
12
+ def initialize(path)
13
+ @path = path
14
+ exec('status')
15
+ end
16
+
17
+ Ref = Struct.new(:name)
18
+
19
+ def head
20
+ h = exec("show-ref --head").lines.map {|r| r =~ /^(\S+)\sHEAD$/ && $1}[0]
21
+ Ref.new(h)
22
+ end
23
+
24
+
25
+ def checkout(ref, opts)
26
+ # strategy: :force
27
+ exec("checkout -qf #{ref}")
28
+ end
29
+
30
+ def tags
31
+ exec("tag").lines.map {|l| Ref.new(l.chomp)}
32
+ end
33
+
34
+ def exec(cmd)
35
+ `cd #{@path} && git #{cmd}`
36
+ end
37
+ end
38
+ end
data/lib/lyp/package.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'fileutils'
2
- require 'rugged'
3
2
  require 'open-uri'
4
3
  require 'yaml'
5
4
 
@@ -7,12 +6,12 @@ module Lyp::Package
7
6
  class << self
8
7
 
9
8
  def list(pattern = nil)
10
- packages = Dir["#{Lyp.packages_dir}/*"].map do |p|
11
- File.basename(p)
9
+ packages = Dir["#{Lyp.packages_dir}/**/package.ly"].map do |path|
10
+ File.dirname(path).gsub("#{Lyp.packages_dir}/", '')
12
11
  end
13
12
 
14
13
  if pattern
15
- if (pattern =~ /@/) && (pattern =~ Lyp::PACKAGE_RE)
14
+ if (pattern =~ /[@\>\<\=\~]/) && (pattern =~ Lyp::PACKAGE_RE)
16
15
  package, version = $1, $2
17
16
  req = Gem::Requirement.new(version) rescue nil
18
17
  packages.select! do |p|
@@ -60,6 +59,51 @@ module Lyp::Package
60
59
  end
61
60
  package, version = $1, $2
62
61
 
62
+ if version =~ /\:/
63
+ info = install_from_local_files(package, version, opts)
64
+ else
65
+ info = install_from_repository(package, version, opts)
66
+ end
67
+
68
+ install_package_dependencies(info[:path], opts)
69
+
70
+ puts "\nInstalled #{package}@#{info[:version]}\n\n" unless opts[:silent]
71
+
72
+ # important: return the installed version
73
+ info[:version]
74
+ end
75
+
76
+ def install_from_local_files(package, version, opts)
77
+ version =~ /^([^\:]+)\:(.+)$/
78
+ version, local_path = $1, $2
79
+
80
+ entry_point_path = nil
81
+ if File.directory?(local_path)
82
+ ly_path = File.join(local_path, "package.ly")
83
+ if File.file?(ly_path)
84
+ entry_point_path = ly_path
85
+ else
86
+ raise "Could not find #{ly_path}. Please specify a valid lilypond file."
87
+ end
88
+ elsif File.file?(local_path)
89
+ entry_point_path = local_path
90
+ else
91
+ raise "Could not find #{local_path}"
92
+ end
93
+
94
+ package_path = "#{Lyp.packages_dir}/#{package}@#{version}"
95
+ package_ly_path = "#{package_path}/package.ly"
96
+
97
+ FileUtils.rm_rf(package_path)
98
+ FileUtils.mkdir_p(package_path)
99
+ File.open(package_ly_path, 'w+') do |f|
100
+ f << "\\include \"#{entry_point_path}\"\n"
101
+ end
102
+
103
+ {version: version, path: package_path}
104
+ end
105
+
106
+ def install_from_repository(package, version, opts)
63
107
  url = package_git_url(package)
64
108
  tmp_path = git_url_to_temp_path(url)
65
109
 
@@ -75,25 +119,30 @@ module Lyp::Package
75
119
  FileUtils.rm_rf(package_path)
76
120
  FileUtils.cp_r(tmp_path, package_path)
77
121
 
78
- install_package_dependencies(package_path, opts)
79
-
80
- puts "\nInstalled #{package}@#{version}\n\n" unless opts[:silent]
81
-
82
- # return the installed version
83
- version
122
+ {version: version, path: package_path}
84
123
  end
85
124
 
86
125
  def uninstall(package, opts = {})
126
+ unless package =~ Lyp::PACKAGE_RE
127
+ raise "Invalid package specifier #{package}"
128
+ end
129
+ package, version = $1, $2
130
+ package_path = git_url_to_package_path(
131
+ package !~ /\// ? package : package_git_url(package), nil
132
+ )
133
+
87
134
  if opts[:all_versions]
88
- Dir["#{Lyp.packages_dir}/#{package}@*"].each do |path|
89
- puts "Uninstalling #{File.basename(path)}" unless opts[:silent]
135
+ Dir["#{package_path}@*"].each do |path|
136
+ name = path.gsub("#{Lyp.packages_dir}/", '')
137
+ puts "Uninstalling #{name}" unless opts[:silent]
90
138
  FileUtils.rm_rf(path)
91
139
  end
92
140
  else
93
- path = "#{Lyp.packages_dir}/#{package}"
94
- if File.directory?(path)
95
- puts "Uninstalling #{package}" unless opts[:silent]
96
- FileUtils.rm_rf(path)
141
+ package_path += "@#{version}"
142
+ if File.directory?(package_path)
143
+ name = package_path.gsub("#{Lyp.packages_dir}/", '')
144
+ puts "Uninstalling #{name}" unless opts[:silent]
145
+ FileUtils.rm_rf(package_path)
97
146
  else
98
147
  raise "Could not find #{package}"
99
148
  end
@@ -103,14 +152,21 @@ module Lyp::Package
103
152
  def package_repository(url, tmp_path, opts = {})
104
153
  # Create repository
105
154
  if File.directory?(tmp_path)
106
- repo = Rugged::Repository.new(tmp_path)
107
- repo.fetch('origin', [repo.head.name])
108
- else
109
- FileUtils.mkdir_p(File.dirname(tmp_path))
110
- puts "Cloning #{url}..." unless opts[:silent]
111
- repo = Rugged::Repository.clone_at(url, tmp_path)
155
+ begin
156
+ repo = Rugged::Repository.new(tmp_path)
157
+ repo.fetch('origin', [repo.head.name])
158
+ return repo
159
+ rescue
160
+ # ignore and try to clone
161
+ end
112
162
  end
113
- repo
163
+
164
+ FileUtils.rm_rf(File.dirname(tmp_path))
165
+ FileUtils.mkdir_p(File.dirname(tmp_path))
166
+ puts "Cloning #{url}..." unless opts[:silent]
167
+ Rugged::Repository.clone_at(url, tmp_path)
168
+ rescue => e
169
+ raise "Could not clone repository (please check that the package URL is correct.)"
114
170
  end
115
171
 
116
172
  def checkout_package_version(repo, version, opts = {})
@@ -155,7 +211,7 @@ module Lyp::Package
155
211
  if search_index && (url = search_lyp_index(package))
156
212
  package_git_url(url, false) # make sure url is qualified
157
213
  else
158
- raise "Invalid package specified"
214
+ raise "Could not find package '#{package}' in lyp-index"
159
215
  end
160
216
  end
161
217
  end
@@ -199,22 +255,25 @@ module Lyp::Package
199
255
  end
200
256
 
201
257
  def git_url_to_package_path(url, version)
202
- version = 'head' if version.nil? || (version == '')
258
+ # version = 'head' if version.nil? || (version == '')
203
259
 
204
- case url
260
+ package_path = case url
205
261
  when /^(?:http|https)\:(?:\/\/)?(.+)$/
206
262
  path = $1.gsub(/\.git$/, '')
207
- "#{Lyp::packages_dir}/#{path}@#{version}"
263
+ "#{Lyp::packages_dir}/#{path}"
208
264
  when /^(?:.+@)([^\:]+)\:(?:\/\/)?(.+)$/
209
265
  domain, path = $1, $2.gsub(/\.git$/, '')
210
- "#{Lyp::packages_dir}/#{domain}/#{path}@#{version}"
266
+ "#{Lyp::packages_dir}/#{domain}/#{path}"
211
267
  else
212
268
  if url !~ /\//
213
- "#{Lyp::packages_dir}/#{url}@#{version}"
269
+ "#{Lyp::packages_dir}/#{url}"
214
270
  else
215
271
  raise "Invalid URL #{url}"
216
272
  end
217
273
  end
274
+
275
+ package_path += "@#{version}" if version
276
+ package_path
218
277
  end
219
278
 
220
279
  TAG_VERSION_RE = /^v?(\d.*)$/
@@ -249,7 +308,7 @@ module Lyp::Package
249
308
  repo.tags.each {|t| tags << t}
250
309
 
251
310
  tags.sort do |x, y|
252
- x_version, y_version = tag_version(x), tag_version(y)
311
+ x_version, y_version = tag_version(x.name), tag_version(y.name)
253
312
  if x_version && y_version
254
313
  Gem::Version.new(x_version) <=> Gem::Version.new(y_version)
255
314
  else
data/lib/lyp/resolver.rb CHANGED
@@ -385,6 +385,7 @@ class Lyp::Resolver
385
385
 
386
386
  # Sort permutations by version numbers
387
387
  def sort_permutations(permutations, user_deps)
388
+ # Cache for versions converted to Gem::Version instances
388
389
  versions = {}
389
390
 
390
391
  map = lambda do |m, p|
@@ -398,7 +399,8 @@ class Lyp::Resolver
398
399
  x_versions = x.inject({}, &map)
399
400
  y_versions = y.inject({}, &map)
400
401
 
401
- # Naive implementation - add up the comparison scores for each package
402
+ # If the dependency is direct (not transitive), just compare its versions.
403
+ # Otherwise, add the result of comparison to score.
402
404
  x_versions.inject(0) do |score, kv|
403
405
  package = kv[0]
404
406
  cmp = kv[1] <=> y_versions[package]
data/lib/lyp/system.rb CHANGED
@@ -4,21 +4,20 @@ module Lyp::System
4
4
  class << self
5
5
  INSTALL_MSG = <<EOF
6
6
 
7
- lyp is not yet properly installed in your home directory.
7
+ Warning! Lyp is not yet properly installed in your home directory.
8
8
 
9
9
  To install lyp run 'lyp install self'. lyp will then:
10
10
  1. Setup ~/.lyp as its base directory.
11
- 2. Add ~/.lyp/bin to $PATH.
11
+ 2. Add the lyp and lilypond scripts to ~/.lyp/bin.
12
+ 3. Add ~/.lyp/bin to front of $PATH.
12
13
 
13
14
  You can uninstall lyp at any time by running 'lyp uninstall self'.
14
15
 
15
16
  EOF
16
17
 
17
18
  def test_installed_status!
18
- return
19
19
  unless installed?
20
20
  puts INSTALL_MSG
21
- exit 1
22
21
  end
23
22
  end
24
23
 
data/lib/lyp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Lyp
2
- VERSION = "0.0.5"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lyp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-11 00:00:00.000000000 Z
11
+ date: 2016-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: highline
@@ -71,65 +71,53 @@ dependencies:
71
71
  - !ruby/object:Gem::Version
72
72
  version: 0.19.1
73
73
  - !ruby/object:Gem::Dependency
74
- name: nokogiri
74
+ name: httpclient
75
75
  requirement: !ruby/object:Gem::Requirement
76
76
  requirements:
77
77
  - - "~>"
78
78
  - !ruby/object:Gem::Version
79
- version: '1.6'
79
+ version: '2.7'
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 1.6.7
82
+ version: 2.7.1
83
83
  type: :runtime
84
84
  prerelease: false
85
85
  version_requirements: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '1.6'
89
+ version: '2.7'
90
90
  - - ">="
91
91
  - !ruby/object:Gem::Version
92
- version: 1.6.7
92
+ version: 2.7.1
93
93
  - !ruby/object:Gem::Dependency
94
- name: httpclient
94
+ name: nokogiri
95
95
  requirement: !ruby/object:Gem::Requirement
96
96
  requirements:
97
- - - "~>"
98
- - !ruby/object:Gem::Version
99
- version: '2.7'
100
- - - ">="
97
+ - - '='
101
98
  - !ruby/object:Gem::Version
102
- version: 2.7.1
99
+ version: 1.6.6.2
103
100
  type: :runtime
104
101
  prerelease: false
105
102
  version_requirements: !ruby/object:Gem::Requirement
106
103
  requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: '2.7'
110
- - - ">="
104
+ - - '='
111
105
  - !ruby/object:Gem::Version
112
- version: 2.7.1
106
+ version: 1.6.6.2
113
107
  - !ruby/object:Gem::Dependency
114
108
  name: rugged
115
109
  requirement: !ruby/object:Gem::Requirement
116
110
  requirements:
117
- - - "~>"
118
- - !ruby/object:Gem::Version
119
- version: '0.23'
120
- - - ">="
111
+ - - '='
121
112
  - !ruby/object:Gem::Version
122
- version: 0.23.3
113
+ version: 0.23.0
123
114
  type: :runtime
124
115
  prerelease: false
125
116
  version_requirements: !ruby/object:Gem::Requirement
126
117
  requirements:
127
- - - "~>"
128
- - !ruby/object:Gem::Version
129
- version: '0.23'
130
- - - ">="
118
+ - - '='
131
119
  - !ruby/object:Gem::Version
132
- version: 0.23.3
120
+ version: 0.23.0
133
121
  description: Lyp is a tool for managing lilypond versions and lilypond packages
134
122
  email: ciconia@gmail.com
135
123
  executables:
@@ -140,11 +128,13 @@ extra_rdoc_files: []
140
128
  files:
141
129
  - LICENSE
142
130
  - README.md
131
+ - bin/get.sh
143
132
  - bin/lilypond
144
133
  - bin/lyp
145
134
  - lib/lyp.rb
135
+ - lib/lyp/base.rb
146
136
  - lib/lyp/cli.rb
147
- - lib/lyp/directories.rb
137
+ - lib/lyp/git_based_rugged.rb
148
138
  - lib/lyp/lilypond.rb
149
139
  - lib/lyp/package.rb
150
140
  - lib/lyp/resolver.rb