learn-open 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9b1416ac2cc4269301b050a0cadf8cde655a72d3
4
+ data.tar.gz: 64abe5d3070fcc33cdc1d118b8123bd166eda402
5
+ SHA512:
6
+ metadata.gz: 19374d28e259f3aef1ee701e8dd3d3df8a1e58c09638af93c71fd223ce10694ff363aab58c541b063aab463d91d8cf3ff8855ea26869da56e0edbab4867f1971
7
+ data.tar.gz: 76f77515c889ea771a953b91daa7a23742893219a2ef8942034be0c13a27c403aadaf39dd5204bd21d6849ad3aab56554d0201879cb18e828dd0a0a8728491a2
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in learn-open.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Flatiron School
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # learn-open
2
+
3
+ Open Learn lessons locally
4
+
5
+ ## Installation
6
+
7
+ Install with:
8
+
9
+ ```
10
+ $ gem install learn-open
11
+ ```
12
+
13
+ Alternatively, add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'learn-open'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ ## Usage
24
+
25
+ Run:
26
+
27
+ ```
28
+ $ learn-open lesson-name [--editor=editor-binary]
29
+ ```
30
+
31
+ ## Contributing
32
+
33
+ 1. Fork it ( https://github.com/flatiron-labs/learn-open/fork )
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
36
+ 4. Push to the branch (`git push origin my-new-feature`)
37
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/learn-open ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'learn_open'
4
+
5
+ lesson, editor_specified = LearnOpen::ArgumentParser.new(ARGV).execute
6
+
7
+ LearnOpen::Opener.run(lesson: lesson, editor_specified: editor_specified)
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'learn_open/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "learn-open"
8
+ spec.version = LearnOpen::VERSION
9
+ spec.authors = ["Flatiron School"]
10
+ spec.email = ["learn@flatironschool.com"]
11
+ spec.summary = %q{Open Learn lessons locally}
12
+ spec.homepage = "https://learn.co"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib", "bin"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+
23
+ spec.add_runtime_dependency "netrc"
24
+ spec.add_runtime_dependency "git"
25
+ spec.add_runtime_dependency "learn-web", ">= 1.0.0"
26
+ end
@@ -0,0 +1,29 @@
1
+ module LearnOpen
2
+ class ArgumentParser
3
+ attr_reader :args
4
+
5
+ def initialize(args)
6
+ @args = args
7
+ end
8
+
9
+ def execute
10
+ config_path = File.expand_path('~/.learn-config')
11
+ editor_data = YAML.load(File.read(config_path))[:editor]
12
+ lesson = nil
13
+
14
+ configured_editor = !(editor_data.empty? || editor_data.nil?) ? editor_data : nil
15
+ editor_specified = ARGV.detect {|arg| arg.start_with?('--editor=')}.match(/\-\-editor=(.+)/) || configured_editor
16
+ open_after = !!editor_specified
17
+
18
+ if !ARGV[0].start_with?('--editor=')
19
+ lesson = ARGV[0]
20
+ end
21
+
22
+ if open_after
23
+ editor_specified = editor_specified.is_a?(String) ? editor_specified : editor_specified[1]
24
+ end
25
+
26
+ [lesson, editor_specified]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,234 @@
1
+ module LearnOpen
2
+ class Opener
3
+ attr_reader :editor, :client, :lessons_dir
4
+ attr_accessor :lesson, :repo_dir, :lesson_is_lab, :lesson_id
5
+
6
+ def self.run(lesson:, editor_specified:)
7
+ new(lesson, editor_specified).run
8
+ end
9
+
10
+ def initialize(lesson, editor)
11
+ _login, token = Netrc.read['learn-config']
12
+ @client = LearnWeb::Client.new(token: token)
13
+
14
+ @lesson = lesson
15
+ @editor = editor
16
+ @lessons_dir = YAML.load(File.read(File.expand_path('~/.learn-config')))[:learn_directory]
17
+ end
18
+
19
+ def run
20
+ set_lesson
21
+
22
+ if lesson_is_readme?
23
+ open_readme
24
+ else
25
+ fork_repo
26
+ clone_repo
27
+ open_with_editor
28
+ cd_to_lesson
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def set_lesson
35
+ if !lesson
36
+ puts "Getting current lesson..."
37
+ self.lesson = get_current_lesson_forked_repo
38
+ self.lesson_is_lab = current_lesson.lab
39
+ self.lesson_id = current_lesson.id
40
+ else
41
+ puts "Looking for lesson..."
42
+ self.lesson = ensure_correct_lesson.repo_slug
43
+ self.lesson_is_lab = correct_lesson.lab
44
+ self.lesson_id = correct_lesson.lesson_id
45
+ end
46
+
47
+ self.repo_dir = lesson.split('/').last
48
+ end
49
+
50
+ def current_lesson
51
+ @current_lesson ||= client.current_lesson
52
+ end
53
+
54
+ def get_current_lesson_forked_repo(retries=3)
55
+ begin
56
+ Timeout::timeout(15) do
57
+ current_lesson.forked_repo
58
+ end
59
+ rescue Timeout::Error
60
+ if retries > 0
61
+ puts "There was a problem getting your lesson from Learn. Retrying..."
62
+ get_current_lesson_forked_repo(retries-1)
63
+ else
64
+ puts "There seems to be a problem connecting to Learn. Please try again."
65
+ exit
66
+ end
67
+ end
68
+ end
69
+
70
+ def ensure_correct_lesson
71
+ correct_lesson
72
+ end
73
+
74
+ def correct_lesson(retries=3)
75
+ @correct_lesson ||= begin
76
+ Timeout::timeout(15) do
77
+ client.validate_repo_slug(repo_slug: lesson)
78
+ end
79
+ rescue Timeout::Error
80
+ if retries > 0
81
+ puts "There was a problem connecting to Learn. Retrying..."
82
+ correct_lesson(retries-1)
83
+ else
84
+ puts "Cannot connect to Learn right now. Please try again."
85
+ exit
86
+ end
87
+ end
88
+ end
89
+
90
+ def fork_repo(retries=3)
91
+ if !repo_exists?
92
+ puts "Forking lesson..."
93
+ begin
94
+ Timeout::timeout(15) do
95
+ client.fork_repo(repo_name: repo_dir)
96
+ end
97
+ rescue Timeout::Error
98
+ if retries > 0
99
+ puts "There was a problem forking this lesson. Retrying..."
100
+ fork_repo(retries-1)
101
+ else
102
+ puts "There is an issue connecting to Learn. Please try again."
103
+ exit
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ def clone_repo(retries=3)
110
+ if !repo_exists?
111
+ puts "Cloning lesson..."
112
+ begin
113
+ Timeout::timeout(15) do
114
+ Git.clone("git@github.com:#{lesson}.git", repo_dir, path: lessons_dir)
115
+ end
116
+ rescue Timeout::Error
117
+ if retries > 0
118
+ puts "There was a problem cloning this lesson. Retrying..."
119
+ clone_repo(retries-1)
120
+ else
121
+ puts "Cannot clone this lesson right now. Please try again."
122
+ exit
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ def repo_exists?
129
+ File.exists?("#{lessons_dir}/#{repo_dir}")
130
+ end
131
+
132
+ def open_with_editor
133
+ if ios_lesson?
134
+ open_ios_lesson
135
+ elsif editor
136
+ system("cd #{lessons_dir}/#{repo_dir} && #{editor} .")
137
+ end
138
+ end
139
+
140
+ def ios_lesson?
141
+ languages = YAML.load(File.read("#{lessons_dir}/#{repo_dir}/.learn"))['languages']
142
+ ios_lang = languages.any? {|l| ['objc', 'swift'].include?(l)}
143
+
144
+ ios_lang || xcodeproj_file? || xcworkspace_file?
145
+ end
146
+
147
+ def open_ios_lesson
148
+ if can_open_ios_lesson?
149
+ open_xcode
150
+ else
151
+ puts "You need to be on a Mac to work on iOS lessons."
152
+ exit
153
+ end
154
+ end
155
+
156
+ def can_open_ios_lesson?
157
+ on_mac?
158
+ end
159
+
160
+ def open_xcode
161
+ if xcworkspace_file?
162
+ system("cd #{lessons_dir}/#{repo_dir} && open *.xcworkspace")
163
+ elsif xcodeproj_file?
164
+ system("cd #{lessons_dir}/#{repo_dir} && open *.xcodeproj")
165
+ end
166
+ end
167
+
168
+ def xcodeproj_file?
169
+ Dir.glob("#{lessons_dir}/#{repo_dir}/*.xcodeproj").any?
170
+ end
171
+
172
+ def xcworkspace_file?
173
+ Dir.glob("#{lessons_dir}/#{repo_dir}/*.xcworkspace").any?
174
+ end
175
+
176
+ def cd_to_lesson
177
+ puts "Opening lesson..."
178
+ Dir.chdir("#{lessons_dir}/#{repo_dir}")
179
+ bundle_install
180
+ puts "Done."
181
+ exec(ENV['SHELL'])
182
+ end
183
+
184
+ def bundle_install
185
+ # TODO: Don't bundle for other types of labs either
186
+ if !ios_lesson?
187
+ puts "Bundling..."
188
+ system("bundle install &>/dev/null")
189
+ end
190
+ end
191
+
192
+ def lesson_is_readme?
193
+ !lesson_is_lab
194
+ end
195
+
196
+ def open_readme
197
+ if can_open_readme?
198
+ puts "Opening readme..."
199
+ launch_browser
200
+ else
201
+ puts "You need to be running this on a Mac to open a Readme from the command line."
202
+ exit
203
+ end
204
+ end
205
+
206
+ def launch_browser
207
+ if chrome_installed?
208
+ open_chrome
209
+ else
210
+ open_safari
211
+ end
212
+ end
213
+
214
+ def chrome_installed?
215
+ File.exists?('/Applications/Google Chrome.app')
216
+ end
217
+
218
+ def open_chrome
219
+ system("open -a 'Google Chrome' https://learn.co/lessons/#{lesson_id}")
220
+ end
221
+
222
+ def open_safari
223
+ system("open -a Safari https://learn.co/lessons/#{lesson_id}")
224
+ end
225
+
226
+ def can_open_readme?
227
+ on_mac?
228
+ end
229
+
230
+ def on_mac?
231
+ !!RUBY_PLATFORM.match(/darwin/)
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,3 @@
1
+ module LearnOpen
2
+ VERSION = '1.0.0'
3
+ end
data/lib/learn_open.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'yaml'
2
+ require 'netrc'
3
+ require 'git'
4
+ require 'learn_web'
5
+ require 'timeout'
6
+
7
+ require 'learn_open/version'
8
+ require 'learn_open/opener'
9
+ require 'learn_open/argument_parser'
10
+
11
+ module LearnOpen
12
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: learn-open
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Flatiron School
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: netrc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: git
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: learn-web
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 1.0.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.0.0
83
+ description:
84
+ email:
85
+ - learn@flatironschool.com
86
+ executables:
87
+ - learn-open
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - bin/learn-open
97
+ - learn-open.gemspec
98
+ - lib/learn_open.rb
99
+ - lib/learn_open/argument_parser.rb
100
+ - lib/learn_open/opener.rb
101
+ - lib/learn_open/version.rb
102
+ homepage: https://learn.co
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ - bin
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.4.5
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Open Learn lessons locally
127
+ test_files: []