import_js 0.3.1 → 0.4.0

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
2
  SHA1:
3
- metadata.gz: c90724e922f7ebecab12977097f1b867d83d8f74
4
- data.tar.gz: 43cc4828550165c17ca8b07b142c5e033fbbb31f
3
+ metadata.gz: a2a0036427b0f66373fcbc6fda702570d501f281
4
+ data.tar.gz: 9c798047e26eb9189e169c5395ed1bd41b03e2fc
5
5
  SHA512:
6
- metadata.gz: c6f3b02306c7c21ccc09b13e7246d2c8ddb7c78f05f149d2644b73d1ce8d731d4349e54f68d52bc79b1558d07aa94aba5fe7a809f9f4137410f9cfccd0d4225e
7
- data.tar.gz: 105ab5859eaef7bd8d3bd5b31a0725c4000cf833743a786c7d6a1e9a5bac21bcbdc2de79580c565f74fde07a58f4467b004709031695a892d3468d4cc9304b2d
6
+ metadata.gz: 4eaed3ab7c8204e62a7b19bdad9cf002384f6797cd15fe6f6615763ebcda6f8cf607cbb3127f8c494082a53f84684c17e383544f897cd368ae0074101676dc5d
7
+ data.tar.gz: 43c8abdad3178c4df5c6f04a7030737daa9d2cb4e83cb777e6dbde088a5a43dffa2690ae13e1b1950ce915dc01f5252a75d4747883a9d0777124cf7353541e64
data/bin/import-js CHANGED
@@ -9,7 +9,7 @@ opts = Slop.parse do |o|
9
9
  o.bool '--goto', 'instead of importing, just print the path to a module'
10
10
  o.array '--selections', 'a list of resolved selections, e.g. Foo:0,Bar:1'
11
11
  o.string '--filename',
12
- 'a path to the file which contents are being passed in as stdin'
12
+ 'a path to the file which contents are being passed in as stdin'
13
13
  o.on '-v', '--version', 'print the current version' do
14
14
  puts ImportJS::VERSION
15
15
  exit
@@ -50,7 +50,7 @@ end
50
50
 
51
51
  # Print messages to stderr
52
52
  meta = {
53
- messages: editor.messages
53
+ messages: editor.messages,
54
54
  }
55
55
  ask = editor.ask_for_selections
56
56
  meta[:ask_for_selections] = ask unless ask.empty?
@@ -1,4 +1,5 @@
1
1
  module ImportJS
2
+ # This is the implementation of command line integration in Import-JS.
2
3
  class CommandLineEditor
3
4
  def initialize(lines, opts)
4
5
  @lines = lines
@@ -24,20 +25,14 @@ module ImportJS
24
25
  @goto = file_path
25
26
  end
26
27
 
27
- # @return [String]
28
- def goto
29
- @goto
30
- end
28
+ attr_reader :goto
31
29
 
32
30
  # @param str [String]
33
31
  def message(str)
34
32
  @messages << str
35
33
  end
36
34
 
37
- # @return [Array]
38
- def ask_for_selections
39
- @ask_for_selections
40
- end
35
+ attr_reader :ask_for_selections
41
36
 
42
37
  # @return [String]
43
38
  def current_file_content
@@ -110,7 +105,7 @@ module ImportJS
110
105
  else
111
106
  @ask_for_selections << {
112
107
  word: word,
113
- alternatives: alternatives
108
+ alternatives: alternatives,
114
109
  }
115
110
  nil
116
111
  end
@@ -1,42 +1,55 @@
1
+ # frozen_string_literal: true
1
2
  require 'json'
2
3
  require 'open3'
3
4
 
4
5
  module ImportJS
5
- CONFIG_FILE = '.importjs.json'
6
+ CONFIG_FILE = '.importjs.json'.freeze
6
7
 
7
8
  DEFAULT_CONFIG = {
8
9
  'aliases' => {},
9
10
  'declaration_keyword' => 'import',
11
+ 'named_exports' => {},
10
12
  'eslint_executable' => 'eslint',
11
13
  'excludes' => [],
12
14
  'ignore_package_prefixes' => [],
15
+ 'import_dev_dependencies' => false,
16
+ 'import_function' => 'require',
13
17
  'lookup_paths' => ['.'],
18
+ 'minimum_version' => '0.0.0',
14
19
  'strip_file_extensions' => ['.js', '.jsx'],
15
- 'use_relative_paths' => false
16
- }
20
+ 'strip_from_path' => nil,
21
+ 'use_relative_paths' => false,
22
+ }.freeze
17
23
 
18
24
  # Class that initializes configuration from a .importjs.json file
19
25
  class Configuration
