lyp 0.0.5 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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