20
- def initialize
21
- @config = DEFAULT_CONFIG.merge(load_config)
22
- end
26
+ def initialize(path_to_current_file)
27
+ @path_to_current_file = normalize_path(path_to_current_file)
28
+ @configs = []
29
+ user_config = load_config(CONFIG_FILE)
30
+ @configs.concat([user_config].flatten.reverse) if user_config
31
+ @configs << DEFAULT_CONFIG
23
32
 
24
- def refresh
25
- return if @config_time == config_file_last_modified
26
- @config = DEFAULT_CONFIG.merge(load_config)
33
+ check_current_version!
27
34
  end
28
35
 
29
36
  # @return [Object] a configuration value
30
- def get(key)
31
- @config[key]
37
+ def get(key, from_file: nil)
38
+ @configs.find do |config|
39
+ applies_to = config['applies_to'] || '*'
40
+ applies_from = config['applies_from'] || '*'
41
+ next unless config.key?(key)
42
+ File.fnmatch(normalize_path(applies_to), @path_to_current_file) &&
43
+ File.fnmatch(normalize_path(applies_from), normalize_path(from_file))
44
+ end[key]
32
45
  end
33
46
 
34
47
  # @param variable_name [String]
35
48
  # @param path_to_current_file [String?]
36
49
  # @return [ImportJS::JSModule?]
37
50
  def resolve_alias(variable_name, path_to_current_file)
38
- path = @config['aliases'][variable_name]
39
- return resolve_destructured_alias(variable_name) unless path
51
+ path = get('aliases')[variable_name]
52
+ return unless path
40
53
 
41
54
  path = path['path'] if path.is_a? Hash
42
55
 
@@ -44,21 +57,18 @@ module ImportJS
44
57
  path = path.sub(/\{filename\}/,
45
58
  File.basename(path_to_current_file, '.*'))
46
59
  end
47
- ImportJS::JSModule.new(lookup_path: nil,
48
- relative_file_path: path,
49
- strip_file_extensions: [])
60
+ ImportJS::JSModule.new(import_path: path)
50
61
  end
51
62
 
52
- def resolve_destructured_alias(variable_name)
53
- @config['aliases'].each do |_, path|
54
- next if path.is_a? String
55
- if (path['destructure'] || []).include?(variable_name)
56
- js_module = ImportJS::JSModule.new(lookup_path: nil,
57
- relative_file_path: path['path'],
58
- strip_file_extensions: [])
59
- js_module.is_destructured = true
60
- return js_module
61
- end
63
+ # @param variable_name [String]
64
+ # @return [ImportJS::JSModule?]
65
+ def resolve_named_exports(variable_name)
66
+ get('named_exports').each do |import_path, named_exports|
67
+ next unless named_exports.include?(variable_name)
68
+
69
+ js_module = ImportJS::JSModule.new(import_path: import_path)
70
+ js_module.has_named_exports = true
71
+ return js_module
62
72
  end
63
73
  nil
64
74
  end
@@ -67,26 +77,42 @@ module ImportJS
67
77
  def package_dependencies
68
78
  return [] unless File.exist?('package.json')
69
79
 
70
- package = JSON.parse(File.read('package.json'))
71
- dependencies = package['dependencies'] ?
72
- package['dependencies'].keys : []
73
- peer_dependencies = package['peerDependencies'] ?
74
- package['peerDependencies'].keys : []
75
-
76
- dependencies.concat(peer_dependencies)
80
+ keys = %w[dependencies peerDependencies]
81
+ keys << 'devDependencies' if get('import_dev_dependencies')
82
+ package_json = JSON.parse(File.read('package.json'))
83
+ keys.map do |key|
84
+ package_json[key].keys if package_json[key]
85
+ end.compact.flatten
77
86
  end
78
87
 
79
88
  private
80
89
 
90
+ # @param file [File]
81
91
  # @return [Hash]
82
- def load_config
83
- @config_time = config_file_last_modified
84
- File.exist?(CONFIG_FILE) ? JSON.parse(File.read(CONFIG_FILE)) : {}
92
+ def load_config(file)
93
+ return unless File.exist?(file)
94
+ JSON.parse(File.read(file))
95
+ end
96
+
97
+ # @param path [String]
98
+ # @return [String]
99
+ def normalize_path(path)
100
+ return './' unless path
101
+ path = path.sub(/^#{Regexp.escape(Dir.pwd)}/, '.')
102
+ path = "./#{path}" unless path.start_with?('.')
103
+ path
85
104
  end
86
105
 
87
- # @return [Time?]
88
- def config_file_last_modified
89
- File.exist?(CONFIG_FILE) ? File.mtime(CONFIG_FILE) : nil
106
+ # Checks that the current version is bigger than the `minimum_version`
107
+ # defined in config. Raises an error if it doesn't match.
108
+ def check_current_version!
109
+ minimum_version = get('minimum_version')
110
+ return if Gem::Dependency.new('', ">= #{minimum_version}")
111
+ .match?('', ImportJS::VERSION)
112
+
113
+ fail ImportJS::ClientTooOldError,
114
+ 'The .importjs.json file you are using requires version ' \
115
+ "#{get('minimum_version')}. You are using #{ImportJS::VERSION}."
90
116
  end
91
117
  end
92
118
  end
@@ -1,159 +1,159 @@
1
1
  # encoding: utf-8
2
2
  module ImportJS
3
- end
4
-
5
- class ImportJS::EmacsEditor
6
- attr_accessor :current_word
7
-
8
- def initialize
9
- loop do
10
- input = gets.chomp
11
- command, value, path = input.split(':')
12
-
13
- begin
14
- @path = path
15
- @file = File.readlines(path).map(&:chomp)
16
- @current_word = value
17
-
18
- case command
19
- when 'import'
20
- ImportJS::Importer.new(self).import
21
- write_file
22
- puts 'import:success'
23
- when 'goto'
24
- ImportJS::Importer.new(self).goto
25
- when 'fix'
26
- ImportJS::Importer.new(self).fix_imports
27
- write_file
28
- puts 'import:success'
29
- else
30
- puts "unknown command: #{command}"
3
+ # This is the implementation of the emacs integration in Import-JS.
4
+ class EmacsEditor
5
+ attr_accessor :current_word
6
+
7
+ def initialize
8
+ loop do
9
+ input = gets.chomp
10
+ command, value, path = input.split(':')
11
+
12
+ begin
13
+ @path = path
14
+ @file = File.readlines(path).map(&:chomp)
15
+ @current_word = value
16
+
17
+ case command
18
+ when 'import'
19
+ ImportJS::Importer.new(self).import
20
+ write_file
21
+ puts 'import:success'
22
+ when 'goto'
23
+ ImportJS::Importer.new(self).goto
24
+ when 'fix'
25
+ ImportJS::Importer.new(self).fix_imports
26
+ write_file
27
+ puts 'import:success'
28
+ else
29
+ puts "unknown command: #{command}"
30
+ end
31
+ rescue Exception => e
32
+ puts e.inspect
31
33
  end
32
- rescue Exception => e
33
- puts e.inspect
34
34
  end
35
35
  end
36
- end
37
36
 
38
- def write_file
39
- new_file = File.open(@path, 'w')
40
- @file.each {|line| new_file.puts(line) }
41
- new_file.close
42
- end
37
+ def write_file
38
+ new_file = File.open(@path, 'w')
39
+ @file.each { |line| new_file.puts(line) }
40
+ new_file.close
41
+ end
43
42
 
44
- # Open a file specified by a path.
45
- #
46
- # @param file_path [String]
47
- def open_file(file_path)
48
- puts "goto:success:#{File.expand_path(file_path)}"
49
- end
43
+ # Open a file specified by a path.
44
+ #
45
+ # @param file_path [String]
46
+ def open_file(file_path)
47
+ puts "goto:success:#{File.expand_path(file_path)}"
48
+ end
50
49
 
51
- # Get the path to the file currently being edited. May return `nil` if an
52
- # anonymous file is being edited.
53
- #
54
- # @return [String?]
55
- def path_to_current_file
56
- @path
57
- end
50
+ # Get the path to the file currently being edited. May return `nil` if an
51
+ # anonymous file is being edited.
52
+ #
53
+ # @return [String?]
54
+ def path_to_current_file
55
+ @path
56
+ end
58
57
 
59
- # Display a message to the user.
60
- #
61
- # @param str [String]
62
- def message(str)
63
- puts str
64
- end
58
+ # Display a message to the user.
59
+ #
60
+ # @param str [String]
61
+ def message(str)
62
+ puts str
63
+ end
65
64
 
66
- # Read the entire file into a string.
67
- #
68
- # @return [String]
69
- def current_file_content
70
- @file.join("\n")
71
- end
65
+ # Read the entire file into a string.
66
+ #
67
+ # @return [String]
68
+ def current_file_content
69
+ @file.join("\n")
70
+ end
72
71
 
73
- # Reads a line from the file.
74
- #
75
- # Lines are one-indexed, so 1 means the first line in the file.
76
- # @return [String]
77
- def read_line(line_number)
78
- @file[line_number - 1]
79
- end
72
+ # Reads a line from the file.
73
+ #
74
+ # Lines are one-indexed, so 1 means the first line in the file.
75
+ # @return [String]
76
+ def read_line(line_number)
77
+ @file[line_number - 1]
78
+ end
80
79
 
81
- # Get the cursor position.
82
- #
83
- # @return [Array(Number, Number)]
84
- def cursor
85
- return 0, 0
86
- end
80
+ # Get the cursor position.
81
+ #
82
+ # @return [Array(Number, Number)]
83
+ def cursor
84
+ [0, 0]
85
+ end
87
86
 
88
- # Place the cursor at a specified position.
89
- #
90
- # @param position_tuple [Array(Number, Number)] the row and column to place
91
- # the cursor at.
92
- def cursor=(position_tuple)
93
- end
87
+ # Place the cursor at a specified position.
88
+ #
89
+ # @param position_tuple [Array(Number, Number)] the row and column to place
90
+ # the cursor at.
91
+ def cursor=(position_tuple)
92
+ end
94
93
 
95
- # Delete a line.
96
- #
97
- # @param line_number [Number] One-indexed line number.
98
- # 1 is the first line in the file.
99
- def delete_line(line_number)
100
- @file.delete_at(line_number - 1)
101
- end
94
+ # Delete a line.
95
+ #
96
+ # @param line_number [Number] One-indexed line number.
97
+ # 1 is the first line in the file.
98
+ def delete_line(line_number)
99
+ @file.delete_at(line_number - 1)
100
+ end
102
101
 
103
- # Append a line right after the specified line.
104
- #
105
- # Lines are one-indexed, but you need to support appending to line 0 (add
106
- # content at top of file).
107
- # @param line_number [Number]
108
- def append_line(line_number, str)
109
- @file.insert(line_number, str)
110
- end
102
+ # Append a line right after the specified line.
103
+ #
104
+ # Lines are one-indexed, but you need to support appending to line 0 (add
105
+ # content at top of file).
106
+ # @param line_number [Number]
107
+ def append_line(line_number, str)
108
+ @file.insert(line_number, str)
109
+ end
111
110
 
112
- # Count the number of lines in the file.
113
- #
114
- # @return [Number] the number of lines in the file
115
- def count_lines
116
- @file.size
117
- end
111
+ # Count the number of lines in the file.
112
+ #
113
+ # @return [Number] the number of lines in the file
114
+ def count_lines
115
+ @file.size
116
+ end
118
117
 
119
- # Ask the user to select something from a list of alternatives.
120
- #
121
- # @param word [String] The word/variable to import
122
- # @param alternatives [Array<String>] A list of alternatives
123
- # @return [Number, nil] the index of the selected alternative, or nil if
124
- # nothing was selected.
125
- def ask_for_selection(word, alternatives)
126
- puts "asking for selection"
127
- puts "ImportJS: Pick JS module to import for '#{word}':"
128
- puts JSON.pretty_generate(alternatives)
129
- return
130
-
131
- # need to implement this
132
- escaped_list = [heading]
133
- escaped_list << alternatives.each_with_index.map do |alternative, i|
134
- "\"#{i + 1}: #{alternative}\""
135
- end
136
- escaped_list_string = '[' + escaped_list.join(',') + ']'
137
-
138
- selected_index = VIM.evaluate("inputlist(#{escaped_list_string})")
139
- return if selected_index < 1
140
- selected_index - 1
141
- end
118
+ # Ask the user to select something from a list of alternatives.
119
+ #
120
+ # @param word [String] The word/variable to import
121
+ # @param alternatives [Array<String>] A list of alternatives
122
+ # @return [Number, nil] the index of the selected alternative, or nil if
123
+ # nothing was selected.
124
+ def ask_for_selection(word, alternatives)
125
+ puts 'asking for selection'
126
+ puts "ImportJS: Pick JS module to import for '#{word}':"
127
+ puts JSON.pretty_generate(alternatives)
128
+ return
129
+
130
+ # need to implement this
131
+ escaped_list = [heading]
132
+ escaped_list << alternatives.each_with_index.map do |alternative, i|
133
+ "\"#{i + 1}: #{alternative}\""
134
+ end
135
+ escaped_list_string = '[' + escaped_list.join(',') + ']'
142
136
 
143
- # Get the preferred max length of a line
144
- # @return [Number?]
145
- def max_line_length
146
- 80
147
- end
137
+ selected_index = VIM.evaluate("inputlist(#{escaped_list_string})")
138
+ return if selected_index < 1
139
+ selected_index - 1
140
+ end
148
141
 
149
- # @return [String] shiftwidth number of spaces if expandtab is not set,
150
- # otherwise `\t`
151
- def tab
152
- return ' ' * shift_width || 2
153
- end
142
+ # Get the preferred max length of a line
143
+ # @return [Number?]
144
+ def max_line_length
145
+ 80
146
+ end
147
+
148
+ # @return [String] shiftwidth number of spaces if expandtab is not set,
149
+ # otherwise `\t`
150
+ def tab
151
+ ' ' * shift_width || 2
152
+ end
154
153
 
155
- # @return [Number?]
156
- def shift_width
157
- 2
154
+ # @return [Number?]
155
+ def shift_width
156
+ 2
157
+ end
158
158
  end
159
159
  end